【webpack学习】webpack的构建流程是什么、性能优化以及与Vite的区别?

51 阅读6分钟

webpack的概念

module、chunk和bundle的区别

  1. Module(模块)

    • 模块是你应用程序中的最小代码单元,通常是一个单独的文件。一个模块可以包含 JavaScript 代码、样式表、图片或其他资源。
    • 模块是 Webpack 处理的最基本的单位。Webpack 支持各种模块类型,包括 ES6 模块、CommonJS 模块、AMD 模块等。
    • 模块之间可以相互导入和导出变量、函数、类等。模块化编程有助于组织代码并实现可维护性。
  2. Chunk(代码块)

    • 代码块是 Webpack 在代码分割(code splitting)时生成的单元。代码块可以包含一个或多个模块。
    • 代码块的创建通常是通过 Webpack 的配置文件中的代码分割选项来控制的。这使得你可以将应用程序拆分成多个块,以实现按需加载和提高性能。
    • 代码块的生成与模块导入和应用程序的路由结构有关,可以是入口点 chunk(entry chunk)或动态导入 chunk(dynamic import chunk)。
  3. Bundle(捆绑包)

    • 捆绑包是 Webpack 构建过程的最终输出文件,通常是一个 JavaScript 文件。它包含了应用程序的所有代码和其依赖项。
    • 捆绑包是用于部署的文件,它包括了模块和代码块,以便在浏览器中加载和执行应用程序。
    • 一个捆绑包通常对应一个入口点(entry),但也可以包含多个入口点和其依赖的代码。

总结来说,"module" 是应用程序中的最小代码单元,"chunk" 是 Webpack 代码分割的结果,可以包含一个或多个模块,而 "bundle" 是最终生成的文件,包含了应用程序的全部代码以及其依赖,一般就是和chunk是一对一的关系,bundle就是对chunk进行编译压缩打包等处理之后的产出。

模块化编程帮助组织代码,代码分割和捆绑使应用程序加载更高效。

webpack构建流程

从entry的入口文件开始,一般是index.js,递归解析index.js依赖的所有module,(通过require或import引入的模块),再根据module.rules里配置的loader进行相应的转换处理,对model(index)转换后在解析出module依赖的其他模块(import中的xx.js),解析出一个一个的chunk(通过model进行分组),最后所有的chunk会转换成output设置的bundle.js。在整个构建流程中,webpack会在需要使用plugin的时机执行plugin里定义的那些插件,辅助完成转换处理。

webpack的性能优化

webpack性能优化方案(详细)

webpack的性能优化较多,我们可以对其进行分类:

  • 优化一:打包后的结果,上线时的性能优化。(比如分包处理、减小包体积、CDN服务器等)
  • 优化二:优化打包速度,开发或者构建时优化打包速度。(比如exclude、cache-loader等)

大多数情况下,我们会更加侧重于优化一,这对于线上的产品影响更大。

  • 在大多数情况下webpack都帮我们做好了该有的性能优化:

    • 比如配置mode为production或者development时,默认webpack的配置信息;
    • 但是我们也可以针对性的进行自己的项目优化;

1.性能优化 - 代码分离

代码分离(Code Splitting)是webpack一个非常重要的特性:

  • 它主要的目的是将代码分离到不同的bundle中,之后我们可以按需加载,或者并行加载这些文件;
  • 比如默认情况下,所有的JavaScript代码(业务代码、第三方依赖、暂时没有用到的模块)在首页全部都加载,就会影响首页 的加载速度;
  • 代码分离可以分出更小的bundle,以及控制资源加载优先级,提供代码的加载性能;

Webpack中常用的代码分离有三种:

  • 入口起点:使用entry配置手动分离代码;
  • 防止重复:使用Entry Dependencies或者SplitChunksPlugin去重和分离代码;
  • 动态导入:通过模块的内联函数调用来分离代码;

代码分离的SplitChunksPlugin

  1. Webpack提供了SplitChunksPlugin默认的配置,我们也可以手动来修改它的配置:

2.性能优化-CDN

在开发中,我们使用CDN主要是两种方式:

  • 方式一:打包的所有静态资源,放到CDN服务器, 用户所有资源都是通过CDN服务器加载的;
  • 方式二:一些第三方资源放到CDN服务器上;

3.性能优化-提取css文件

使用MiniCssExtractPlugin插件将css提取到一个独立的css文件中

4.性能优化-JS-CSS代码压缩

Terser可以帮助我们压缩、丑化我们的代码,让我们的bundle变得更小。

5. 性能优化-Webpack对文件压缩 http压缩

什么是HTTP压缩

  • HTTP压缩是一种内置在 服务器 和 客户端 之间的,以改进传输速度和带宽利用率的方式;
  • HTTP压缩的流程什么呢?
  • 第一步:HTTP数据在服务器发送前就已经被压缩了;(可以在webpack中完成)
  • 第二步:兼容的浏览器在向服务器发送请求时,会告知服务器自己支持哪些压缩格式;
  • 第三步:服务器在浏览器支持的压缩格式下,直接返回对应的压缩后的文件,并且在响应头中告知浏览器;

image.png 可以使用CompressionPlugin对文件进行gzip形式的压缩,那么http头里面的content-encoding就显示为gzip

Webpack和Vite的区别

如果能重来,你要选 Vite 还是 Webpack ? - 掘金 (juejin.cn)

如果应用过于复杂,使用Webpack 的开发过程会出现以下问题

  1. Webpack Dev Server 冷启动时间会比较长
  2. Webpack HMR 热更新的反应速度比较慢

vite的特点

  1. 轻量
  2. 按需打包
  3. HMR (热渲染依赖)

webpack dev server 在启动时需要先build一遍,而这个过程需要消耗很多时间。webpack 这类工具的做法是将所有模块提前编译、打包进bundle里,换句话说,不管模块是否会被执行,都要被编译和打包到bundle里。随着项目越来越大,打包后的bundle也越来越大,打包的速度自然会越来越慢。

而Vite 不同的是 执行vite serve 时,内部直接启动了web Server, 并不会先编译所有的代码文件。Vite 通过原生 ES Modules 托管源代码,本质上是让浏览器来接管部分打包器的工作。Vite 只会在浏览器请求发生时,按需将源码转成 ES Modules 格式返回给浏览器,由浏览器加载并执行 ES Modules 文件。

image.png