本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
本章讲解vite中环境变量的使用,
*.env
环境变量文件大部分前端项目都会使用。一般用于区分开发、生产、测试等环境,在不同环境采取不同配置方案。
推荐阅读
vite.config.ts 之 Env 篇 (九)
.env
默认配置不区分项目环境
# port
VITE_PORT = 8808
# title
VITE_APP_TITLE = Admin JueJin Plus
.env.development
开发环境生效 运行npm run dev 时会加载
.env.development
配置内容到环境变量中,同时会合并.env配置存在相同变量名会覆盖默认配置。 变量命名规则以VITE_开头
# public path
VITE_PUBLIC_PATH = /
# 是否为打包后的文件提供传统浏览器兼容性支持 支持 true 不支持 false
VITE_LEGACY = false
# 跨域代理 可以配置多个
VITE_PROXY = [["/basic-dev","http://localhost:3000"],["/basic-dev-upload","http://localhost:3300/upload"]]
.env.production
生产环境生效
# public path
VITE_PUBLIC_PATH = /
# 是否启用图片压缩
VITE_USE_IMAGEMIN = false
# 是否启用压缩
VITE_USE_COMPRESS = false
# 是否为打包后的文件提供传统浏览器兼容性支持 支持 true 不支持 false
VITE_LEGACY = false
# 使用压缩时是否删除源文件,默认为false
VITE_COMPRESS_DELETE_ORIGIN_FILE = false
# 跨域代理 可以配置多个
VITE_PROXY = [["/basic-prod","http://localhost:3000"],["/basic-prod-upload","http://localhost:3300/upload"]]
- 读取环境变量
vite
中提供了loadEnv
方法可以加载当前环境变量配置
import { loadEnv } from 'vite'
// 加载.env.development
const env = loadEnv('development', process.cwd())
// 加载.env.production
const env = loadEnv('production', process.cwd())
注意获取到的配置值全部都是字符串,通过工具类进行对应类型转换。
// util.ts
declare type Recordable<T = any> = Record<string, T>
// 读取所有要处理的环境变量配置文件
export function wrapperEnv(envConf: Recordable): ViteEnv {
const ret: any = {}
for (const envName of Object.keys(envConf)) {
let realName = envConf[envName].replace(/\\n/g, '\n')
realName = realName === 'true' ? true : realName === 'false' ? false : realName
if (envName === 'VITE_PORT') {
realName = Number(realName)
}
if (envName === 'VITE_PROXY' && realName) {
try {
realName = JSON.parse(realName.replace(/'/g, '"'))
} catch (error) {
realName = ''
}
}
ret[envName] = realName
if (typeof realName === 'string') {
process.env[envName] = realName
} else if (typeof realName === 'object') {
process.env[envName] = JSON.stringify(realName)
}
}
return ret
}
返回值
ViteEnv
定义在env.d.ts
中
// env.d.ts
/// <reference types="vite/client" />
interface ViteEnv {
readonly VITE_APP_TITLE: string
readonly VITE_PUBLIC_PATH: string
readonly VITE_PORT: number
readonly VITE_PROXY: [string, string][]
readonly VITE_DROP_CONSOLE: boolean
readonly VITE_USE_IMAGEMIN: boolean
readonly VITE_USE_COMPRESS: boolean
readonly VITE_COMPRESS_DELETE_ORIGIN_FILE: boolean
readonly VITE_USE_MOCK: boolean
readonly VITE_LEGACY: boolean
}
declare module '*.vue' {
import type { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
- 配置
import { UserConfig, ConfigEnv, loadEnv } from 'vite'
import { createVitePlugins, createViteBuild } from './config'
import { wrapperEnv } from './config/utils'
// https://vitejs.dev/config/
export default ({ command, mode }: ConfigEnv): UserConfig => {
const isBuild = command === 'build'
const env = loadEnv(mode, process.cwd())
const viteEnv = wrapperEnv(env)
const { VITE_PUBLIC_PATH } = viteEnv
return {
base: VITE_PUBLIC_PATH,
plugins: createVitePlugins(viteEnv, isBuild),
build: createViteBuild(isBuild),
}
}
- 使用
import vue from '@vitejs/plugin-vue'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
import legacy from '@vitejs/plugin-legacy'
import OptimizationPersist from 'vite-plugin-optimize-persist'
import PkgConfig from 'vite-plugin-package-config'
import { configCompressPlugin } from './compress'
import { configImageminPlugin } from './imagemin'
import { configStyleImportPlugin } from './style'
import {
configAutoImportPlugin,
configVueComponentsPlugin,
configVueIconsPlugin,
configVuePurgeIconsPlugin,
} from './unplugin'
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
const { VITE_USE_IMAGEMIN, VITE_USE_COMPRESS, VITE_COMPRESS_DELETE_ORIGIN_FILE, VITE_LEGACY } =
viteEnv
const plugins = [vue(), vueSetupExtend(), PkgConfig(), OptimizationPersist()]
// 是否为打包后的文件提供传统浏览器兼容性支持
VITE_LEGACY &&
plugins.push(
legacy({
targets: ['ie >= 11'],
additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
})
)
if (isBuild) {
// vite-plugin-compress
VITE_USE_COMPRESS && plugins.push(configCompressPlugin(VITE_COMPRESS_DELETE_ORIGIN_FILE))
// vite-plugin-imagemin
VITE_USE_IMAGEMIN && plugins.push(configImageminPlugin())
}
// unplugin-auto-import
plugins.push(configAutoImportPlugin())
// unplugin-vue-components
plugins.push(configVueComponentsPlugin())
// vite-plugin-style-import
plugins.push(configStyleImportPlugin())
// unplugin-icons
plugins.push(configVueIconsPlugin())
// vite-plugin-purge-icons
plugins.push(configVuePurgeIconsPlugin())
return plugins
}
- 开发服务器配置
开发服务器配置没有添加到vite配置中,如果想要使用自行配置。完整代码已经提交到Gitee中,想要学习的小伙伴请自行下载👍
import { ProxyOptions } from 'vite'
type ProxyTargetList = Record<string, ProxyOptions>
const httpsRE = /^https:\/\//
export function createViteServer(viteEnv: ViteEnv) {
const { VITE_PORT, VITE_PROXY } = viteEnv
const proxy: ProxyTargetList = {}
for (const [prefix, target] of VITE_PROXY) {
const isHttps = httpsRE.test(target)
// https://github.com/http-party/node-http-proxy#options
proxy[prefix] = {
target: target,
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
// https is require secure=false
...(isHttps ? { secure: false } : {}),
}
}
return {
hmr: { overlay: false }, // 禁用或配置 HMR 连接 设置 server.hmr.overlay 为 false 可以禁用服务器错误遮罩层
cors: true, // 类型: boolean | CorsOptions 为开发服务器配置 CORS。默认启用并允许任何源
open: true, // 服务启动时是否自动打开浏览器
port: VITE_PORT, // 类型: number 指定服务器端口
headers: {
'Cache-Control': 'no-store',
},
https: false, // 是否开启 https
host: '0.0.0.0', // IP配置,支持从IP启动
// 本地跨域代理
proxy,
}
}
继续学习
废话只说一句:码字不易求个👍,收藏 === 学会,快行动起来吧!🙇🙇🙇。