webpack 3.X - 4.X 之升级之旅

2019-07-14  本文已影响0人  行走的蛋白质

鉴于公司项目越来越大编译的速度越来越慢,打出来的包也越来越大。webpack4 渐渐的走进了我们的视野,据官方表明,webpack4 新增加了很多默认配置项使开发人员不用编写 webpack.config.js 就能打包开发。极大的降低了学习成本,并对其进行了打包速度的优化以及压缩文件大小的优化。此次升级以 TTK 前端开源框架ttk-app-core 项目 做为实例。欢迎各路大神加入我们。


文章最末附图升级前后启动提升 31% 编译构建提升 43% 速度,可以看出提升是很明显的,后续我会对项目进行压缩优化(因为之前大神已经进行过很多的优化所以目前不知道还能有多少优化的空间),让我们期待 webpack4 更好的表现吧。


升级过程

网上升级的帖子也有很多大家可以自行搜索,在此我只记录一下自己成功升级后的方法。分三步

npm install -D webpack@latest webpack-cli webpack-dev-server@latest

踩坑之旅 error

遇到报错不要慌乱首先看 bash 的输出报错是什么,然后 Bing 即可。下述错误不进行排序,因为每个人遇到的顺序肯定是不一样的。

首先进行的是 start

webpackerr1.jpg

找到报错大致意思是 DllRefrencePlugin 这个插件是无效的操作。那么就要先看一下项目中 webpack.config.js 中的配置了

plugins.push(new webpack.DllReferencePlugin({
    context: __dirname,
    manifest: merge(require('./vendor/vendor.manifest.json')),
}))

通过搜索老外的得出来的解决方案:
Simply running webpack --config webpack.config.vendor.js with the latest webpack-cli rebuilt vendor-manifest.json (the DLL), and allowed me to get past the error.
大致意思是我们需要重新生成一下我们 vendor 中的 manifest.json 文件即可,本项目需要在 bash 中执行 npm run dll 期间收到一些 warning 因为不影响流程所以我把他们都放到了最后来讲解。然后继续 start

webpackerr2.jpg

这个就很明确的告诉我们 webpack.optimize.CommonsChunkPlugin 这个东西被移除了你需要 config.optimization.splitChunks 来代替它。那么首先我就需要注释掉对应部分的代码并添加新配置如下:

/*plugins.push(new webpack.optimize.CommonsChunkPlugin({
    names: ['edf'],
    filename: '[name].min.js',
    minChunks: Infinity
}))*/
//并在配置中增加如下代码。
    optimization: {
        splitChunks: { 
            chunks: 'async',
            minSize: 30000,
            maxSize: 0,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                /*vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10
                },*/
                default: {
                    minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true
                }
            }
        }
    },

然后继续 start 这次看到进度百分比了说明我的努力已经收到成效了。

webpackerr3.jpg

这个经查阅资料分析是 css 代码分离出问题了,那么我们使用的插件是 extract-text-webpack-plugin 现在问题就简单了直接 npm install extract-text-webpack-plugin@latest -D 命令升级即可
然后 start 发现会报一个重复的错误,那么继续查阅资料发现最新版本仍不能满足 webpack4 我们需要升级成 next 版本,执行命令 npm install extract-text-webpack-plugin@next -D
然后继续 start Compiled successfully. 成功了!但是打开项目发现样式错乱了。这时候我首先想到的就是把 样式相关的 loader 进行升级,查找了一下我项目大致用到了 css-loader、less、less-loader、file-loader、url-loader、style-loader 不管三七二十一全部升级。然后喜闻乐见的又报错了

webpackerr4.jpg

通过查阅资料我们知道这是 less 升级到 3.0 之后的报错。解决方案是修改less的配置 options: { javascriptEnabled: true } 对应项目代码如下:

plugins.push(new HappyPack({
    id: 'css',
    // loaders: ['css-loader', clientInformation'less-loader'],
    loaders: [{
        loader: 'css-loader',
    }, {
        loader: "less-loader",
        options: {
            "modifyVars": modifyVars, // 变量
            "javascriptEnabled": true
        }
    }],
    threadPool: happyThreadPool, // 变量
}))

接下来我们继续 start,这次又启动成功了。尴尬的是页面还是错乱的,所以说上述改进好像没有生效,但是作为插件升级也就不回退了,理论上是有利于后续打包压缩优化的。
接下来我们继续分析和样式有关的插件 plugin 有什么,我们就找到了 extract-text-webpack-plugin 这个上面让我们踩了两次坑的破插件,然后我们查看 github 文档我们会看到它的 options 有这样一个属性说明,截图如下:

extract-text-webpack-plugin1.jpg

大致意思呢就是当我们使用 CommonsChunkPlugin 插件并且 ExtractTextPlugin.extract 有在公共模块使用时 allChunks 属性必须设置为 true。虽然我们已经弃用了 CommonsChunkPlugin 但是还是需要尝试一下,所以我们修改代码如下:

plugins.push(new ExtractTextPlugin({
    filename: '[name].css',
    allChunks: true 
}))

然后 start,这次又启动成功了。而且页面完好,点进项目也没有出问题。至此我们启动算是大功告成。接下来是踩在启动的肩膀上来构建编译项目。来看项目的打包 release 命令:

"release": "cross-env NODE_ENV=single npm run build && npm run css && npm run modules && npm run merge:manifest",
"build": "cross-env NODE_ENV=production NODE_ENV=single webpack --progress --colors --display-error-details --config webpack.config.prd.js",
"css": "cross-env NODE_ENV=production NODE_ENV=single webpack --progress --config webpack.config.css.prd.js",
"modules": "npm run module --edf && npm run module --test",
"module": "cross-env NODE_ENV=production webpack --progress --colors --display-error-details --config webpack.config.module.js",
"merge:manifest": "node createManifest.js",

所以我只需要查看并先按照上述 webpack.config.js、webpack.dll.js 来做修改 webpack.config.prd.js、webpack.config.css.prd.js、webpack.config.module.js、createManifest.js 这四个文件的代码。
然后执行 release 喜闻乐见的报错了

extract-text-webpack-plugin3.jpg

大致意思呢是 webpack4 中抽离 css 用 mini-css-extract-plugin 来代替 extract-text-webpack-plugin 这个大坑,虽然查阅资料还有其他解决方案继续使用 extract-text-webpack-plugin 但是我放弃抵抗了决定弃用它,做如下改动:

// 首先在 bash 中安装
npm install -D mini-css-extract-plugin 
// 然后引入进来
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 根据官方说明来做代码调整如下
// 插件替换
/*plugins.push(new ExtractTextPlugin({
    filename: '[name].css',
    allChunks: true
}))*/
plugins.push(new MiniCssExtractPlugin({ // webpack 4
    filename: '[name].css',
    chunkFilename: '[id].css',
}))
// module 替换引入
        rules: [{
            test: /\.(css|less)/,
            /*use: ExtractTextPlugin.extract({ // webpack 3
                use: ['happypack/loader?id=css']
            })*/
            use: [MiniCssExtractPlugin.loader, 'happypack/loader?id=css'] // webpack 4
        }

然后先 start 试验一下启动成功项目也没有任何问题,那么我们继续 release 操作打包成功。启动 MAMP 启动服务器来测试一下,没有任何问题至此大功告成!!!
当然在实际升级过程中并没有这么顺利,走了很多很多的弯路和意想不到的报错,为此付出了很多的努力,最后总结出这么一套流程。看上去是非常之简单了。

踩坑之旅 warning

这就是 webpack4 让你在配置文件设置一下你的环境是生产还是开发,我们只需要在配置文件中设置 mode 属性即可。

warning2.jpg

这是建议你的入口文件大小限制的,我们只需要告诉它不要管我就可以了,我们需要在配置文件中加入 performance: { hints: false } 的属性设置即可。

项目启动/编译构建升级前后时间对比
升级前start.jpg 升级后start.jpg 升级前release1.jpg 升级前release2.jpg 升级前release3.jpg 升级前release4.jpg 升级后release1.jpg 升级后release2.jpg 升级后release3.jpg 升级后release4.jpg
上一篇 下一篇

猜你喜欢

热点阅读