阅读 1251

webpack5踩坑指南

序言

webpack5即将发布,打算趁发布前踩个坑,之前从alpha版本就有关注,本次重点更新在长期缓存,tree shakking和es6打包这块,具体更新日志可以参考官方。

更新日志

官方更新日志

  • node版本更新为v10。
  • webpack5默认采用es6代码进行输出,4是es5的(可通过设置output.ecmaVersion来使用es5进行打包,默认是采用es2015进行生成)。
  • webpack <= 4带有许多node.js核心模块的polyfill,5去掉了这些模块,专注于与前端兼容的模块。
  • 优化了打包后的文件大小
  • 长期缓存(默认开启)
  • 自定义json解析器
  • 优化后的tree shakking (可以针对嵌套的模块进行分析,未使用将在生产模式删除)
  • splitChunk和模块大小(可以针对js和css样式进行更细致的切割,并用于minSize和maxSize)
  • 模块命名
  • 编译器空闲并关闭(在node中使用wepback()结束后,需要手动调用compiler.close(), compiler是当前webpack实例)

环境准备

  • node v10以上,官方最低8.9.0,个人v13.1.0
  • webpack 5.0.0-beta.7
  • webpack-cli 3.13.0

以上为我个人环境,仅供参考。

参考文章

开始踩坑

打包对比

新建一个webpack.config.js,内容如下

const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].[chunkhash].js'
  }
}
// package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack --mode development",
    "build": "webpack --mode production"
  },
复制代码

上图为webpack5打包后的结果,左边是开发环境,右边是生产环境。

这个是webpack4打包后的结果,左边开发环境,右边生产环境,webpack5相对4来说,打包后的内容少了一丢丢,代码也采用了es6的语法,去掉了webpack4自带的polyfill,体积更小。

上图为4和5的时间对比,5的时间是175ms,4只有96ms,就速度来说,还是4比较有优势,具体原因不明,可能和内部优化有关。

现在来安装html-webpack-plugin和webpack-dev-server,让配置支持热更新和html

npm i html-webpack-plugin webpack-dev-sever -D

// package.json的配置修改为
"dev": "webpack-dev-server --mode development"
复制代码

安装完成后配置变成修改成这样

然后,html-webpack-plugin给我们带来了个惊喜(报错),是不是很刺激,很意外。

说htmlWebpackPluginAlterChunks无法添加这个属性,经过大佬提醒,我们可以通过安装最新版的html-webpack-plugin。

yarn add html-webpack-plugin@next -D
复制代码

安装完成后,重新启动我们的webpack,发现问题已经解决,项目可继续运行。然后发现编译时间太长了,目前还仅仅只有个console和一个什么都没的html页面,我们可以开启webpack的多线程,进行打包,安装terser-webpack-plugin即可,安装完后,配置如下

我们加了一个optimization属性,用来写terserPlugin的配置,通过parallel这个属性,我们可以进行多线程打包,默认是系统的线程数 - 1个,可以手动设置,支持布尔和数字,当然这个插件也可以做代码优化,混淆,去除console等,具体去看官方文档terser-webpack-plugin。启动运行后发现,html-webpack-plugin又给我们带来了一个报错,报错内容如下:

可以参考这个issue, 经过一番查找,找到了原因,我们找到html-webpack-plugin下面的index.js把上面注释掉的那行换成下面的那一行,就可以成功运行了。

好像并没什么变化,试了几次,每次打包时间不固定,可能文件太小吧,优化并不明显。

tree shakking

webpack5的结果

webpack4的结果

5直接把模块里面的内容打印了出来,4把变量打印了出来,共同点是都去掉了未使用的b,官方解释是webpack现在可以针对导出的嵌套模块进行访问,重新导出对象时,可以改善tree shakking,感觉应该是webpack在编译之前,提前对模块的依赖进行分析,然后做了预处理,然后编译时,把未使用的模块直接删掉。深入的就不了解了。 webpack5还开启了optimization.innerGraph,默认在生产模式启动,该选项可以针对模块的符号进行分析,从而找出导入和导入的依赖关系,相对来说,webpack4并没有这个功能。 可以针对以下内容进行分析:

  • function
  • class
  • export default 或变量声明
  • 局部变量
  • 类和函数表达式

现在我们又新加了以下代码

webpack5:
webpack4:
为了方便测试,我加了console.log('test'),从而更好看结果,结果很显然,5并没把test函数使用的其他部分打进去,而4把内容打了进去,webpack5在调用test函数的时候,去分析了当然的引用,从而去掉了未使用的something这个变量, 当设置optimization.sideEffects为false时,将会删除更多内容。

持久缓存

webpack5新增了持久缓存,可通过以下配置开启:

试了下,好像并没什么效果,可能我姿势不对

模块命名id得以确定

上图分别为4和5的打包结果,在webpack4的时候,通过import()加载的模块将会生成下标以数字为标识的模块,webpack5修改了这一设置,改成模块命名,不需要手动通过import(webpackChunkName: "name")进行设置。

总结

webpack5更新的内容大概来说就是这些,本次踩坑并没针对各种loader进行测试,总体来说,webpack相对4来说大小发生了质的变化,速度上来说,还是4更有优势,目前来看,至于正式版本就不清楚了。代码已经上传到github,如果有问题也可以加我Q: 2495713984。

地址:webpack5地址

关注下面的标签,发现更多相似文章
评论