Gulp老项目升级为webpack打包及相关优化
Contents
概览
vue 和 js 改为webpack打包
- 升级babel
- 引入webpack config
- 添加webpack loader
- 生成入口列表 entry
- 结合到gulp流程
- 增加可视化打包分析
开发模式热更新
- webpack-dev-server
vue 拆分多入口 实现按需加载 按需引用vue-component
- vue 文件入口 为指定入口
- vue-web
- vue-mobile
- vue-article
- vue-home
- vue-stock
vue 公共资源抽离vue-common
- 增加splitChunks
- chunks 设置 只抽取vue部分
js 引用方式修改为 从vue引入
- 减少体积
- 不用手动控制js加载
拆分vue路由
lodash 按需引用 去除全局lodash
- 减小体积
- 避免冲突
js资源 preload
- 加快速度
vue warning 解决
- 之前的打包方式 不会有warning提示
- confirm modal 拆分(暂缓)
- 新增的考虑拆分
- poliyfill
- 单独引用 30k
背景
snowman项目采用pug
渲染 + vue
渲染结合,vue渲染部分js资源未按需加载,页面加载全部的js
一. vue 和 js 改为webpack打包
1.升级babel
1 | "devDependencies": { |
.babelrc 改用preset-env1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": [
"Android >= 4.0",
"ios >= 9",
"ie 9"
]
}
}
]
],
"plugins": [
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-transform-runtime",
["import", {
"libraryName": "lodash",
"libraryDirectory": "",
"camel2DashComponentName": false,
}]
]
}
node入口babel升级
1 | require('@babel/register')({ |
2.引入webpack config
webpack.common.js
webpack.dev.js
webpack.prod.js
entry 打包入口
1 | 'vue-web': './src/vue/web.js', |
3.添加webpack loader
1 | rules: [ |
4.增加可视化打包分析
1 | if (process.env.VISU) { |
使用npm run visu
即可浏览
分析最开始的vue-web.js 为500k
发现是snbchart和moment-timezone 错误引用造成的
查找问题发现
取消错误引用后,减小到350k
5.生成入口列表 js entry
目前只有vue文件是webpack 打包的,snowman是多入口 还有很多js文件也要分别打包处理
遍历src/js 获得webpack 入口列表
1 | const getEntrys = (path) => { |
1 | const entry = { |
至此webpack打包已经能生成各种js文件,但是还不能运行。所以需要结合到gulp流程
6.结合到gulp流程
我们的pug文件热更新需要沿用gulp流程
webpack output至 gulp dist/js 目录
生成的文件注意不要加hash, gulp有统一处理
1 | output: { |
增加webpack gulp命令
1 | import webpack from 'webpack'; |
修改gulpfile
二. 开发模式热更新
采用 webpack-dev-server
启动在5001端口
为了与gulp dev 模式兼容, writeToDist 为true ,同样写到gulp 目录
1 | const merge = require('webpack-merge'); |
output publicPath 设置为0.0.0.0:5001 , 目的是为了热更新的js代码能被正确找到
1 | output: { |
npm script
1 | "dev": "npm run gulp-dev & npm run webpack-dev-server", |
编译界面
三. vue 拆分多入口 实现按需加载
目前都在一块,没有分页面分路由拆分 所有vue页面都有全部的vue-web.js
原因在于只写了一个vue入口 src/vue/web.js 所有的vue组件都在这里引用,其实应该拆开
看注释 能看到大概的组件属于哪一页
计划先按照主要页面 拆分
- 文章页
- 个股页
- 已登录首页
- 未登录首页
- 编辑器页
抽取通用的vue.common.js 包含一些所有页面都公用的配置和组件
1 | const entry = { |
后续考虑 使用dll将通用的node_modules 打包到一块, 加快打包速度,减少发版后用户端的js更新量。
文章页
pug文件中引用
个股页
pug文件中应用
已登录首页
未登录首页
四. 抽离公共vue-common
每个js有很多重复的部分
vue 公共资源抽离vue-common
增加splitChunks
1 | optimization: { |
五. js引用方式改为从vue引入
之前的引用方式
- 文章页
- 个股页
之前为了按需加载写的代码 可以不用单独在pug入口文件中写了,直接在 vue/article.js 或者 vue/stock.js 中 引用即可
改变引用方式后的打包图,可以发现 vue-stock 包含了 snbchart 并且 体积小于 之前stock_new.js的体积
六. 拆分vue路由
看下面这个打包图,vue-common中包含了所有的路由,并且发现有个bussiness.js 的模块挺大的,后来发现这个模块只有个股页用到了,所以应该打包到vue-stock 这个文件里
分析后发现是vue路由没有拆开的原因
vue/router/index
旧代码
1 | let routes; |
看这种写法是想拆分路由的 只是因为入口一样 无法拆分
现在有了不同的入口 就可以拆分了
改为
只有个股页 才引用 stock-info
匿名首页 只引用 home
个人页 只引用 profiles
个人中心 只引用 center
搜索 只引用 search
效果如下
vue-common 252 -> 200
可以看到 router 从 vue-common 中消失了
commponent 大小也减小,拆分到了 需要的js 中 实现按需加载
common 中的 business 也正确的只打包在 vue-stock 中
匿名首页 拆分 vue 路由后
七. lodash按需引用 去除全局lodash
lodash 多个地方重复引用,并且是全量引用
增加lodash tree shake
https://www.azavea.com/blog/2019/03/07/lessons-on-tree-shaking-lodash/
import foo from 'lodash/foo'
以这种方式引用才可以tree shake
从26k降到了6k
使用 babel-plugin-import
但是每次都手动写,不太方便。
分析原理 import { debounce } from 'lodash'
这种引用方式不能按需加载的原因为:
其被babel转换为了1
2var lodash = require('lodash');
var debounce = lodash.debounce;
第一句 var lodash = require('lodash');
就把所有的lodash都引进来了。
所以我们需要一个插件,能正确的babel转换
babel-plugin-import
就是提供了这么一个功能。
能直接转换为
1 | var debounce = require('lodash/debounce'); |
所以最后我们采用 babel-plugin-import
。并增加了lodash的引用路径配置。
采用import { debounce } from 'lodash'
这种写法即可实现按需加载。
并且引用其他库时,也可以配置按需引用了,比如我们的 snb-lib-jsbridge
等。
八. 资源preload
js资源加载时间很靠后
增加link preload