Webpack5实践-构建效率倍速提升!

本文转载自微信公众号「五月君」,作者五月君。转载本文请联系五月君公众号。

创新互联公司专业为企业提供临泽网站建设、临泽做网站、临泽网站设计、临泽网站制作等企业网站建设、网页设计与制作、临泽企业网站模板建站服务,十年临泽做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。

对于前端构建工具 Webpack、babel、eslint 等的每一次升级,就像刚刚经历一场地震似得,最不想面对的就是处理各种 API 的不兼容性,有时还会出现一些奇奇怪怪的问题,为什么还要升呢?并不是为了给自己找事,还是要讲究投入产出比的,也就是最终的收益是要大于产出比的。

前段在团队内部对 Webpack v5 带来的一些新特性做一些 Research,相较于一些项目的构建工具版本(Webpack v3)做了一个对比,在构建效率这块是有质的飞跃的,同样相对于 Webpack v4 也是有很大提升的。本文是本次升级过程中的实践(踩坑)记录,分享一些值得关注的功能、一些重大的改变、遇到的一些 NPM 组建兼容性问题,希望能给予读者朋友一些参考和帮助。

先上一张脑图,涵盖本文主题!

构建效果对比

基于一些项目做了一些测试,首次构建相较于之前提速将近 2 倍多,二次构建差不多 2s 左右,效果更显著,修改文件后的增量构建,差不多也在几秒钟可完成,整体构建效率提升还是很明显的,除此之外打包后的文件大小也比之前小了一些,但之间的差距不是特别的大,重点还是构建效率大幅提升。

构建效率上之所以有这么大的性能提升,这与它的基于文件系统的持久化缓存是有很大帮助的,下文会讲解。内部的项目数据就不便再这里展示了,文末提供了一些来自社区的实践,也可以看到一些数据对比。

下面,基于之前 Research 时写的一些 Demo 可以对比下使用了持久化缓存在初次构建、二次无文件改动构建、改动文件后增量构建三种情况下的效果对比,也可以显著的看到一些效果。

代码压缩(生产环境)

JavaScript 代码压缩

Webpack5 在生产环境下默认使用自带的 TerserPlugin 插件(无需安装)来做代码压缩,这个插件也被认为是在代码压缩方面性能是较好的。无需再借助 UglifyjsPlugin、ParallelUglifyPlugin 这些插件了。

如果你使用的是 webpack4 版本需要手动安装 yarn add terser-webpack-plugin -D 并将插件添加到生产环境的配置文件中。

以下是使用示例,在 Webpack v5 的生产环境默认开启。

 
 
 
 
  1. const TerserPlugin = require("terser-webpack-plugin"); 
  2.  
  3. module.exports = { 
  4.   optimization: { 
  5.     minimize: true, 
  6.     minimizer: [new TerserPlugin()], 
  7.   }, 
  8. }; 

支持做一些自定义的配置:文件过滤、并发运行等,详细参见 Webpack 文档 TerserWebpackPlugin[1]。

  • test:匹配需要压缩的文件。
  • include:匹配包含的目录。
  • exclude:匹配不需要包含的目录。
  • parallel:多进程并发运行,默认 os.cpus().length - 1。
 
 
 
 
  1. module.exports = { 
  2.   optimization: { 
  3.     minimize: true, 
  4.     minimizer: [ 
  5.       new TerserPlugin({ 
  6.         test: /\.js(\?.*)?$/i, 
  7.         include: /\/includes/, 
  8.         exclude: /\/excludes/, 
  9.         parallel: true 
  10.         // more ... 
  11.       }), 
  12.     ], 
  13.   }, 
  14. }; 

CSS 文件分离

CSS 压缩之前先做的一项工作是 CSS 和 JS 文件分离,如果是从 Webpack v3 升级到 v5 会遇到一些问题,之前使用的是 extract-text-webpack-plugin 在 webpack v5 会收到废弃提醒,建议使用 **MiniCssExtractPlugin** 这个插件,本插件基于 webpack v4 的新特性(模块类型)构建。

与 extract-text-webpack-plugin 相比,拥有这些特性:异步加载、没有重复的编译(性能提升)、更容易使用、特别针对 CSS 开发。

下面是一个配置,这里还有些优化,生产模式使用 mini-css-extract-plugin 插件分离 JS/CSS 文件实现并行加载,而开发环境选择 style-loader 它可以使用多个标签将 CSS 插入到 DOM 中,并且反应会更快。

 
 
 
 
  1. const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 
  2. module.exports = { 
  3.   module: { 
  4.     rules: [ 
  5.       { 
  6.         test: /\.css$/i, 
  7.         use: [ 
  8.           devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 
  9.           'css-loader' 
  10.         ], 
  11.       }, 
  12.     ], 
  13.   }, 
  14.   plugins: [new MiniCssExtractPlugin()], 
  15. }; 

关于 CSS 分割插件的更详细配置 Webpack 文档 mini-css-extract-plugin[2]。

CSS 打包后加载图片 404?

生产环境我们使用 mini-css-extract-plugin 插件分离 CSS 文件,如果你在 CSS 里引用了图片,可能会遇到为什么打包后 CSS 里引用的图片加载时 404 了?

在 Webpack 的 output 选项中有一个 publicPath 配置,它指定了应用程序中所有资源的基础路径。

 
 
 
 
  1. module.exports = { 
  2.   output: { 
  3.     publicPath: 'auto' 
  4.   } 

Webpack loader 的 options 选项中也有一个 publicPath 配置,为 CSS 内的图片、文件等外部资源指定一个自定义的公共路径,默认值为 output.publicPath。如果出现打包后 CSS 内图片 404 的可以检查下这里的配置是否有问题。

 
 
 
 
  1. const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 
  2. module.exports = { 
  3.   module: { 
  4.     rules: [ 
  5.       { 
  6.         test: /\.css$/i, 
  7.         use: [ 
  8.           devMode ? 'style-loader' : { 
  9.             loader: MiniCssExtractPlugin.loader, 
  10.             options: { 
  11.               publicPath: '../' 
  12.             } 
  13.           }, 
  14.         ], 
  15.       }, 
  16.     ], 
  17.   }, 
  18.   plugins: [new MiniCssExtractPlugin()], 
  19. }; 

CSS 代码压缩

CSS 压缩之前会使用 optimize-css-assets-webpack-plugin 这个插件,在 webpack v5 之后推荐使用 css-minimizer-webpack-plugin 这个插件。

 
 
 
 
  1. const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); 
  2. module.exports = { 
  3.   optimization: { 
  4.     minimizer: [ 
  5.       new CssMinimizerPlugin(), 
  6.     ], 
  7.   }, 
  8. }; 

性能提升核心缓存优化

之前通过 cache-loader、babel-loader?cacheDirectory 在配置 cacheDirectory:true 实现将编译结果写入磁盘或者通过 hard-source-webpack-plugin 插件。

Webpack5 自带缓存能力,会缓存生成的 webpack module 和 chunk,对于二次构建有了很大的性能提升。通过 cache 属性配置,分为内存和文件两种缓存方式,默认在生产环境是禁用的,需自行开启。

基于内存缓存

当在开发环境默认设置为 memory,基于内存的缓存,除了下面的方式配置外,也可通过 cache: true 配置。

 
 
 
 
  1. module.exports = { 
  2.   cache: { 
  3.     type: 'memory' 
  4.   }, 
  5. }; 

基于 FileSystem 的持久化缓存

基于内存的缓存,只有在服务运行中,才有效,每次的单独构建是利用不了缓存的,webpack5 对于缓存另一个比较好的功能是提供了基于文件系统的持久化缓存。

基于文件系统的持久化缓存无论在单独构建或连续构建(可以指热更新操作)中都可应用,首先它会查看内存缓存,如果未命中,则降级到文件系统缓存。

应用很简单,设置 type:filesystem。默认情况下它位于 node_modules/.cache/webpack/ 目录,我们还可以通过 name 属性修改它的名称,例如,我们通过不同的环境 NODE_ENV 来区别不同环境的缓存。

当 type 设置为 filesystem 后,有很多属性是可以配置的,参见 Webpack 文档 cache[3]。

 
 
 
 
  1. module.exports = { 
  2.   cache: { 
  3.     type: 'filesystem', 
  4.     buildDependencies: { 
  5.       config: [__filename], 
  6.     }, 
  7.     name: `${ process.env.NODE_ENV || 'development'}-cache` 
  8.   } 

缓存失效

基于内存的缓存每一次重新运行都是一次新的构建。需要注意的是持久化缓存,当你修改了文件或传递了一些参数,发现最终展现的效果没有被更改,通常这与持久化缓存的缓存策略相关。

出于性能考虑,缓存会跳过 node_modules 认为这会极大降低 webpack 执行速度,建议是不要手动编辑 node_modules。通常也不会这么干直接去修改 node_modules。

有些操作也会使缓存失效,例如:当 NPM 升级 loader、plugin、更改配置等。

Webpack 提供了 buildDependencies、name、version 三种方式可以使构建缓存失效。

方法一:cache.buildDependencies

buildDependencies 指定构建过程中受影响的代码依赖,默认为 webpack/lib,当 node_modules 中的 webpack 或其依赖项发生任何变化,当前的缓存即失效。

还有一个是指定的配置文件 config: [__filename] 或配置文件的依赖项发生变化,也会失效。

 
 
 
 
  1. module.exports = { 
  2.   cache: { 
  3.     type: 'filesystem', 
  4.     buildDependencies: { 
  5.       defaultWebpack: ["webpack/lib/"], 
  6.       config: [__filename], 
  7.     }, 
  8.     name: `${ process.env.NODE_ENV || 'development'}-cache` 
  9.   } 

方法二:cache.version

如果是把构建工具封装为一个单独的工具包,类似于 react-scripts 这种的,理论上每次升级工具包,就需要重新编译的,之前在一次本地测试时发现工具包升级后缓存没有失效,如果出现这种情况的可以在 cache 里加上 version 配置指向 package.json 里的 version。

 
 
 
 
  1. module.exports = { 
  2.   cache: { 
  3.     type: 'filesystem', 
  4.     version: `${packageJson.version}` 
  5.   } 

有时配置文件或者代码没有修改,但是会依赖于命令行传递值想使缓存失效,同样也可在 version 上加上这些命令行传递的值做为版本控制。

 
 
 
 
  1. module.exports = { 
  2.   cache: { 
  3.     type: 'filesystem', 
  4.     version: `${process.env.CLI_VALUE}` 
  5.   } 

当 version 依赖于多个值时,可以将多个值做个 md5 生成一串唯一的字符串做为版本也可。

方法三:cache.name

name 属性比较好的是可以保存多个缓存目录,例如通过 process.env.NODE_ENV 区分不同的环境。

 
 
 
 
  1. module.exports = { 
  2.   cache: { 
  3.     type: 'filesystem', 
  4.     name: `${ process.env.NODE_ENV || 'development'}-cache` 
  5.   } 

持久化缓存这块也有很多的东西可以讲,详情参见 [译] webpack 5 之持久化缓存[4]。

长期缓存优化

Webpack 5 新增了长期缓存算法,以确定性的方式为模块和分块分配短的(3 或 5 位)数字 ID,这是包大小和长期缓存之间的一种权衡,生产环境默认开启以下配置。在减小文件打包大小同时也利于浏览器长期缓存(不会因为删除或新增一个模块而导致大量缓存文件失效)。

 
 
 
 
  1. // production default 
  2. module.exports = { 
  3.   optimization: { 
  4.     moduleIds: 'deterministic', 
  5.     chunkIds: 'deterministic' 
  6.     mangleExports: 'deterministic' 
  7.   } 

Webpack v5 VS v4 模块 ID

Webpack v4 及之前的 moduleId 默认是自增的,例如 0.xxx.js、1.xxx.css、2.xxx.js 如果更改模块数量(即使内容没有变化),也会导致模块文件重新发生改变,不利于长期缓存。

不同的版本也提供了不同的解决方案,webpack v4 之前使用 HashedModuleIdsPlugin 插件覆盖默认的模块 ID 规则,在 webpack v4 中可以配置 optimization.moduleIds = 'hashed' 解决。这几种方案都是使用模块路径生成的 hash 做为 moduleId。

Webpack v5 生产环境默认 optimization.moduleIds='deterministic' 无需更改。

Webpack v5 VS v4 Chunk ID

webpack v4 及之前的 chunkId 默认也是递增的,如果在 entry 配置中新增或删除一个元素,chunkId 也会随着递增或递减。

webpack v4 之前使用 NamedChunksPlugin 插件覆盖默认的 chunkId 规则,在 webpack v4 中可以配置 optimization.chunkIds = 'named' 解决。

Webpack v5 生产环境默认 optimization.chunkIds='deterministic' 无需更改。

真正的内容哈希

另外,当使用 [contenthash] 时,webpack5 将使用真正的文件内容做为哈希值,这个类似于协商缓存 Etag,不一样的是还有一些优化,如果你只是删除了代码中的一些注释或重新命名变量,而这种情况代码逻辑是没有修改的,这些变化在压缩后是不可见的,不会导致 [contenthash] 也发生变化。

如果是从 webpack v3 升级到 v5 的,HashedModuleIdsPlugin、NamedChunksPlugin 这些插件是可以去掉的,webpack v5 环境默认开启新的算法,无需再配置。

参考文档 Webpack release 日志记录 — 重大变更:长期缓存[5]。

原生支持资源模块

Webpack v5 内置了资源模块(assert),用来处理资源文件(图片、字体等),在之前是通过配置额外的 loader,例如 raw-loader、file-loader、url-loader 实现的。

Webpack v4 资源文件处理

下面是一段 webpack v4 及之前版本的资源文件处理配置,当匹配的文件大小如果小于 limit 限制,将其处理成 data URI 内联到 bundle 中,否则生成文件(使用 file-loader)输出到目录中,url-loader 内置了 file-loader 对文件的处理。

 
 
 
 
  1.   test: /\.(jpe?g|png|gif|svg)$/, 
  2.   use: [ 
  3.     { 
  4.       loader: 'url-loader', 
  5.       options: { 
  6.         limit: 1024 * 10 
  7.       } 
  8.     } 
  9.   ] 
  10. }, 

Webpack v5 新的资源文件处理

Webpack v5 不再需要安装 url-loader 处理资源文件,内置了资源模块类型,通过 type 定义,用来替换之前需要额外配置 loader 的方式。

  • asset/resource:将文件打包输出并导出 URL,类似于 file-loader。
  • asset/inline:导出一个资源的 data URI,编码到 bundle 中输出,类似于 url-loader。
  • asset/source:导出资源的源代码,类似于 raw-loader。
  • asset:提供了一种通用的资源类型,根据设置的 Rule.parser.dataUrlCondition.maxSize 自动的在 asset/resource、asset/inline 之间做选择,小于该大小指定的文件视为 inline 模块类型,否则视为 resource 模块类型。

下面是一个示例,大于 4kb 的输出到目录 static 中。

 
 
 
 
  1.   test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i, 
  2.   type: "asset", 
  3.   parser: { 
  4.     dataUrlCondition: { 
  5.       maxSize: 4 * 1024 // 4kb 
  6.     } 
  7.   }, 
  8.   generator: { 
  9.     filename: 'static/[hash][ext][query]' 
  10.   } 
  11. }, 

参考文档 Webpack 文档 Assert module[6]。

强大的 tree-shaking 能力

tree-shaking 是一个术语,翻译为中文为 “树摇”,想想一下一颗长满果子的树木,其中有些已经熟透了,当摇晃树木时是不是一部分会被摇掉。

图片来源:https://cdn.pixabay.com/photo/2019/05/16/23/39/apple-tree-4208594_1280.jpg

对于我们代码层面来说,那些上下文未引用的 JavaScript 代码,也可以通过工具移除(“摇掉”),实现打包体积的优化。

嵌套的 tree-shaking

在这种情况下,可以删除未使用的变量 b,生产环境默认开启。

 
 
 
 
  1. // inner.js 
  2. export const a = 1; 
  3. export const b = 2; 
  4.  
  5. // module.js 
  6. export * as inner from './inner'; 
  7.  
  8. // user.js 
  9. import * as module from './module'; 
  10. console.log(module.inner.a); 

内部模块 tree-shaking

Webpack v5 还增加了模块导出和引用之间的依赖关系分析,通过配置 optimization.innerGraph 控制,生产环境默认开启。

以下示例,something 只有在使用 test 导出时才会使用。

 
 
 
 
  1. import { something } from './something'; 
  2.  
  3. function usingSomething() { 
  4.   return something; 
  5.  
  6. export function test() { 
  7.   return usingSomething(); 

支持 CommonJS Tree Shaking

新增 CommonJS 模块的导出和引用之间的依赖分析,下例,可以删除未使用的变量 b。

 
 
 
 
  1. // inner.js 
  2. exports.a = 1; 
  3. exports.b = 2; 
  4.  
  5. // module.js 
  6. exports.inner = require('./inner'); 
  7.  
  8. // user.js 
  9. const module = require('./module'); 
  10. console.log(module.inner.a); 

参考 Webpack 文档 tree-shaking[7]。

Node.js 调用 webpack API

之前在团队内部,基于 webpack 这些构建工具封装了适合团队内部的构建工具模块,是通过 API 调用的,有些问题还是要注意下。

生产环境

调用 webpack() 创建一个 compiler 实例,之后调用 run() 方法执行,需要注意的是在完成之后记得关闭 compiler,这样低优先级的工作(比如持久缓存)就有机会完成,否则,有时候会发现每次都是重新构建没有利用上缓存。

下例中的 stats 参数可以获取到代码编译过程产生的错误和警告、计时信息、module 和 chunk 信息,如果想达到 cli 环境下的日志输出格式,调用 stats.toString() 方法即可。

 
 
 
 
  1. const compiler = webpack(config); 
  2. return new Promise((resolve, reject) => { 
  3.   compiler.run((err, stats) => { 
  4.     if (err) { 
  5.       return reject(err); 
  6.     } 
  7.  
  8.     console.log(stats.toString({ 
  9.       chunks: false, 
  10.       colors: true 
  11.     })); 
  12.  
  13.     compiler.close(closeErr => { 
  14.       if (closeErr) { 
  15.         console.log(chalk.red(`compiler close failed with message ${closeErr.message}`)); 
  16.       } 
  17.     }); 
  18.  
  19.     return resolve(stats); 
  20.   }); 
  21. }); 

开发环境

与生产环境 API 调用不同,开发环境我们需要热更新,在创建一个 compiler 后需要调用 webpack-dev-server 插件。

还有个问题是 devServer 中的配置选项将被忽略,但可以将配置选项作为第二个参数传入。

 
 
 
 
  1. const compiler = webpack(config); 
  2. const devServerOptions = Object.assign({}, config.devServer, { 
  3.   port: port, 
  4.   host: DEFAULT_HOST, 
  5.   open: true, 
  6. }); 
  7. const server = new WebpackDevServer(compiler, devServerOptions); 
  8. server.listen(port, DEFAULT_HOST); 

参考文档 Webpack 文档 Node.js API 接口[8]。

原生 Web Worker 支持

从 webpack 5 开始,使用 Web Workers 代替 worker-loader,这种语法也是为了实现不使用 bundler 就可以运行代码。

Web Worker 是解决一些密集型的任务,例如一些加解密、图片处理等一些耗时的计算任务可以放置于工作线程处理,处理完毕在通知到主线程,在处理的过程不会影响用户在界面上的一些其它操作。

 
 
 
 
  1. const worker = new Worker(new URL('./worker-calculate.js', import.meta.url)); 
  2. worker.postMessage({ 
  3.   question: 
  4.     'The Answer to the Ultimate Question of Life, The Universe, and Everything.', 
  5. }); 
  6. worker.onmessage = ({ data: { answer } }) => { 
  7.   console.log(answer); 
  8. }; 
  9.  
  10. // worker-calculate.js 
  11. self.onmessage = ({ data: { question } }) => { 
  12.   self.postMessage({ 
  13.     answer: 42, 
  14.   }); 
  15. }; 

Web Workers 可以在浏览器中的原生 ECMAScript 模块中使用,也可以用于 Node.js 中,如果采用 ESM 模块规范,Node.js 需要 >= 12.17.0。

 
 
 
 
  1. import { Worker } from 'worker_threads'; 
  2. new Worker(new URL('./worker.js', import.meta.url)); 

Node.js 通过 worker_threads 模块提供支持,在 Node.js 中如果你使用 CommonJS 规范在 v10.0.5 版本就已经支持了。

 
 
 
 
  1. const { Worker } = require('worker_threads'); 

更多详情参考 webpack 文档 Web Workers[9]。

其它 NPM 组件兼容性问题

开发环境热更新

如果是从 webpack v3.x 升级的,会发现之前的热更新方式会报如下错误。

 
 
 
 
  1. Error: Cannot find module 'webpack/bin/config-yargs' 

Webpack v5 使用 webpack serve 启动开发环境,解决这个问题就是重新安装 webpack-cli、还有 webpack-dev-server 也是需要安装的。

 
 
 
 
  1. // For webpack-cli 3.x: 
  2. "scripts": { "start:dev": "webpack-dev-server" } 
  3.  
  4. // For webpack-cli 4.x: 
  5. "scripts": { "start:dev": "webpack serve" } 

问题参考 cannot-find-module-webpack-bin-config-yargs。

compiler.plugin is not a function with InterpolateHtmlPlugin

可能会遇到以下错误:

 
 
 
 
  1. TypeError: compiler.plugin is not a function 
  2.     at InterpolateHtmlPlugin.apply (/Users/qufei/Documents/code/f-designer-tool-webpack5-test/node_modules/react-dev-utils/InterpolateHtmlPlugin.js:25:14) 

单独安装插件 yarn add -D interpolate-html-plugin 替换 InterpolateHtmlPlugin = require('react-dev-utils/interpolate-html-plugin'); 为 const InterpolateHtmlPlugin = require('interpolate-html-plugin');

最后确保 InterpolateHtmlPlugin 出现在插件列表中的 HtmlWebpackPlugin 之后。

webpack.NamedModulesPlugin is not a constructor with NamedModulesPlugin

当开启 HMR 的时候使用该插件会显示模块的相对路径,该插件已废弃,在 Webpack4 中建议设置为 optimization.namedModules,但是在 Webpack5 也被废弃,如果需要请改为 optimization.moduleIds: 'named',在 Webpack5 中的建议是 “请考虑将 optimization.moduleIds 和 optimization.chunkIds 从你 webpack 配置中移除。使用默认值会更合适,因为它们会在 production 模式 下支持长效缓存且可以在 development 模式下进行调试。” 参见 https://webpack.docschina.org/migrate/5/#clean-up-configuration

移除 Node.js 模块 Polyfills

Webpack5 移除了 Node.js 模块的 Polyfills,更专注于前端模块兼容。认为这会在构建时给 bundle 附加庞大的 Polyfills,大部分情况下也并非必须的,如果你的模块或你安装的第三方模块引用了 cypto、process 这些模块,就会看到报错。

 
 
 
 
  1. process is not a function 
  2. xxx is not a function 

参考 automatic-nodejs-polyfills-removed,对于 webpack v5,可以从 webpack.config.js 的相应插件部分引用 process/browser。

参考 webpack-bundle-js-uncaught-referenceerror-process-is-not-defined。

 
 
 
 
  1. const webpack = require('webpack') 
  2. module.exports = { 
  3.   plugins: [ 
  4.     // fix "process is not defined" error: 
  5.     // (do "npm install process" before running the build) 
  6.     new webpack.ProvidePlugin({ 
  7.       process: 'process/browser', 
  8.     }), 
  9.   ] 

compiler.plugin is not a function with react-dev-utils/WatchMissingNodeModulesPlugin

 
 
 
 
  1. new WatchMissingNodeModulesPlugin(), 
  2.  
  3. // 运行之后报错 
  4. // TypeError: compiler.plugin is not a function 
  5. //      at WatchMissingNodeModulesPlugin.apply (/Users/xxx/node_modules/react-dev-utils/WatchMissingNodeModulesPlugin.js:20:14) 

这个错误是在 Webpack 4 upgrade PR,升级 react-dev-utils yarn add react-dev-utils -D。

babel-eslint has been deprecated

之前在使用 eslint 代码检查时,如果有用到 eslint 不支持的试验性特性时会需要用到 babel-eslint,但是这个项目已经废弃了,到官网会看到这样一句话:

 
 
 
 
  1. babel-eslint is now @babel/eslint-parser. This package will no longer receive updates. 

现在推荐使用 @babel/eslint-parser 代替。

更多新功能

  • Top Level Await 支持:目前在 Webpack v5 计划中属于试验性支持,可通过开启 experiments.topLevelAwait 配置支持,这对于文件头部初始化资源很有用,无需让 await 必须在 async 里面。参考 Webpack v5 配置#experiments。
  • 模块联邦(Federated Modules):是 webpack v5 增加的一个新功能,为前端项目打包模式提供了新的方式,对多个不存在依赖关系的多个项目可以独立构建组成一个应用程序,从开发者的角度看,模块可以从远程构建中导入。这通常称为微前端,也并不仅限于此。更多可参考 Webpack 提供的单独指南 module-federation,也可看看下面的社区实践。
  • 原生支持 WebAssembly 构建:webpack v5 原生支持了 WebAssembly 的代码构建,只需开启 experiments.syncWebAssembly 配置即可,这个功能也属于试验性支持。
  • ... 更多功能参考 webpack v5 release 日志。

来自社区实践

  • 字节:Webpack5 新特性业务落地实战
  • 腾讯:构建效率大幅提升,webpack5 在企鹅辅导的升级实践
  • 蚂蚁:调研 Federated Modules,应用秒开,应用集方案,微前端加载方案改进等
  • 百度:Webpack 5 升级实验
  • 飞书:Webpack5 上手测评

因为微信对外链的限制,文中有些链接不能打开,可以 “阅读原文” 查看。

参考资料

[1]Webpack 文档 TerserWebpackPlugin: https://webpack.docschina.org/plugins/terser-webpack-plugin/

[2]Webpack 文档 mini-css-extract-plugin: https://webpack.docschina.org/plugins/mini-css-extract-plugin

[3]Webpack 文档 cache: https://webpack.docschina.org/configuration/other-options/#cache

[4][译] webpack 5 之持久化缓存: https://juejin.cn/post/6844903967793627149

[5]Webpack release 日志记录 — 重大变更:长期缓存: https://webpack.docschina.org/blog/2020-10-10-webpack-5-release/#major-changes-long-term-caching

[6]Webpack 文档 Assert module: https://webpack.docschina.org/guides/asset-modules/

[7]Webpack 文档 tree-shaking: https://www.webpackjs.com/guides/tree-shaking/

[8]Webpack 文档 Node.js API 接口: https://webpack.docschina.org/api/node/

[9]webpack 文档 Web Workers: https://webpack.docschina.org/guides/web-workers/

本文标题:Webpack5实践-构建效率倍速提升!
标题URL:http://www.shufengxianlan.com/qtweb/news38/217288.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联