拥抱webpack4,有效缩减构建时间57%+
背景
最近有感觉到,随着系统模块数量的增加,wepack编译打包的速度越来越慢,于是我想给项目做一下优化升级,也借此机会系统地学习一下webpack4。
升级过程
当前版本
"dependencies": {
"@fullcalendar/core": "^4.2.0",
"@fullcalendar/daygrid": "^4.2.0",
"@fullcalendar/interaction": "^4.2.0",
"@fullcalendar/vue": "^4.2.2",
"axios": "0.18.1",
"babel-polyfill": "6.26.0",
"echarts": "4.0.4",
"element-ui": "2.10.0",
"jquery": "3.3.1",
"js-cookie": "2.2.0",
"js-md5": "0.7.3",
"lodash": "4.17.5",
"moment": "^2.24.0",
"node-sass": "^4.11.0",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"qs": "6.5.1",
"vue": "2.6.10",
"vue-router": "3.0.3",
"vuex": "3.1.1"
},
"devDependencies": {
"autoprefixer": "7.2.3",
"babel-core": "6.26.0",
"babel-eslint": "8.0.3",
"babel-helper-vue-jsx-merge-props": "2.0.3",
"babel-loader": "7.1.2",
"babel-plugin-syntax-jsx": "6.18.0",
"babel-plugin-transform-runtime": "6.23.0",
"babel-plugin-transform-vue-jsx": "3.7.0",
"babel-preset-env": "1.6.1",
"babel-preset-stage-2": "6.24.1",
"chalk": "2.3.0",
"copy-webpack-plugin": "4.2.3",
"css-loader": "0.28.7",
"eslint": "4.13.1",
"eslint-friendly-formatter": "3.0.0",
"eslint-loader": "1.9.0",
"eslint-plugin-html": "4.0.1",
"eventsource-polyfill": "0.9.6",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.5",
"friendly-errors-webpack-plugin": "1.6.1",
"html-webpack-plugin": "2.30.1",
"node-notifier": "5.1.2",
"optimize-css-assets-webpack-plugin": "3.2.0",
"ora": "1.3.0",
"portfinder": "1.0.13",
"postcss-import": "11.0.0",
"postcss-loader": "2.0.9",
"rimraf": "2.6.2",
"sass-loader": "6.0.6",
"semver": "5.4.1",
"shelljs": "0.7.8",
"svg-sprite-loader": "4.1.6",
"uglifyjs-webpack-plugin": "1.1.3",
"url-loader": "0.6.2",
"vue-loader": "15.7.0",
"vue-style-loader": "4.1.2",
"vue-template-compiler": "2.6.10",
"webpack": "3.10.0",
"webpack-bundle-analyzer": "2.9.1",
"webpack-dev-server": "2.9.7",
"webpack-merge": "4.1.1"
}
目标版本
"dependencies": {
"@fullcalendar/core": "^4.2.0",
"@fullcalendar/daygrid": "^4.2.0",
"@fullcalendar/interaction": "^4.2.0",
"@fullcalendar/vue": "^4.2.2",
"axios": "0.18.1",
"babel-polyfill": "6.26.0",
"echarts": "4.0.4",
"element-ui": "2.10.0",
"jquery": "3.3.1",
"js-cookie": "2.2.0",
"js-md5": "0.7.3",
"lodash": "4.17.5",
"moment": "^2.24.0",
"node-sass": "^4.11.0",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"qs": "6.5.1",
"vue": "2.6.10",
"vue-router": "3.0.3",
"vuex": "3.1.1"
},
"devDependencies": {
"autoprefixer": "9.6.1",
"babel-core": "6.26.3",
"babel-eslint": "10.0.3",
"babel-helper-vue-jsx-merge-props": "2.0.3",
"babel-loader": "^7.1.5",
"babel-plugin-syntax-jsx": "6.18.0",
"babel-plugin-transform-runtime": "6.23.0",
"babel-plugin-transform-vue-jsx": "3.7.0",
"babel-preset-env": "1.7.0",
"babel-preset-stage-2": "6.24.1",
"chalk": "2.4.2",
"copy-webpack-plugin": "5.0.4",
"css-loader": "3.2.0",
"eslint": "6.3.0",
"eslint-friendly-formatter": "3.0.0",
"eslint-import-resolver-webpack": "^0.11.1",
"eslint-loader": "3.0.0",
"eslint-plugin-vue": "^5.2.3",
"eventsource-polyfill": "0.9.6",
"file-loader": "4.2.0",
"friendly-errors-webpack-plugin": "1.7.0",
"html-webpack-plugin": "3.2.0",
"mini-css-extract-plugin": "^0.8.0",
"node-notifier": "5.1.2",
"optimize-css-assets-webpack-plugin": "3.2.0",
"ora": "1.3.0",
"portfinder": "1.0.13",
"postcss-import": "12.0.1",
"postcss-loader": "3.0.0",
"rimraf": "2.6.2",
"sass-loader": "8.0.0",
"semver": "5.4.1",
"shelljs": "0.7.8",
"svg-sprite-loader": "4.1.6",
"uglifyjs-webpack-plugin": "2.2.0",
"url-loader": "2.1.0",
"vue-loader": "15.7.1",
"vue-style-loader": "4.1.2",
"vue-template-compiler": "2.6.10",
"webpack": "4.39.3",
"webpack-bundle-analyzer": "3.4.1",
"webpack-cli": "^3.3.8",
"webpack-dev-server": "3.8.0",
"webpack-merge": "4.2.2"
}
第一步
升级webpack到4.39.3版本,npm run dev遇到了报错......
npm run dev报错
webpack-dev-server版本过低
Error: Cannot find module 'webpack/bin/config-yargs'
应该是webpack与webpack-dev-server版本不符,于是升级webpack-dev-server到3.8.0版本。
webpack-cli缺失
The CLI moved into a separate package: webpack-cli
Please install 'webpack-cli' in addition to webpack itself to use the CLI
-> When using npm: npm i -D webpack-cli
-> When using yarn: yarn add -D webpack-cli
internal/modules/cjs/loader.js:584
throw err;
^
Error: Cannot find module 'webpack-cli/bin/config-yargs'
webpack4将webpack-cli单独分离出来了,因此提示我们安装webpack-cli,那就直接安装吧。
html-webpack-plugin版本问题
10% building 2/2 modules 0 active(node:8596) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
(node:8596) DeprecationWarning: Tapable.apply is deprecated. Call apply on the plugin directly instead
53% building 363/366 modules 3 active D:\coollu\projects\coollu-v3\source-code\develop\coollu-cloud-web\node_modules\core-js\modules\_array-reduce.jsD:\coollu\projects\coollu-v3\source-code\develop\coollu-cloud-web\node_modules\html-webpack-plugin\lib\compiler.js:81
var outputName = compilation.mainTemplate.applyPluginsWaterfall('asset-path', outputOptions.filename, {
^
TypeError: compilation.mainTemplate.applyPluginsWaterfall is not a function
考虑是html-webpack-plugin版本问题,升级至3.2.0
extract-text-webpack-plugin?
10% building 2/2 modules 0 active(node:19732) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
查到是因为extract-text-webpack-plugin不再支持webpack4.3,需要改用mini-css-extract-plugin。
ps: extract-text-webpack-plugin是用来抽取依赖的.css文件的,防止样式全部打包在js bundle里太大。改用了mini-css-extract-plugin后,该报错并未消除,考虑要用compiler钩子重写一些东西,先在这埋个坑,后面弄明白了再来填坑。
eslint-loader升版本
Module build failed (from ./node_modules/eslint-loader/index.js):
TypeError: Cannot read property 'eslint' of undefined
at Object.module.exports (D:\coollu\projects\coollu-v3\source-code\develop\coollu-cloud-web\node_modules\eslint-loader\index.js:148:18)
升级eslint-loader
file-loader升版本
Module build failed (from ./node_modules/file-loader/dist/cjs.js):
TypeError: Cannot read property 'context' of undefined
at Object.loader (D:\coollu\projects\coollu-v3\source-code\develop\coollu-cloud-web\node_modules\file-loader\dist\index.js:34:49)
升级file-loader
npm run build报错
改用splitChunks
webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.
使用webpack4的optimization.splitChunks替代CommonsChunkPlugin
vue-loader升版本
ERROR in ./src/App.vue?vue&type=style&index=0&id=7c362b6c&lang=scss&scoped=tr (./node_modules/mini-css-extract-plugin/dist/loader.js??ref--10-0!./node_mods/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=0&id=62b6c&lang=scss&scoped=true&)
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.:
ModuleParseError: Module parse failed: Unexpected character '#' (14:0)
File was processed with these loaders:
* ./node_modules/vue-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
考虑是vue-loader版本问题,先升级vue-loader@15.7.1
babel-loader降版本
ERROR in ./src/main.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Cannot find module '@babel/core'
babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'.
把babel-loader@8降低了版本,调整为babel-loader@7
ps: 想了一下,觉得可能其他的loader版本也会过低,于是将其他的loader都进行了升级,具体见package.json。
优化打包速度
happypack
一个号称用多进程策略提升webpack打包速度的插件,真的挺管用的。
happypack允许您并行转换多个文件,从而加快了webpack的构建速度。
安装:
npm install --save-dev happypack
简单配置如下:
const HappyPack = require('happypack')
// webpack配置,只列出关于happypack的配置
rules: [
// ...其他rule
{
test: /\.js$/,
// 注释掉原来的babel-loader,改用happypack/loader
// loader: "babel-loader",
use: ['happypack/loader'],
include: [
resolve("src")
]
}
],
plugins: [
// ...其他plugin
// 安装说明简单配置了一下
new HappyPack({
// 将我们刚才注释的loader放在这,告诉happypack
loaders: ['babel-loader'],
// 开启4个子进程,据说是最优解
threads: 4
})
]
总结
经过大量npm包版本的调整,以及webpack配置的修改(主要是optimization的调整;把extract-text-webpack-plugin换成了mini-css-extract-plugin;加入了happypack),报错基本上消除了,经测试,dev和prod环境都没有功能上的问题,热加载,编译,打包速度确实得到了显著提升。
热加载
速度得到了显著提升,之前改一行代码,热加载编译的时间差不多要花
1min,让人难受;优化后,基本上控制在<=5swebpack升级前打包:Hash: 35f207120dd3736758dd
Version: webpack 3.10.0
Time: 95987ms
大概需要
96s的打包时间。webpack升级后打包:Hash: fb73468076752cad58f6
Version: webpack 4.39.3
Time: 61597ms
打包时间降低到
61.6s,节约了34.4s,打包效率提升了35.8%以上。使用
happypack后:Happy[1]: Version: 5.0.1. Threads: 4
Happy[1]: All set; signaling webpack to proceed.
Hash: a635e8b39b7064adf41c
Version: webpack 4.39.3
Time: 41047ms
打包时间降低到
41s,再次节约了20.6s!总共节约了55s,与升级前相比,打包效率提升了57%以上。
当然可优化的空间还很大,webpack4还有很多东西值得我们去折腾,优化之路还在继续!
扫一扫下方小程序二维码或搜索Tusi博客,即刻阅读最新文章!

拥抱webpack4,有效缩减构建时间57%+的更多相关文章
- 利用构建缓存机制缩短Docker镜像构建时间
在使用Docker部署PHP或者node.js应用时,常用的方法是将代码和环境镜像打包成一个镜像然后运行,一些云厂商提供了非常便捷的操作,只需要把我们的代码提交到VCS上,然后它们就会帮我们拉取代码并 ...
- 优化webpack构建时间的小技巧
在之前工作的地方,我们一直使用webpck去构建.但是,经过长达四年的更新迭代,每个人都在同一个项目中做了不同的操作和更新,这导致我们生产构建时间达到了惊人的一分半,watch模式的rebuild也达 ...
- Jenkins插件之显示构建时间
1.进入jenkin插件管理器中,安装 Timestamper 插件 2.安装完成后,进入到构建任务里面,在 构建环境 中勾选 Add timestamps to the Console Outp ...
- Java 项目热部署,节省构建时间的正确姿势
上周末,帮杨小邪(我的大学室友)远程调试项目.SpringBoot 构建,没有热部署,改一下就得重启相关模块.小小的 bug ,搞了我一个多小时,大部分时间都还在构建上(特么,下次得收钱才行).我跟他 ...
- Jenkins构建时间Poll Scm的设置
每15分钟构建一次:H/15 * * * * 或*/15 * * * * 每天8点构建一次:0 8 * * * 每天8点~17点,两小时构建一次:0 8-17/2 * * * 周一到周五,8点~1 ...
- Jenkins定时构建时间设置
每隔5分钟构建一次 H/ * * * * 每两小时构建一次 H H/ * * * 每天中午12点定时构建一次 H * * * 每天下午18点定时构建一次 H * * * 在每个小时的前半个小时内的每1 ...
- Jenkins构建时间Poll Scm的设置(常用设置)
每15分钟构建一次:H/15 * * * * 或*/5 * * * * 每天8点构建一次:0 8 * * * 每天8点~17点,两小时构建一次:0 8-17/2 * * * 周一到周五,8点~17 ...
- [Jenkins] Jenkins配置自动构建时间代表意义
- react - web + webpack4 从0构建
https://www.jianshu.com/p/91a4214b913b 文章https://github.com/Liao123/react-web 可运行的代码 dev分支
随机推荐
- Python中最简单快捷的输出方式
格式化输出最简单的方式之哑巴填充公式 name=ludundun age=25 print(f'hello {name},your age is {age}') 输出内容: hello ludundu ...
- 微信pc端和手机上传处理
一.原因 在微信通过电脑版和浏览器登录时,调用了微信上传的接口,wx.getLocalImgData或返回失败. 没办法,只有处理当电脑上传时,使用ajaxuploadfile上传. 二.方法 fun ...
- 程序员offer沟通的4个基本原则
常柱 架构未来 你需要就一份新工作进行沟通时:比如你的薪水.福利,或者我个人最喜欢的每周工作时间缩短等,当公司问你“你想要多少?”或者“这是我们的报价,你说呢?” 最后关于薪资的谈话可能是最伤脑筋 ...
- tp5.1批量删除商品
选中要删除的商品,点击批量删除 先在控制器使用sql语句查出商品信息goods 然后在html源码中使用goods变量. <table> {foreach $goods as $item} ...
- SMTP email from C#
/// <summary> /// 一人一附件发送邮件 /// 2017-05-17 涂聚文 GeovinDu /// </summary> /// <param nam ...
- 通知advice
基于注解的Spring AOP开发,来自https://www.cnblogs.com/junzi2099/p/8274813.html 1.定义目标类接口和实现类 2.编写Spring AOP的as ...
- 集合系列 Queue(十):LinkedList
我们之前在说到 List 集合的时候已经说过 LinkedList 了.但 LinkedList 不仅仅是一个 List 集合实现,其还是一个双向队列实现. public class LinkedLi ...
- 【10分钟学Spring】:(二)一文搞懂spring依赖注入(DI)
Spring最基础的特性就是创建bean.管理bean之间的依赖关系.下面通过具体实例演示该如何装配我们应用中的bean. Spring提供了三种主要的装配机制 在xml中进行显示的配置 在Java中 ...
- .net core 2.1 Nlog.Web.AspNetCore Nlog日志
1.先创建 .net core Web 应用程序,选择API 2.安装 Nuget 包:Nlog.Web.AspNetCore install-package Nlog install-package ...
- inux CPU监控分析
一.vmstat 可对操作系统的虚拟内存.进程.CPU活动进行监控 Procs(进程) r: 运行队列中进程数量,这个值也可以判断是否需要增加CPU.(长期大于1) b: 等待IO的进程数量. Mem ...