Vue3项目上线打包优化

之前整理过 Vue2项目上线打包优化,在vue3中,使用vite打包,配置稍微改了改。

1 开启gzip压缩

1.1 安装依赖

npm i vite-plugin-compression -D

1.2 vite.config.ts 配置

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节点下新增以下配置

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可配置如下:

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

2 拆分 js & 追加时间戳

vite会将所有的js和css文件都打在一个文件夹下,assets目录,以下配置拆分js和css在不同目录下

vite.config.ts中新增节点build

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 安装依赖

npm install -D unplugin-vue-components unplugin-auto-import

3.2 vite.config.ts 配置

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 页面缓存配置

解决每次发版都需要手动清除缓存的问题

<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请求:

<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 中的变量

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

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@

打包完成,部署时即可使用VITE_API_URL环境变量指定后端URL

6 移除console日志输出

vite中已经集成了去除console和debugger的功能, 但没有terser插件,想要去除console和debugger, 必须先安装terser插件

npm install -D terser

vite.config.ts配置如下

import { defineConfig } from 'vite'
export default defineConfig({
	build: {
		minify: 'terser',
	    terserOptions: {
	      compress: {
	        drop_console: true,
	        drop_debugger: true
	      }
	    }
	}
})

你可能感兴趣的:(Vue,vue3,线上打包,性能优化,vite)