最近一段时间, 在尝试 easywebpack 工程化方案升级到 Webpack 4 版本,在此期间遇到比较多问题:
- Webpack 4 虽然发布了,但没有文档,只能看源代码
- Webpack 4 相关插件没有及时适配, 需要提issue,让作者适配,需要等待
- ssr 构建中遇到问题 6681
- 配置适配兼容,包括 mode, commonsChunk, 默认插件
- 骨架升级测试, 会遇到一些奇怪问题,然后去升级对应的插件
Webpack 4 最新问题(2018-3-27)
- 目前
extract-text-webpack-plugin
最新版本不支持 webpack 4.3.0 版本. webpack 4.2.0 以下可用。 - 目前从 extract-text-webpack-plugin issues 了解, 未来 extract-text-webpack-plugin 将废弃,作者建议使用 mini-css-extract-plugin 插件。
- easywebpack 工程化方案近期会适配, 具体进展见 extract-text-webpack-plugin 不再支持 Webpack 4.3.0
Webpack 4 版本特性
- 配置默认初始化一些配置, 比如 entry 默认 ‘./src’
- 开发模式和发布模式, 插件默认内置
- CommonsChunk 配置简化
- 使用 ES6 语法,比如 Map, Set, includes
- 新增 WebAssembly 构建支持
- 如果要使用 webpack cli 命令,需要单独再安装 webpack-cli
目前 Webpack4 已经基本稳定,还是有些 bug 再不断的修复,目前已经 4.1.1。 具体见:https://github.com/webpack/webpack/releases 目前 Webpack 4 的文档还没有出来,只能看 Webpack 源码了。
配置
默认配置
在 Webpack 4 中,不再强制要求指定 entry 和 output 路径。webpack 4 会默认 entry 为 ./src,output 为 ./dist
构建模式 mode:
Webpack 4 配置, 必须配置 mode 属性, 可选值有 development,production,none
development 默认开启插件(无需配置):
- NamedModulesPlugin->optimization.namedModules
- development 模式 使用 eval 构建 module,用来提升构建速度
- webpack.DefinePlugin 插件的 process.env.NODE_ENV 的值不需要再定义,默认是 development
production 默认开启插件(无需配置):
- NoEmitOnErrorsPlugin->optimization.noEmitOnErrors
- ModuleConcatenationPlugin->optimization.concatenateModules
- webpack.DefinePlugin 插件的 process.env.NODE_ENV 的值不需要再定义,默认是 production
公共代码提取
Webpack3的commonschunk hash问题非常的不雅,使用复杂, Webpack 4 直接将 CommonsChunkPlugin 插件直接改为 optimization.splitChunks 和 optimization.runtimeChunk 两个配置
- Webpack 3
plugins:[
new webpack.optimize.CommonsChunkPlugin({ names: 'common'}),
new webpack.optimize.CommonsChunkPlugin({ name: 'runtime', chunks:['common']})
]
- Webpack 4
optimization: {
splitChunks: {
chunks: 'all',
name: 'common',
},
runtimeChunk: {
name: 'runtime',
}
}
压缩
压缩插件更新到 uglifyjs-webpack-plugin 1.0 版本,支持多进程压缩,缓存以及es6语法,无需单独安装转换器。当 mode=’production’ 默认开启压缩,无需配置。可以通过 optimization.minimize
和 optimization.minimizer
自定义配置。测试发现,第二次打包时间是第一次打包的一半左右。
optimization.minimize
是否启用压缩optimization.minimizer
制定压缩库, 默认uglifyjs-webpack-plugin 1.0
optimization: {
minimize:true
}
Webpack4 代码: WebpackOptionsDefaulte.js#L261
优化配置
Webpack 4 默认内置了一些配置, 但额外又增加了一些配置,比如 optimization 配置属性,差不多 20 各左右的属性配置, 具体看webpack/schemas/WebpackOptions.json
sideEffects 构建大小优化
Webpack 4 提供了 sideEffects 的配置,引入的第三方插件在 package.json 里面配置 sideEffects:false 后,据说是可以大幅度地减小打包出的文件的体积,具体待验证。
目前初步了解 sideEffects 的信息:sideEffects:false 表示该模块无副作用。当你需要导入,但不需要导出任何东西时,但需要在导入时做其他事情(必然初始化,pollyfill等),这就是导入模块的副作用. 目前对这个理解的不多,具体在第三方库的构建上面没有一个直观的感受,需要继续慎入了解。
目前查到的资料:https://stackoverflow.com/questions/41127479/es6-import-for-side-effects-meaning
插件事件注册与调用
Webpack4 代码层面最大的变化是整个Plugin的事件注册和事件触发机制完全重写了,导致大部分第三方插件都要修改才能用,有些插件作者一两年都没有更新,提了issue只能耐心等待,如果要用只能自己硬着头皮去翻源码然后PR了。 到目前为止, 常用的插件都已经适配。
Webpack3:
注册:
compiler.plugin(‘done’,callback)
触发:
compilitation.applyPlugins(‘done’,params)
Webpack4:
- 注册:
compiler.hooks.done.tap(‘mypluinname’,callback)
- 触发:
compiler.hooks.done.call()
常用插件版本
- eslint-loader: ^ 2.0.0
- file-loader:^1.1.10
- vue-loader: ^14.1.1
- webpack-hot-middleware
- extract-text-webpack-plugin: ^4.0.0-beta.0
工程化支持
easywebpack 前端工程化方案已经支持 Webpack4 配置, 对应方案是 ^4.x.x 版本。
如果你之前已经使用 easywebpack(webpack3)工程化方案, 你只需要按照版本发布指引升级或删除 package.json 对应插件依赖即可。 webpack.config.js
无需修改,easywebpack 4 已经向下兼容了。
已经适配 Webpack4 的骨架项目代码在对应的 webpack4 分支,有需要可以玩玩。
-
egg-vue-webpack-boilerplate#webpack4 基于 Egg + Vue + Webpack4 多页面SSR项目
-
egg-react-webpack-boilerplate#webpack4 基于 Egg + React + Webpack4 多页面SSR项目
-
webpack-static-html#webpack4 HTML静态多页面 Webpack 构建工程化解决方案骨架
参考资料
https://github.com/webpack/webpack/releases
https://medium.com/webpack/webpack-4-released-today-6cdb994702d4
https://github.com/dwqs/blog/issues/60