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

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


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


升级过程

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

  • 首先区别网上一些通过 npm-check-updates 来查看 package.json 中所有包的最新版本并选择安装,我这里只选择安装 webpack webpack-cli webpack-dev-server
npm install -D webpack@latest webpack-cli webpack-dev-server@latest
  • 然后不要着急根据所了解 webpack4 的新变化来修改项目中 webpack.config.js 文件,我选择启动/编译构建我们的项目。一般会在 package.json 的 scripts 中定义为 npm run start / npm run release 这个命令因个人项目定义而异。
  • 最后逐一解决步骤2收到的很多很多的报错。过程中就不一一赘述报错插件的作用介绍了。如果想了解可以看我的 plugin 插件篇 (持续更新常用插件的个人理解,如果找不到你想要的请联系个人邮箱 547106430@qq.com 我们共同学习共同进步)

踩坑之旅 error

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

首先进行的是 start

  • ValidationError: Dll Reference Plugin Invalid Options 截图如下:
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

  • webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead. 截图如下:
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 这次看到进度百分比了说明我的努力已经收到成效了。

  • Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead 截图如下:
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 不管三七二十一全部升级。然后喜闻乐见的又报错了

  • .bezierEasingMixin(); 截图如下:
    Inline JavaScript is not enabled. Is it set in your options?
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 喜闻乐见的报错了

  • .bezierEasingMixin() 但是这个报错我们出现过,在 start 的解决方案并不能满足 release 的打包原因不得而知,我只知道 extract-text-webpack-plugin 插件是个十足的大坑,接下来通过查阅 webpack 的官方文档我们看到下述说明,截图如下:
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
  • WARNING in configuration
    The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
    You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/ 截图如下:
    warning1.jpg

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

  • WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
    This can impact web performance.
    Assets:
    vendor.e282754a.dll.js (1.7 MiB) 截图如下:
warning2.jpg

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

项目启动/编译构建升级前后时间对比
  • start 启动 29828ms 对比 43149ms 快了大概 31% 的样子
升级前start.jpg
升级后start.jpg
  • release 编译构建 52035ms 对比 91424ms 快了大概 43% 的样子
    注:这里 webpack.config.module.js 执行两次因为我们有两个 module 模块。
升级前release1.jpg
升级前release2.jpg
升级前release3.jpg
升级前release4.jpg
升级后release1.jpg
升级后release2.jpg
升级后release3.jpg
升级后release4.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容