Skip to content
On this page

webpack 的整体流程

  1. 合并参数配置,合并命令行参数和配置文件的参数配置
  2. 初始化所有插件
  3. 确定入口,开始初始化 compile 类中的 run 方法
  4. 从入口文件开始递归解析模块,生成模块依赖关系图
  5. 通过 loader 来解析不同文件内容
  6. 将所有模块合并成一个或者多个 chunk
  7. 通过文件系统将chunk 输出成具体文件

webpack 热更新原理

在启动 webpack-dev-server 的时候也会启动一个 websocket 服务器。同时将websocketruntime 代码注入到 html 中。这样就建立起了一个双向的websocket服务。在编译完成后会通过文件系统的API 监听工作区文件夹,当文件发生改变时,会触发 webpack 的重新编译。给出一个新的 hash 值。通过 websocket 发送给客户端。客户端通过对比本地hash新hash 是否相同。如果不相同则发送一个jsonp请求参数是 hash 值去请求json文件。json文件中描述了这个更新需要更新的 chunk名以及对应的 hash 值。如果是对应多个 chunk则需要发多个 jsonp 请求 [chunk]+[hash].hot-update.js 请求对应模块内容然后再通过执行这些内容,移除就缓存的模块,加载新的模块。来做到模块更新

webpack 的 loader 和 plugin 的区别

  • loader 主要承担模块之间的翻译功能,因为webpack 在设计时只能识别 js/json 等文件其他文件就需要对应的 loader 来转换成 js 文件。
  • plugin 主要承担拓展功能。在 打包 期间 webpack 会触发一系列的事件,开发者通过监听这些事件来改变输出结果

tree-shaking 原理

tree-shaking 主要通过 ESM 的静态分析实现,通过静态分析就能确定出哪些模块是永远不会执行的,这个效果需要开启 package.json.sideEffects 来开启默认值是 true,可选值 boolean,[]

如果为 true 的话则告诉打包器这些文件都是有副作用的不能删除,也就没有 tree-shaking效果 如果值是 数组 则表示这些文件会有副作用不能删除,其他的可以删除

值得一提的是 在 Webpack 中没有直接实现 tree-shaking 效果,他会将死代码进行代码注释标记,需要配合 terser/UglifyJS 等压缩代码插件来移除这些死代码。

webpack 打包优化

  1. 限制 resolve 查找后缀范围
  2. loader 中加上 include/exclude 关键字缩小转换的范围
  3. 通过 optimization.splitChunk 合理拆分 chunk
  4. 通过 thread-loader 并行编译
  5. 合理使用缓存,比如 babel-loader 的缓存以及 cache-loader/hard-source-loader
  6. 使用 external 排除使用 cdn 加载的库
  7. 使用 esbuild-loader/swc-loader 来代替 babel-loader

webpack 的 hash、chunkhash 和 contenthash 的区别

聊聊 source-map

Compiler 和 Compilation 的区别

Compiler 代表了整个 Webpack 的环境配置,在启动 Webpack的时候被创建。

每一次调用 compiler.run 方法都会创建出一个 Compilation对象,代表一次完整的构建过程,Compilation 对象包含了关于这次编译的所有信息 依赖关系结果 等。

Compilation 对象也提供了很多关键时机的回调,以供插件做扩展。