webpack v4 升级尝鲜
按照 webpack 其在 Github 上的日程表,不出意外地,本月迎来了 v4 正式版的发布,离发版狂魔的目标又近了一步。毕竟其发明者 Tobias 把正经工作辞掉全身心搞本工具,不多多发版也对不起观众不是。
然而,正如你在使用 v3 时可以看到官方文档的匮乏,遑论这新鲜出炉还热乎的 v4 呢,所以文档什么的就别想了。
但按奈不住猎奇,迅速装上进行了尝鲜升级。
Changelog & 升级迁移
官方的 Migration Guide ,还在 WIP (work in progress),就是说,观望着社区的有志之士进行贡献,毕竟那么多受众嗷嗷待哺,相信不久会出炉。目前的升级,只能摸着石头过河了。所以老项目,先稳一稳,比较新的项目或者玩票性质的 side project,那必需用最新版啊,毕竟这样历史包袱最小。
还是有很多途径可以了解到新版的有用信息的,
- 关注 webpack 的 Medium 主页,里面集中了核心贡献者写的文章,包含最新设计理念,功能介绍,使用指南等(是的,他们快把这里当成写文档的地方了)。
- webpack 源码。随源码自带的 Examples 更新是及时的,对于如何配置使用新版,有很大参考价值。即使是后面 v4 的文档到位了,源码依然是危急时刻的不二之选,如果你写过 webpack 插件,你会懂的。
- 最后,最直接的方式是迈开腿,get your hands dirty,装上新版亲自去探索。从 v3 切到 v4 后,报错一定是有的,逐个去排查,大部分应该都是插件在新的机制下不工作,或者 loader 报 warning。定位到对应组件,然后去其 github 项目页看其是否有针对 v4 适配的新版发布,以及 issues 页相关的升级适配讨论。
下面借着 Changelog 说说升级点。
webpack CLI
更新成 v4 后,最先映入眼帘的是之前的 npm scripts
run 不起来了。新版中将 webpack 命令行工具拆分到单独的仓库中,所以需要额外安装 webpack-cli
。
CLI has been move to webpack-cli, you need to install webpack-cli to use the CLI
npm i -D webpack-cli
零配置,不折腾
webpack 常被诟病的一点是配置麻烦。对于小白用户或是想快速开始产品开发来说,它不让人省心。诚然,市面上有各种 Starter Kit/Boilerplate 集成了成套开发方案,总有一款大致满足需求,但难免也会根据业务自定义一些配置。
本次新版本中引入了 mode
配置项,开发者可在裸奔 none
,开发 development
以及产品 production
三种模式间选择。该配置项缺省情况下默认使用 production
模式。
具体来说,
development
模式给你极致的开发体验,包含浏览器调试相关工具,极快的增量编译,丰富全面的报错信息...production
模式则包含大量发版优化,代码压缩,丝般润滑的运行时优化,开发相关代码的排除,易用,etc.none
不使用预设,等于老版本中全部自己配置的原始状态。
注意这里裸奔模式并不推荐,正如 changelog 中据说:
There is a hidden none mode which disables everything
它是隐藏起来的,没有正式介绍,将来文档中应该也不太提及。但通过 webpack 源码中对于配置项的描述来看,确实是存在的。
"mode": {
"description": "Enable production optimizations or development hints.",
"enum": [
"development",
"production",
"none"
]
},
其实就是将之前需要人肉重复进行的配置,优化及插件引入等工作,打包内置了,似乎0配置(#0CJS)就可以开车了,有点对标 parcel 的意思。无论如何,套餐的出炉可以让大部分人可以享受到「约定大于配置」的省心了。
所以,为原来的配置文件加上 mode
配置,然后可以删除很多冗余配置或插件了。
- 随着不同模式 webpack 会自动设置
process.env.NODE_ENV
为生产环境或产品环境,可以去掉项目中手动的设置。没有验证其设置的环境变量是否有跨平台兼容的问题,如果有的话,还需要借助 cross-env 自己搞。 json-loader
可以功成身退了,新版 webpack 默认支持 json 文件的加载。- NamedModulesPlugin 也隐退了,开发模式下自动开启。
全新的插件引擎
tapable 整体更新带来 api 的变化。webpack 插件机制又是基于此库而生的。所以必然导致许多插件在新版 webpack 中会报错。其插件调用 api 变化了,同时好多 hook 也变了,有的已经不复存在。好在尝试后发现大部分重要的插件,尤其是官方 webpack-contrib 维护的,都第一时间进行了适配。
关于插件及 loader 的更新详见 webpack 4: migration guide for plugins/loaders。
R.I.P. CommonsChunkPlugin
CommonsChunkPlugin,该插件抽取共用代码,进行代码拆分,对于减少冗余及合理打包功不可没。但在新版中移除了。
别急,对应功能只是转移到了 optimize.splitChunks
与 optimization.runtimeChunk
配置项下,并且进行了加强与拓展。
在满足预设条件时,会进行自动的 trunk 拆分和抽取。详见 RIP CommonsChunkPlugin 或 webpack 4: Code Splitting, chunk graph and the splitChunks optimization。
HtmlWebpackPlugin
HtmlWebpackPlugin 的作者 Jan Nicklas 带着小婊子跑路了,以至于如此重要的插件没人进行 webpack v4 的更新适配。因为涉及到 html 的生成,对它的依赖度还挺高。无奈 webpack 官方 fork 了一分进行升级。 所以暂时可以安装这个 fork 的版本。
npm i -D html-webpack-plugin@webpack-contrib/html-webpack-plugin
前面 Jan 其实没跑路,按照 webpack 博客中的说法,人家只是劳务派遣出国了。等忙完这阵就回来更新!
ts-loader
非常给力的是 ts-loader 在 webpack 新版发布后第一时间进行了更新适配。如果项目中在用 TypsScript,那可以将 ts-loader 升级到最新的 v4.0.0 就可以正常编译了。
其实不止是 ts-loader, 官方 webpack-contrib 名下维护的库存不算,其他库的更新响应也很及时,给我的感觉是 webpack 凭借其积攒的实力做到现在的人气,能够振臂一呼,拥趸者众,也是实至名归。
cache-loader
cache-loader,我主要配合 webpack-modernizr-loader 使用。后者可以读取 modernizr 配置文件,动态生成项目中需所依赖的 modernizr 库。因为 modernizr 配置文件不会经常变动,所以将生成的 modernizr 库存缓存起来就显得很有必要了。因为 cache-loader 的 peer dependencies 声明的是 webpack ^2.0.0 || ^3.0.0
,所以运行在 webpack v4 下会有 warning。问题倒不大,因为没有触碰 webpack 变更后的 api 所以能正常跑。将其升级到最新的 v1.2.1 可以解决掉 warning。
loader 类的兼容一般都是这个原因,因为 peer dependency 报 warning。譬如 file-loader,webpack-modernizr-loader 等。所以 loader 部分升级较为轻松。