欧洲杯决赛竞猜平台

Webpack5 实践

admin 2021-07-06 19:57 未知

 

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

对于前端构建工具 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 的生产环境默认开启。

const TerserPlugin = require("terser-webpack-plugin");  module.exports = {   optimization: {     minimize: true,     minimizer: [new TerserPlugin()],   }, }; 

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

test:匹配需要压缩的文件。 include:匹配包含的目录。 exclude:匹配不需要包含的目录。 parallel:多进程并发运行,默认 os.cpus().length - 1。
module.exports = {   optimization: {     minimize: true,     minimizer: [       new TerserPlugin({         test: /\.js(\?.*)?$/i,         include: //includes/,         exclude: //excludes/,         parallel: true         // more ...       }),     ],   }, }; 
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 中,并且反应会更快。

const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = {   module: {     rules: [       {         test: /\.css$/i,         use: [           devMode ? 'style-loader' : MiniCssExtractPlugin.loader,           'css-loader'         ],       },     ],   },   plugins: [new MiniCssExtractPlugin()], }; 

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

CSS 打包后加载图片 404?

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

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

module.exports = {   output: {     publicPath: 'auto'   } } 

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

const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = {   module: {     rules: [       {         test: /\.css$/i,         use: [           devMode ? 'style-loader' : {             loader: MiniCssExtractPlugin.loader,             options: {               publicPath: '../'             }           },         ],       },     ],   },   plugins: [new MiniCssExtractPlugin()], }; 
CSS 代码压缩

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

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); module.exports = {   optimization: {     minimizer: [       new CssMinimizerPlugin(),     ],   }, }; 
性能提升核心缓存优化

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

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

基于内存缓存

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

module.exports = {   cache: {     type: 'memory'   }, }; 
基于 FileSystem 的持久化缓存

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

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

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

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

module.exports = {   cache: {     type: 'filesystem',     buildDependencies: {       config: [__filename],     },     name: `${ process.env.NODE_ENV 

Powered by 欧洲杯决赛竞猜平台 @2018 RSS地图 HTML地图