webpack在2018年2月25号发布最新的4.0版本, 更新了以下内容:
- 性能大幅提升(没感觉..)
- 新增mode配置, 可选择设置为development和production, 实现零配置启动(意义不大…)
- 废弃CommonsChunkPlugin, 使用optimize.splitChunks和optimization.runtimeChunk替代
- 支持WebAssembly
- 支持CommonJS, AMD, ESM等模块系统, 可以直接导入.mjs扩展名的模块文件, 对wasm模块也有实验性的支持
今天我将自己维护的React脚手架从webpack2升级到了4, 记录一下需要改动的地方. 本篇是”不完全指南”, 欢迎补充更多内容
升级依赖版本
- webpack: 2.2.1 -> 4.1.1
- webpack-dev-middleware: 1.10.0 -> 3.0.1
- html-webpack-plugin: 2.28.0 -> 3.0.6
- extract-text-webpack-plugin: 2.0.0 -> 4.0.0-beta.0
- copy-webpack-plugin: 4.0.1 -> 4.5.1
- react-hot-loader: 3.0.0-beta.7 -> 4.0.0
webpack config添加mode字段
1 2 3 4
| module.exports = { mode: 'development' }
|
删除UglifyJsPlugin插件
在mode: production下, 会自动进行代码压缩. 可以修改配置项 optimization.minimize: 'on'/'off'
控制是否启用, 修改配置项 optimization.minimizer: {}
调整默认行为
删除CommonsChunkPlugin插件
替代为配置项 optimization.splitChunks
, 可配置内容如下:
最简单的配置
1 2 3 4 5
| optimization: { splitChunks: { chunks: 'all', }, }
|
手动定制vendor内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| module.exports = { entry: { vendor: ['react', 'react-dom', 'redux'] }, optimization: { splitChunks: { cacheGroups: { vendor: { chunks: 'initial', name: 'vendor', test: 'vendor', enforce: true, }, }, }, }, }
|
字符串或者正则匹配控制vendor内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| module.exports = { entry: { vendor: ['react', 'react-dom', 'redux'] }, optimization: { splitChunks: { cacheGroups: { vendor: { chunks: 'initial', name: 'vendor', test: path.resolve(__dirname, '../node_modules'), enforce: true, }, }, }, }, }
|
函数控制vendor内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| module.exports = { entry: { vendor: ['react', 'react-dom', 'redux'] }, optimization: { splitChunks: { cacheGroups: { vendor: { chunks: 'initial', name: 'vendor', test: module => /node_modules/.test(module.context), enforce: true, }, }, }, }, }
|
react-hot-loader
原来的写法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import React from 'react'; import ReactDom from 'react-dom'; import { AppContainer } from 'react-hot-loader'; import App from './App'; const render = (Component) => { ReactDom.render( <AppContainer> <Component /> </AppContainer>, document.getElementById('app'), ); }; render(App); if (module.hot) { module.hot.accept('./App', () => { render(App); }); } import React, { Component } from 'react'; export default class App extends Component { render() { return <div>App</div> } }
|
现在改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import React from 'react'; import ReactDom from 'react-dom'; import App from './App'; ReactDom.render( <App />, document.getElementById('app'), ); // App.jsx import React, { Component } from 'react'; import { hot } from 'react-hot-loader'; import Hello from './components/Hello'; class App extends Component { render() { return <div>App</div> } } export default hot(module)(App);
|
还有, 在webpack html-webpack-plugin-after-emit
事件回调中, 删除 hotMiddleware.publish({ action: 'reload' });
语句
引用内容
webpack@4.0.0 release log
webpack 4.0.0-alpha.5 feedback #6357