理解 module、chunk 和 bundle
-
module 就是我们通过 import 引入的各种模块
-
chunk 是 webpack 根据功能拆分出来的模块,包括入口文件, 动态 import,lazy 等的文件以及 splitChunks 拆分出来的代码,chunk 可能包含多个 module
-
bundle 就是 webpack 打包之后的各个文件,于 chunk 一般一一对应
hash 的分类
-
hash:the hash of the module identifier(根据 module_id 序列的变化而变化)
-
chunkHash:the hash of the chunk content(chunkHash,根据每一个 chunk 内容的变化而变化)
-
contentHash:the hash of extracted content(根据内容变化而变化)
hash
-
compilation
- webpack 的 hash 是根据 compilation 计算出来的,compilation 对象代表某个版本的资源对应的编译进程,当我们的文件发生改变的时候, 进而能够针对改动生产全新的编译文件。compilation 对象包含当前模块资源、待编译文件、有改动的文件和监听依赖的所有信息,如果我们修改某一个文件,那么此时整个项目的 hash 都会改变
-
compiler
- compiler 对象代表的是配置完备的 Webpack 环境。 compiler 对象只在 Webpack 启动时构建一次,由 Webpack 组合所有的配置项构建生成,compiler 对象代表的是不变的 webpack 环境,compilation 是针对随时可变的项目文件
-
module_id
- webpack 通过给每一个模块一个 module_id 来处理各个模块之间的依赖关系,而默认的 id 命名规则是根据模块引入的顺序赋予一个整数(1,2,3),所以任意的增添或者删除一个模块的依赖,都会对整个的 ID 序列产生影响,最后影响 hash 值,这些模块会被 runtime 和 manifest 和引用到
-
对于图片、字体、PDF 等资源该 hash 还是可以生成一个唯一值的
-
此时我们配置 webpack 的 output 为 hash
// 此时项目的 mode: 'production', entry: { app: [path.resolve(__dirname, '../src/index.js')], }, output: { filename: 'js/[name].[hash].js', hashDigestLength: 7, path: path.resolve(__dirname, '../dist'), publicPath: './', },
-
项目依赖打包情况如下,我们可以看到所有的 hash 的值都是一样的
Asset Size Chunks Chunk Names css/app.2f3933e.css 52 bytes 0 [emitted] [immutable] app css/list.2f3933e.css 1.5 KiB 1 [emitted] [immutable] list css/vendors.2f3933e.css 71.2 KiB 2 [emitted] [immutable] vendors css/vendors.2f3933e.css.gz 7.85 KiB [emitted] index.html 1.33 KiB [emitted] js/app.2f3933e.js 6.63 KiB 0 [emitted] [immutable] app js/list.2f3933e.js 50.9 KiB 1 [emitted] [immutable] list js/list.2f3933e.js.LICENSE 120 bytes [emitted] js/list.2f3933e.js.gz 15 KiB [emitted] js/vendors.2f3933e.js 340 KiB 2 [emitted] [immutable] [big] vendors js/vendors.2f3933e.js.LICENSE 423 bytes [emitted] js/vendors.2f3933e.js.gz 91.8 KiB [emitted] js/work.2f3933e.js 188 bytes 3 [emitted] [immutable] work
-
runtime 和 manifest
-
webpack 通过 runtime 和 manifest 来管理所有模块的交互
-
runtime
- runtime,以及伴随的 manifest 数据,主要是指:在浏览器运行过程中,webpack 用来连接模块化应用程序所需的所有代码。它包含:在模块交互时,连接模块所需的加载和解析逻辑。包括:已经加载到浏览器中的连接模块逻辑,以及尚未加载模块的延迟加载逻辑
-
manifest
- 当 compiler 开始执行、解析和映射应用程序时,它会保留所有模块的详细要点。这个数据集合称为 “manifest”,当完成打包并发送到浏览器时,runtime 会通过 manifest 来解析和加载模块。无论你选择哪种 模块语法,那些 import 或 require 语句现在都已经转换为 webpack_require 方法,此方法指向模块标识符(module identifier)。通过使用 manifest 中的数据,runtime 将能够检索这些标识符,找出每个标识符背后对应的模块
-
runtime 和 manifest 是一个每次打包都可能变化的不稳定的因素,所以他会导致一些问题,比如,我们对整个项目的文章在做一次打包,打包结果如下,我们发现,我们什么也没有改动但是 hash 全部发生了变化,原因就是 runtime 和 manifest 这些所谓的样板文件
Asset Size Chunks Chunk Names css/app.2f3933e.css 52 bytes 0 [emitted] [immutable] app css/list.2f3933e.css 1.5 KiB 1 [emitted] [immutable] list css/vendors.2f3933e.css 71.2 KiB 2 [emitted] [immutable] vendors css/vendors.2f3933e.css.gz 7.85 KiB [emitted] index.html 1.33 KiB [emitted] js/app.2f3933e.js 6.63 KiB 0 [emitted] [immutable] app js/list.2f3933e.js 50.9 KiB 1 [emitted] [immutable] list js/list.2f3933e.js.LICENSE 120 bytes [emitted] js/list.2f3933e.js.gz 15 KiB [emitted] js/vendors.2f3933e.js 340 KiB 2 [emitted] [immutable] [big] vendors js/vendors.2f3933e.js.LICENSE 423 bytes [emitted] js/vendors.2f3933e.js.gz 91.8 KiB [emitted] js/<