1.构建流程
- 初始化参数: 从配置文件和shell 语句中读取与合并参数,得到最终的参数。
- 开始编译: 用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行 compiler 对象的 run 方法开始执行编译。
- 确定入口: 根据配置中的 entry 找出所有的入口文件。
- 编译模块: 从入口文件出发,调用所有配置的 Loader 对模块进行编译,找出该模块依赖的模块,再递归本步骤直到所有依赖文件都经过本步骤的处理。
- 完成模块编译: 在经过第 4 步使用 Loader 编译完所有模块之后,得到每个模块被编译后的最终内容以及它们之间的依赖关系。
- 输出资源: 根据入口和模块之间的关系,组装成一个个包含多个模块的 chunk,再把每个 chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会。
- 输出完成: 在确定输出内容之后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
2.webpack热更新
webpack 的热更新又称为热替换(Hot Module Replacement),缩写为 HMR,这个机制可以做到不用刷新浏览器而将新变更的模块替换掉旧的模块。
HMR 的核心就是客户端从服务端拉取更新后的文件,准确的说是 chunk diff(chunk需要更新的部分),实际上 webpack-dev-server 与浏览器之间维护了一个 WebSocket,当本地资源发生变化时,webpack-dev-server会向浏览器推送更新,并带上构建时的 hash,让客户端与上一次资源进行对比。客户端对比出差异后会向 webpack-dev-server 发起 ajax 请求来获取更改内容(文件列表、hash),这样客户端就可以再借助这些信息继续向 webpack-dev-server 发起 jsonp 请求获取该 chunk 的增量更新。后续的部分由 HotModulePlugin 来完成,提供了相关的 API 以供开发真针对自身场景进行处理,像 react-hot-loader 和 vue-loader 都是借助这些 API 实现 HMR。
3.提高webpack的打包速度
- 多入口情况下,使用 optimization.splitChunks 来提取公共代码。
- 通过 externals 配置来提取常用库。
- 利用 DllPlugin 和 DllReferencePlugin 预编译资源模块,通过 DllPlugin 来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin 将编译编译的模块加载进来。
- 使用 thread-loader 实现多进程加速编译。
- 使用 terser-webpack-plugin 对js进行代码压缩。
- 优化 resolve 配置缩小范围。
- 使用 tree-shaking 和 Scope hoisting 来剔除多余代码。
4.减少打包体积
- 使用 externals 配置来提取常用库。
- 使用 tree-sjaking 和 scope hoisting 来剔除多余代码。
- 使用 optimize-css-assets-webpack-plugin 压缩css。
- 使用 terser-webpack-plugin 对 js 进行代码压缩。
5.常用loader
- cache-loader:可以在一些性能开销较大的 Loader 之前添加,目的是将结果缓存到磁盘里。
- file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件(处理图片、字体、图标)。
- url-loader:与file-loader 类似,区别是用户可以设置一个阈值,大于阈值会交给 file-loader,小于阈值时返回文件 base64 形式编码(处理图片)。
- image-loader:加载并且压缩图片文件。
- babel-loader:把 ES6 转换成 ES5。
- ts-loader:将 typescript 转换成 JavaScript。
- svg-inline-loader:将压缩后的SVG内容注入代码中。
- raw-loader:加载文件原始内容(utf-8)。
- sass-loader:将 scss/sass 代码转换成 css。
- css-loader:加载 css,支持模块化、压缩、文件导入等特性。
- less-loader:将 less 代码转换成 css。
- style-loader:生成 style 标签,将 js 中的样式资源插入,并添加到 header 中生效。
- vue-loader:加载 vue.js 单文件组件。