之前整理过 Vue2项目上线打包优化,在vue3中,使用vite打包,配置稍微改了改。
1 开启gzip压缩
1.1 安装依赖
bash
npm i vite-plugin-compression -D
1.2 vite.config.ts 配置
typescript
import viteCompression from 'vite-plugin-compression'
export default defineConfig({
plugins: [
// ...
viteCompression({
verbose: true, // 默认即可
disable: false, //开启压缩(不禁用),默认即可
deleteOriginFile: false, //删除源文件
threshold: 10240, //压缩前最小文件大小
algorithm: 'gzip', //压缩算法
ext: '.gz' //文件类型
})
],
});
1.3 nginx 配置
在server节点下新增以下配置
nginx
server {
listen 80;
server_name localhost;
# 追加如下配置
gzip on;
gzip_static on;
gzip_buffers 4 16k;
gzip_min_length 1k;
gzip_comp_level 9;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]";
}
如果是打包成docker镜像,Dockerfile可配置如下:
dockerfileFROM nginx:1.25.2-alpine-slim COPY dist /usr/share/nginx/html/ # 开启gzip压缩配置 RUN sed -i '/server_name localhost;/a \ gzip on;\n\ gzip_static on;\n\ gzip_buffers 4 16k;\n\ gzip_min_length 1k;\n\ gzip_comp_level 9;\n\ gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;\n\ gzip_vary on;\n\ gzip_disable "MSIE [1-6]";' /etc/nginx/conf.d/default.conf # 指定于外界交互的端口 EXPOSE 80
2 拆分 js & 追加时间戳
vite会将所有的js和css文件都打在一个文件夹下,assets目录,以下配置拆分js和css在不同目录下
vite.config.ts中新增节点build
typescript
let timeStamp = new Date().getTime()
export default defineConfig({
//...
build: {
chunkSizeWarningLimit: 1500,
rollupOptions: {
output: {
// 最小化拆分包
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString()
}
},
// 用于从入口点创建的块的打包输出格式[name]表示文件名,[hash]表示该文件内容hash值
entryFileNames: `js/[name].[hash]${timeStamp}.js`,
// 用于命名代码拆分时创建的共享块的输出命名
// chunkFileNames: `js/[name].[hash]${timeStamp}.js`,
// 用于输出静态资源的命名,[ext]表示文件扩展名
assetFileNames: `[ext]/[name].[hash]${timeStamp}.[ext]`,
// 拆分js到模块文件夹
chunkFileNames: chunkInfo => {
const facadeModuleId = chunkInfo.facadeModuleId ? chunkInfo.facadeModuleId.split('/') : []
const fileName = facadeModuleId[facadeModuleId.length - 2] || '[name]'
return `js/${fileName}/[name].[hash]${timeStamp}.js`
}
}
}
}
})
3 ElementPlus按需加载
3.1 安装依赖
bash
npm install -D unplugin-vue-components unplugin-auto-import
3.2 vite.config.ts 配置
typescript
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()]
}),
Components({
resolvers: [ElementPlusResolver()]
})
]
})
3.3 main.ts
移除main.ts
中的ElementPlus
相关引入,包括css
css移除可能会导致 ElLoading、ElMessage 等样式失效,main.ts 中可以不移除
4 index.html 优化
4.1 页面缓存配置
解决每次发版都需要手动清除缓存的问题
html
<meta http-equiv="pragram" content="no-cache">
<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="expires" content="0">
追加时间戳参考 # 2 拆分 js & 追加时间戳 章节
4.2 自动跳转https请求
在前后端配置http自动转https后,如果前端请求的后端接口还是http,则会报跨域
在index.html的head标签里面加入以下代码即可实现自动跳转https请求:
html
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
参考:https://blog.csdn.net/weixin_39809852/article/details/106575230
会强制跳转 https,如果是容器部署,可以采用变量的方式配置请求 url
5 变量暴露到容器
https://www.5axxw.com/questions/content/turw8a、https://www.cnblogs.com/ingstyle/p/14329474.html
如部署时动态配置后端的api baseUrl,单个变量可做如下配置
5.1 request.ts
axios封装时,baseURL改为动态获取,VITE_API_URL
为环境配置文件 .env 中的变量
typescript
const baseUrl = () => {
let querySelector = document.querySelector('html');
if (querySelector) {
const { promiseBaseUrl } = querySelector.dataset
if (promiseBaseUrl && promiseBaseUrl.indexOf('http') === 0) {
return `${promiseBaseUrl}`
}
}
return import.meta.env.VITE_API_URL as any
}
// axios实例
const service = axios.create({
baseURL: baseUrl(),
timeout: 60000,
headers: { 'Content-Type': 'application/json;charset=UTF-8' }
})
5.2 Dockerfile
Dockerfile 里将变量配置到 index.html
dockerfile
FROM nginx:1.25.2-alpine-slim
COPY dist /usr/share/nginx/html/
# 开启gzip压缩配置
RUN sed -i '/server_name localhost;/a \
gzip on;\n\
gzip_static on;\n\
gzip_buffers 4 16k;\n\
gzip_min_length 1k;\n\
gzip_comp_level 9;\n\
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;\n\
gzip_vary on;\n\
gzip_disable "MSIE [1-6]";' /etc/nginx/conf.d/default.conf
# 指定于外界交互的端口
EXPOSE 80
CMD ["/bin/sh", "-c", "sed -i \"s@<html@<html data-promise-base-url=\"$VITE_API_URL\"@\" /usr/share/nginx/html/index.html; nginx -g \"daemon off;\""]
打包完成,部署时即可使用VITE_API_URL
环境变量指定后端URL
6 移除console日志输出
vite中已经集成了去除console和debugger的功能, 但没有terser插件,想要去除console和debugger, 必须先安装terser插件
npm install -D terser
vite.config.ts
配置如下
typescript
import { defineConfig } from 'vite'
export default defineConfig({
build: {
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
}
}
})