在长文分享《GitChat: 使用 Webpack 开发企业官网》中,我使用 Webpack 重构了官网开发工具链,效果很好,现在的开发效率也很高。
当时遗留下来一个问题:
- 我会把所有页面的 CSS 打包到一起。因为 CSS 尺寸不大,打包到一起利用浏览器缓存,可以改善后续页面的打开速度。
- 打包+抽取 CSS+合并,使用 mini-css-extract-plugin,配合 splitChunks。这里遵循的是 官方文档。
- 打包完成后,除了包含所有样式的 screen.css,还会生成 screen.js,里面包含 webpack 模块的初始化代码,只有一行,几十个字节,但是很重要,必须在其它模块前先完成加载。
于是我就面临一个选择:
- 留着这个东西,会略微影响网页打开速度。因为它毕竟是个 JS 文件,要单独加载和运行。
- 想办法去掉它,比如利用 html-webpack-plugin 提供的各种钩子,写个插件,把它的内容提取出来,放进 html 或者跟 app.js 合并,等等。但是这个时机很难找,我尝试过一段时间,无果。
最后综合考虑成本和收益,以及看到这个 issue:https://github.com/webpack-contrib/mini-css-extract-plugin/issues/151 之后,我决定再等等,webpack 5 的时候再说。
最近 Webpack 5 终于发布了,我就来试试升级解决这个问题。
升级 Webpack 5
首先升级 Webpack@5 和 webpack-cli@4。新版本虽然底层变化很大,API 层面还是尽量保持了兼容性,所以配置文件可以不改或者小改(理论上)……果然编译就报错了,错误信息很扯:Error: Can't resolve './src'
,非常莫名其妙。Google 半天无果,后来我突然想起,假如 Webpack 配置信息没加载成功,那么它会默认使用 ./src/index.js
作为入口文件,是不是这个问题呢?
然后搜了半天,没有 dump configuration 的选项,只好仔细看文档。迁移指导里并没有关于配置文件的内容。那就看文档,然后发现,之前 Webpack@4,配置文件可以输出 Object、Promise、或者函数,所以项目的配置文件就是直接输出的 Promise;如今,虽然标题仍然是“Exporting a Promise”,但实际上 module.exports
导出的是函数,只是函数的返回值可以是 Promise。
这里嫌疑很大,所以我就试着改了一下,用函数包裹 Promise,果然可以了。
移除不必要的 screen.js
我会把所有样式都打包到 screen.css 里,这是从 HTML5 boilerplate 学到的。然后 Webpack 就会生成 screen.js,这是个多余的文件,只有坏处,前面说过。
我以为 Webpack@5 之后这个问题就自然解决了,结果看了一眼,还有,只好继续寻找解决方案。之前的关键词忘记了,issue 也没关注,所以多花了不少时间。所幸最终找到了:https://github.com/webpack/webpack/issues/7300#issuecomment-702840962。
- 升级 webpack@5,webpack-cli@4,自不用说
- 升级 mini-css-extract-plugin@1,新版本包含了需要的补丁
- 如下修改代码
{
optimization: {
splitChunks: {
cacheGroups: {
styles: {
type: 'css/mini-extract', // 重点在这里
chunks: 'all',
// If you need this uncomment
// enforce: true,
},
},
},
},
}
然后重新编译,screen.js 就不见了,非常爽。
欢迎吐槽,共同进步