Vue2-Elm项目升级
# Vue2-Elm项目升级
# 准备工作
项目源码:vue2-elm:基于 vue2 + vuex 构建一个具有 45 个页面的大型单页面应用 (opens new window)
安装依赖和运行
npm install
npm run dev
2
# 构建源码分析
构建核心源码
- build
- build.js 打包执行文件
- webpack.base.conf.js 项目配置公共文件
- webpack.dev.conf.js 项目启动配置文件
- webpack.dll.conf.js dll插件抽离第三方库配置文件
- config
- 开发和线上环境的配置文件
构建源码分析:https://mzc28y.yuque.com/mzc28y/pp2zs1/uq9g9i (opens new window)
# 项目需求分析
第一阶段:vue升级改造,对项目中的vue全家桶插件进行升级
第二阶段:webpack打包改造,对项目中现有的打包进行改造升级
第三阶段:项目打包构建优化,对项目的构建速度和打包体积进行优化
# vue-cli2构建分析
开发模式构建源码,脚本如下
"dev":"cross-env NODE_ENV=online node build/dev-server.js"
执行流程分析
# express的核心概念——中间件
路由中间件
异常中间件
异常中间件全局只包含一个
异常中间件可以传递给普通中间件
异常中间件需要放在所有中间件的最后
异常中间件只能捕获回调函数中的异常
全局异常捕获中间件和全局Promise异常捕获中间件
# 核心中间件 webpack-dev-middleware
作用:将磁盘的数据存储到内存中
shared方法很重要
使用memory-fs将磁盘数据转存到内存中
# 核心中间件 webpack-hot-middleware
作用:实现热部署
复杂点:
1.客户端和服务端同时配合实现 HotModuleReplacementPlugin
2.客户端和服务端双向通信
# 第一阶段:Vue升级改造
# Vue3和Vue2对比
# vue2的缺陷
vue2代码复用困难,vue2的代码复用方式有Mixin,但容易出现命名冲突,且无法解决业务逻辑复用
vue2对于TypeScript的支持不足
vue2内部实现过度依赖this,导致无法进行treeshaking
# vue3的优势
- vue3支持vue2的大多数特性,能够实现对vue2的向下兼容。
- vue3对比vue2具有明显的性能提升
- 打包大小减少41%。
- 初次渲染快55%,更新快133%。
- 内存使用减少54%。
- vue3具有的composition API实现逻辑模块化和重用
- vue3.2通过setup语法糖进一步简化开发,可以编写更加优雅的代码0vue3脚手架默认实现对typescript的支持
- 增加了很多新特性,如: Fragmet、Teleport、Suspense
# vue全家桶依赖升级
"vue":"^2.1.0",
"vue-router":"^2.1.1",
"vuex":"^2.0.0"
2
3
"vue":"^3.0.0",
"vue-router":"^4.0.0-0",
"vuex":"^4.0.0-0"
2
3
"devDependencies":{
"@vue/cli-service":"5.0.0-beta.2",
"@vue/compiler-sfc": "^3.2.6",
"sass": "^1.49.7",
"sass-loader": "^12.4.0",
"webpack":"^5.50.0",
"webpack-cli":"^4.9.2"
}
2
3
4
5
6
7
8
vue.config.js中使用configureWebpack可以对webpack进行配置。通过alias可以把src路径映射到指定的路径。
# vuex和vue-router语法升级
vuex从实例化vuex.store对象变为createStore,实现了解构,能够减少打包大小。
vue-router从实例化Router对象变成了{createRouter,createWebHistory}
vue从实例化Vue对象变成了createApp方法
# vuex移植
更新vuex配置:修改项目中vuex的配置
# 移植首页
# vue3语法升级
setup()方法
ref()、reactive()、computed()
useStore、useRouter、useRoute
setup语法糖,在script标签中加入setup,不需要在export default了,直接把setup()方法中的写在script中即可
# 第二阶段:Webpack打包改造
# Webpack5新特性
构建结果不同
不管多么简单的代码,webpack4构建的代码量都挺多且复杂
对于简单的代码,webpack5构建的代码也会非常简单,构建思路上与4有一定的区别
缓存机制不同
- webpack5 比 webpack4 的文件压缩策略更优,分割文件后的 vendor 体积缩小。
- webpack5 缓存构建性优优于 webpack4。
- webpack5缓存的功能显著优于webpack4。
# 低版本的webpack可以使用hard-source-webpack-plugin提升缓存性能
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin)
module.exports = {
plugins:[
new HardSourceWebpackPlugin()
]
}
2
3
4
5
6
# URIs解析
# TreeShaking和Sid
# 模块联邦
微前端
# PackageExports
# 第三阶段:项目打包构建优化
- 查找并诊断性能瓶颈
- 构建速度分析:影响构建性能和开发效率
- 构建体积分析:影响页面访问性能
- 构建性能优化常用方法
- 通过多进程加快构建速度
- 通过分包减小构建目标容量
- 减少构建目标加快构建速度
# 构建速度分析 speed-measure-webpack-plugin
在vue.config.js中使用
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin({
disable: !(process.env.MEASURE === 'true'), //是否启动
outputFormat: 'humanVerbose' //输出格式
})
module.exports = {
configureWebpack:smp.wrap({})
}
2
3
4
5
6
7
8
# 构建体积分析 webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
plugins:[
new BundleAnalyzerPlugin()
]
}
2
3
4
5
6
# 多进程/多实例构建(资源并行解析)
thread-loader(官方推荐)
每一个worker都是一个独立的进程,开辟需要耗费600ms左右的时间。同时会限制跨进程交换。
仅在耗时的操作中使用此loader!
module.exports = {
configureWebpack:{
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'thread-loader',
options: {
worker: 2
}
}]
}]
},
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
上述配置也有简化配置方法
module.exports = {
configureWebpack:{
parallel:true
}
}
2
3
4
5
# webpack5分包策略
# 分包DllPlugin&DllReferencePlugin
分包的具体步骤:
- 分包:定义webpack.dll.config,js,使用DllPlugin配置分包,定义scripts命令,执行命令,完成分包。
- 排除分包: 在vue.config.js中,使用DIIReferencePlugin引用manifest文件排除分包
- 拷贝dll:将dIl拷贝至项目目录下
- 引用dll:使用add-asset-html-webpack-plugin引用dll分包文件
# 利用缓存提升二次构建速度
vue.config.js的配置如下
const module.exports = {
configureWebpack:{
cache:{
type: 'filesystem',
cacheDirectory: path.reolve(__dirname,'./node_modules/.cache_temp')
}
}
}
2
3
4
5
6
7
8
# 图片压缩 image-webpack-loader
vue.config.js的配置如下
const module.exports = {
configureWebpack:{
module:{
rules: [{
test:/\.(gif|png|jpe?g|svg|webp)$/i,
use: [{
loader:'image-webpack-loader',
options:{
mozjpeg:{
progressive:true,
quality:65
}
}
}]
}]
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 删除css未使用内容purgecss-webpack-plugin
vue.config.js的配置如下
const PurgeCssWebpackPlugin = require('purgecss-webpack-plugin')
const module.exports = {
configureWebpack:{
plugins:[
new PurgeCssWebpackPlugin({
paths:glob.sync(`${PATHS/**/*}`,{nodir:true}),
})
]
}
}
2
3
4
5
6
7
8
9
10