Webpack 介绍及它和 vite 的区别

96 阅读4分钟

Webpack 是什么?

Webpack 是一种流行的静态模块打包工具,能够将 js、CSS、图片等文件打包成一个或多个优化后的静态文件,以便在浏览器中运行。

打包方式

Webpack 从项目的入口文件开始,递归地构建依赖关系图,将项目中所有模块组合在一起,并通过 Loaders 和 Plugins 对不同类型的文件进行压缩、优化等处理,以提高文件的加载速度和性能,最终输出打包后的静态文件。

Webpack 的主要配置项

  1. 入口文件 (entry)

    • 定义应用程序的主文件,Webpack 将从这个文件开始构建依赖关系图。
    javascript
    复制代码
    module.exports = {
      entry: './src/index.js',
    };
    
  2. 输出文件 (output)

    • 指定打包后的文件存放路径和文件名。
    javascript
    复制代码
    module.exports = {
      output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
      },
    };
    
  3. 加载器 (loaders)

    • 用于处理非 JavaScript 文件,如将 Sass 转换为 CSS 文件,或者将 ES6 转换为 ES5。
    javascript
    复制代码
    module.exports = {
      module: {
        rules: [
          {
            test: /.css$/,
            use: ['style-loader', 'css-loader'],
          },
        ],
      },
    };
    
  4. 插件 (plugins)

    • 插件可以执行从打包优化到代码压缩的各种任务,例如 HtmlWebpackPlugin 可以自动生成包含打包文件引用的 HTML 文件。
    javascript
    复制代码
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html',
        }),
      ],
    };
    
  5. 模式 (mode)

    • Webpack 提供了 developmentproduction 两种模式,分别用于开发和生产环境。在生产模式下,Webpack 会自动进行代码压缩和优化。
    javascript
    复制代码
    module.exports = {
      mode: 'development', // 开发模式
      // mode: 'production', // 生产模式
    };
    
  6. 优化 (optimization)  :配置 splitChunks 将代码分割成多个包

  optimization: { 
    splitChunks: 
    { chunks: 'all', },
   },

Webpack 和 Vite 的区别

  1. 启动和热更新速度

    • Vite:Vite 支持原生 ES 模块语法,在开发环境下只编译浏览器请求的模块,因此启动和热更新速度非常快。
    • Webpack:Webpack 在开发模式下不支持直接使用 ES 模块语法,它需要对项目中所有模块进行预先打包和编译,所以项目启动和热更新速度较慢。
  2. 配置复杂度

    • Webpack:Webpack 适用于需要精细控制打包的项目。它提供了灵活的配置和强大的插件系统,开发者可以通过自定义插件和选项配置,对打包过程进行精细控制。
    • Vite:Vite 的配置相对简单,开箱即用,适合追求快速开发和良好开发体验的项目。

为什么 Vite 加载速度更快?

  1. 支持原生 ES 模块语法和按需加载

    • Vite 支持原生 ES 模块语法,在开发环境中,只编译浏览器实际请求的模块,而不需要像 Webpack 那样预先打包所有模块。
  2. 更快的热更新

    • Vite 通过 WebSocket 实现文件变化的监听,当文件发生变化时,Vite 只需重新编译变化的部分,并通过浏览器的 ES 模块动态导入功能 (import) 来加载更新的模块。对比 Webpack 的热更新通常涉及到更多的模块重建和替换,因此速度较慢。

Webpack 热更新原理

  1. 当代码发生变化时,Webpack 开发服务器(webpack-dev-server)会检测到文件的变化,并重新编译变化后的文件。
  2. 编译完成后,服务器通过 WebSocket 向浏览器发送更新通知和静态资源。
  3. 浏览器接收到通知后,会替换已更新的模块,而无需刷新整个页面。

Vite 热更新原理

  1. Vite 支持原生 ES 模块语法,在开发环境中直接提供未打包的模块。
  2. 当代码发生变化时,Vite 通过 WebSocket 向浏览器发送更新通知,浏览器接收到通知后,使用 ES 模块的动态导入功能 (import) 来加载更新的模块。

什么是 WebSocket?

WebSocket 是一种通信协议,它允许服务器和客户端之间建立一个持续的连接,双方可以在连接期间随时发送数据,而无需每次都重新建立连接。WebSocket 特别适用于频繁数据交互和实时更新的应用场景,能够提高通信效率并减少延迟。

Webpack 打包优化

  1. 生产环境优化

    • 在生成环境下,Webpack 会自动进行代码压缩、移除开发工具等优化操作。通过设置 modeproduction 可以启用这些优化。
    javascript
    复制代码
    module.exports = {
      mode: 'production',
    };
    
  2. 代码拆分

    • 代码拆分可以将代码分成多个小包,以便更高效地加载。例如,可以通过 import() 语法进行动态导入,Webpack 会将这些模块分离到单独的 chunk 中。
    javascript
    复制代码
    import('./module').then((module) => {
      // 使用动态加载的模块
    });
    
    • 还可以使用 optimization.splitChunks 进行代码拆分。
    javascript
    复制代码
    module.exports = {
      optimization: {
        splitChunks: {
          chunks: 'all',
        },
      },
    };
    
  3. 压缩代码

    • Webpack 提供了内置的压缩工具,可以压缩 JavaScript 和 CSS 文件,减少文件体积。
    javascript
    复制代码
    const TerserPlugin = require('terser-webpack-plugin');
    
    module.exports = {
      optimization: {
        minimize: true,
        minimizer: [new TerserPlugin()],
      },
    };