webpack 构建优化
参考文章
为什么构建会慢?
webpack 的构建流程主要为:
- 递归遍历各个入口文件。
- 基于入口文件不断寻找依赖逐个编译再递归处理 每次递归都需要经历 String->AST->String 然后通过不同的 loader 处理一些字符串或者执行一些 JavaScript 脚本 然后 nodejs 是单线程,js 是单线程语言,所以限制了效率 所以可得出构建优化方向为:
- 缓存
- 多进程
- 寻路优化
- 抽离拆分
- 构建工具替换
分析构建问题
- speed-measure-webpack-plugin
统计 webpack 打包时间,分析总的打包时间,分析各阶段 loader 的耗时,并且可以输出一个文件用于永久化存储数据。
- dev 开发阶段优化
- 在开发阶段,需要热更新。但是像代码混淆压缩,图片压缩这些功能可以不用开启,以此来加快构建时间。
- build 打包优化
- 需在保证最终项目体积小的情况下加快构建速度。
缓存优化
- hard-source-webpack-plugin
为模块提供中间缓存,缓存默认存放路径是 node_modules/.cache/hard-source(webpack5 内置模块缓存了)
- webpack5 cache
- 设置 babel-loader 的 cacheDirectory
- 指定目录用来缓存 loader,之后的构建读取这个缓存
- DDL
- 大佬说配置非常繁琐,并且最终收效甚微。
多进程
- thread-loader
- 把 thread-loader 放置在其它 loader 之前,那么放置在这个 loader 之后的 loader 就会在一个单独的 worker 池中运行。这样做的好处是把原本需要串行执行的任务并行执行。
寻址优化
合理设置 loader 的 exclude 和 include 属性。
分模块构建
指某项目中有路由 A,B,C,D。当前仅基于 A 进行开发,就只构建 A 模块。 需要使 webpack 在初始化遍历路由收集依赖的时候,跳过不需要的模块。 即,需在项目启动时,通过命令脚本,动态生成需要构建的路由列。
- 使用 NormalModuleReplacementPlugin 插件进行文件替换
- 对于项目的入侵小,只需添加前置脚本及修改 Webpack 配置
- 通过生成临时路由文件的方式,替换原路由文件,对项目无任何影响 将原本的路由文件替换掉
js
new webpack.NormalModuleReplacementPlugin(/src\/route\/routes.js/, "./dev.routes.js");
dev.routes 如何生成呢?
开发构建优化
某些 utility, plugin 和 loader 都只用于生产环境。例如,在开发环境下使用 TerserPlugin 来 minify(压缩) 和 mangle(混淆破坏) 代码是没有意义的。通常在开发环境下,应该排除以下这些工具:
- TerserPlugin
- [fullhash]/[chunkhash]/[contenthash]
- AggressiveSplittingPlugin
- AggressiveMergingPlugin
- ModuleConcatenationPlugin
生产构建优化
- 可在 build 阶段去掉代码静态检查 eslint
- 使用esbuild-loader 去替代非常耗时的 babel-loader、ts-loader 等 loader
- 它把 esbuild 的能力包装成 Webpack 的 loader 来实现 Javascript、TypeScript、CSS 等资源的编译。以及提供更快的资源压缩方案。