一.项目2 vue2-elm项目工程化升级
这个项目是5年前 vue-cli2创建项目 带build目录 比较老
升级流程图
1.准备工作
vue-cli2构建源码分析
//1.cross-env NODE_ENV=online表示 通过cross-env这个库设置环境变量NODE_ENV等于online
//2.获取环境变量可以通过 process.env.NODE_ENV
"scripts": {
"dev": "cross-env NODE_ENV=online node build/dev-server.js",
"local": "cross-env NODE_ENV=local node build/dev-server.js",
"build": "node build/build.js"
},
//1.http-proxy-middleware express中启动代理服务的中间件 解决跨域问题
//2.webpack-dev-middleware //webpack-dev-server底层实现的中间件
vue-cli开发模式下 都会采用express启动静态资源服务器
2.webpack-dev-middleware 详解
3.webpack-hot-middleware 详解
4.express创建
//1.创建服务
const express = require("express")
const app = express()
//中间件 处理请求业务逻辑
//前置中间件
//---------中间件第一个参数为回调函数时,则针对所有请求都有效
app.use(function(req,res,next){
console.log('middleware')
next()
});
//----------路由中间件,第一个参数为匹配路由,第二个参数为回调函数
app.use('/test',function(req,res,next){
res.send('test')
throw new Error('error message')
next()
})
//获取静态资源
app.use('/static',express.static('./static'))
//------异常中间件 回调函数包含了4个参数
//! 1.异常中间件全局只包含一个 (多个时只会执行第一个)
//! 2.异常中间件可以传递给普通中间件
//! 3.异常中间件需要放在所有中间件的最后 (可以捕获所有异常)
//! 4.异常中间件只能捕获回调函数中的异常,无法捕获promise的异常 此时需要全局的promise异常捕获<unhandledRejection>
app.use(function(err,req,res,next){
console.error('err!',err.message)
})
//2.拦截路由
app.get('/',function(req,res,next){
console.log('handle /')
res.send('<html><body><div style="color:red">111</div></body></html>')
next()
});
//---------后置中间件
app.use(function(req,res,next){
console.log('after niddlewere')
})
//3.启动服务
const port = 9090
app.listen(port,function(){
console.log('服务启动成功端口号为:'+port)
})
//! 全局的异常捕获
process.on('uncaughtException',function(err){
console.error('uncaughtException',err.message)
})
//! 全局的promise异常捕获
process.on('unhandledRejection',function(err){
console.error('unhandledRejection',err.message)
})
二.vue的升级改造
graph TD
vue2-elm-master项目工程化升级 --> 第一阶段:vue升级改造升级vue3
vue2-elm-master项目工程化升级 --> 第二阶段:webpack打包改造
vue2-elm-master项目工程化升级 --> 第三阶段:项目打包构建优化
介绍:为什么要升级到vue3
- vue2对ts支持不太友好
- vue2过度依赖this,导致无法进行treeshaking
vue3的优势
第一阶段:项目升级vue3
(1)github上下载vue2-elm-master项目,并初始化
(2)vue全家桶依赖升级
//原来版本
"vue": "^2.1.0",
"vue-router": "^2.1.1",
"vuex": "^2.0.0"
//升级后版本
"vue": "^3.0.0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
//1.删除掉原来devDependencies里面所有的依赖
//2.配置vue3需要的依赖
"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"
},
//3.在package.json中 修改
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-cli-service build"
},
遇到的编译上的问题:
(3)vuex和vue-router语法升级
//代码
//在store/index.js中
import { createStore } from "vuex";
export default createStore({})
//使用方式
import {useStore} from 'vuex'
let store = useStore();
store.state.latitude
store.commit('xx'.data)
//在入口main.js中
import { createApp } from "vue";
import App from "./App.vue";
import store from "./store/";
createApp(App).use(store).mount("#app");
(4) 接口升级(地址替换成线上)
(5)图片地址的修改 换成线上
(6)样式的调整
(7)移植首页
第三阶段:项目打包构建优化
1.构建性能优化方法
(1)构建速度分析 speed-measure-webpack-plugin
//1.安装 npm i -D speed-measure-webpack-plugin
//2.在vue.config.js中
const path = require("path");
const SpeedMeasureWebpackPlugin = require("speed-measure-webpack-plugin");
//看下环境变量是否被写入
console.log("process.env.MEASURE", process.env.MEASURE);
const smp = new SpeedMeasureWebpackPlugin({
/*
3.使用环境变量的方式 控制是否要开启构建速度分析
(1)安装 npm i cross-env -D
(2)在package.json中
"scripts": {
"serve": "cross-env MEASURE=true vue-cli-service serve",//MEASURE=true的时候就开启
"build": "vue-cli-service build"
},
*/
disable: !(process.env.MEASURE === "true"), //是否开启构建速度分析 默认false开启的 注意是string格式所以要这样写
outputFormat: "humanVerbose", //输出的日志格式
});
//!使用 smp.wrap()包裹配置
module.exports = {
configureWebpack: smp.wrap({
resolve: {
alias: {
src: path.resolve(__dirname, "./src"),
assets: path.resolve(__dirname, "./src/assets"),
components: path.resolve(__dirname, "./src/components"),
},
},
}),
};
(2)构建体积分析
webpack-bundle-analyzer
会自动弹出一个页面介绍打包详情
//1.安装 npm i webpack-bundle-analyzer -D
//2.在配置文件中
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
//关闭弹出构建体积分析 disabled
//使用环境变量的方式来判断是否开启体积分析
analyzerMode: process.env.MEASURE === "true" ? "server" : "disabled",
})
]
}
2.构建速度的优化
(1)使用thread-laoder多进程构建
parallel vue中是否开启多进程
module.exports = {
//parallel此属性为vue内部封装的thread-loader 为true表示开启多进程
//只能用于生产模式即 npm run build
parallel: true,
configureWebpack: smp.wrap({
}),
};
//require("os").cpus() 查看当前电脑cpu
(2)使用dll做分包
注意要使用copy-webpack-plugin将生成的dll文件拷贝到dist目录下
//建webpack.dll.conf.js
const path = require("path");
const webpack = require("webpack");
const dllPath = "../dll";
module.exports = {
mode: "production",
entry: {
vue: ["vue", "vue-router", "vuex"],
},
output: {
path: path.resolve(__dirname, dllPath),
filename: "[name].dll.js",
library: "[name]_[hash]",
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, dllPath, "[name]-manifest.json"),
name: "[name]_[hash]",
context: process.cwd(), //为当前根目录
}),
],
};
(3)使用cache缓存
(4)图片的压缩 image-webpack-loader
(5)删除css未使用的内容 purgecss-webpack-plugin
第二阶段 加餐webpack4和webpack5比较
1.webpack5 treeshaking的能力更强
引入但没有使用的模块 webpack5会被忽略掉
同样是打包console.log 结果对比如下
2.cache缓存上的区别
//配置不同
//webpack4中
只能设置 cache:true
//webpack5中 可以设置
cache:{
type:'filesystem'
cacheDirectory:path.resolve(__dirname,'./node_modules/.cache_temp')
}
3.hard-source-webpack-plugin 缓存
支持3版本及以下版本进行缓存,并且可以让4版本进行向webpack5一样配置缓存目录
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
plugins:[
new HardSourceWebpackPlugin({
cacheDirectory:path.resolve(__dirname,'./node_modules/.cache_temp')
})
]
4.文件图片打包的不同
//webpack4
必须要使用url-loader 和 file-loader
//webpack5中可以使用 asset 不用安装loader
module:{
rules:[
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: "asset", //启动webpack5内置的moduleAsset属性(webpack5版本以上支持)
parser: {
dataUrlCondition: {
maxSize: 8 * 1024, //表示小于8kb的图片转成base64打包到bundle.js中 否则直接输出到目录
},
},
generator: {
//在images目录中保存 name名称 hash名称(防止重名) ext后缀名 [hash:6]表示hash值保存6位
filename: "images/[name].[hash:6][ext]",
},
}
]
}
5.URIs不同
注意:打包https时需要配置以下
6. Treeshaking和sideEffects(副作用)
- webpack4无法对export default 进行Treeshaking而webpack5可以
- webpack5使用了sideEffects可以精确的控制哪些文件没有副作用,从而不打包
7.模块联邦(微前端的实现方式)
//引入
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin')
- 在
子应用中 - 在
主应用中
8.packageExports
在webpack5+支持 一个lib包可以同时支持node和浏览器
//在package.json中配置
"exports":{
//require引入lib包时拿到a.js的东西
//可以使用node的内置api fs/path/os/child——process
"require":"./a.js",
//import引入lib包时拿到b.js的东西
//可以使用浏览器内置api document/window/dom/bom
"import":"./b.js",
}