vite2 + vu3开发中发现process.env
报undifined,发现在vite中的环境变量取值是与webpack不一样的
新建两个不同的env文件,vite运行时会根据.env.[mode]
加载对应文件
// 文件名 .env.development
NODE_ENV=development
VITE_APP_BASE_API=devapi
// 文件名 .env.production
NODE_ENV=production
VITE_APP_BASE_API=proapi
一、取值
//package.json
"scripts": {
"dev": "cross-env vite --mode development",
"pro": "cross-env vite --mode production"
},
import.meta.env.VITE_BASE_URL
// npm run dev 值 为devapi
// npm run pro值 为proapi
注意事项
除NODE_ENV
外,变量必须以 VITE_
开头,不然无法加载
import.meta.env.中的值 不能在vite.config.js中取 推测是还未加载
二、加载过程
vite中通过loadEnv
方法实现加载文件,也可手动调用方法自定义加载
import { loadEnv } from 'vite'
//vite.config.js
export default (() => {
loadEnv(
mode, // 环境
process.cwd() // 从根路径(项目启动文件路径)加载
)
return defineConfig({
...
})
})
附loadEnv
源码注释引用文章
// 从传参的root目录下获取
// 按顺序 .env.${mode}.local、.env.${mode}、.env.local、.env这四个环境文件
// 输出文件内配置的对象
function loadEnv(mode, root, prefix = 'VITE_') {
if (mode === 'local') {
// ↓如果第一个参数传入'local',就报错:
// ↓"local "不能用作模式名称,因为它与``.env文件的.local后缀冲突。
throw new Error(`"local" cannot be used as a mode name because it conflicts with ` +
`the .local postfix for .env files.`);
}
// ↓待输出的环境变量对象
const env = {};
// ↓要读取的四个文件名称的字符串数组
const envFiles = [
/** mode local file */ `.env.${mode}.local`,
/** mode file */ `.env.${mode}`,
/** local file */ `.env.local`,
/** default file */ `.env`
];
// 检查是否有实际的以VITE_*开头的环境变量。
// 这些通常是Node内联提供的env对象,并应优先考虑。
for (const key in process.env) {
if (key.startsWith(prefix) && env[key] === undefined) {
env[key] = process.env[key];
}
}
for (const file of envFiles) {
// ↓检查根目录下是否有指定配置文件
const path = lookupFile(root, [file], true);
if (path) {
// ↓以换行为单位输出文件中KEY=VAL格式的到结果对象中
const parsed = main$2.parse(fs__default.readFileSync(path), {
debug: !!process.env.DEBUG || undefined
});
// ↓让环境变量互相使用,这个方法我没仔细研究。不是很懂
main$1({
parsed,
// ↓防止process.env修改
ignoreProcessEnv: true
});
// 只输出以prefix开头的key
for (const [key, value] of Object.entries(parsed)) {
// ↓只有这个key在前面没有加载过才赋值
if (key.startsWith(prefix) && env[key] === undefined) {
env[key] = value;
}
else if (key === 'NODE_ENV') {
// 在.env文件中覆盖NODE_ENV。
process.env.VITE_USER_NODE_ENV = value;
}
}
}
}
return env;
}