1. 原理

Vite是用dotenv这个第三方库去实现的

dotenv这个第三方库会自动读取.env文件,并解析这个文件中对应的环境变量,并将其注入到process.env下面(Node的进程信息)。

但是vite考虑到和其他配置的一些冲突问题,他不会直接注入到process对象下。其中涉及到vite.config.js一些配置:

  • root
  • envDir: 配置加载 .env 文件的目录

2. 在服务端(Node端)访问环境变量

此时我们vite给我们提供了loadEnv这个方法。

.env:所有环境都要用到的环境变量

.env.development: 开发环境下用到的环境变量

.env.production: 生产环境下用到的环境变量

yarn dev == yarn dev --mode development
yarn build == yarn build --mode production

执行不同的命令后,mode会被命名不同的值,代表不同的开发环境,传到vite.config.js

export default defineConfig(({ command, mode }) => {
  console.log("command", command);
  console.log("mode", mode);
  const env = loadEnv(mode, process.cwd,"");    // process.cwd方法:返回当前Node工作目录的地址
  
  return envResolver[command]();
})

当我们调用loadEnv时,他会做如下几件事:

  1. 直接找到.env文件,不解释,并解析其中的环境变量,放到一个对象里
  2. 将传进来的mode参数进行拼接,用.env+mode的方式拼接完成后,在第二个参数提供的目录地址去读取配置文件并解析,再放入一个对象
  3. 将上面两个对象对比合并(Object,assign)后,返回这个新的环境变量对象
  4. 其中loadEnv的第三个参数代表的是只加载第三个参数为前缀的环境变量,不传的话默认为VITE_,若为""(空字符串),代表返回所有的环境参数。

3. 在客户端访问环境变量

如果客户端在开发文件中要用到环境变量,可以使用import.meta.env

其中,vite会对loadEnv()返回的环境变量做一个拦截,防止我们把隐私变量放到了环境变量而进入客户端,如果你的环境变量不是以VITE_开头,就不会被注入到客户端import.meta.env去。

VITE_能不能改动呢?当然可以了,那就要用vite.config.js里的envPrefix参数了。

export default defineConfig({
  optimizeDeps: {
    exclude: [],   // 指定中的数组不进行依赖预构建
  },
  envPrefix: "DEV_"  // 配置那些前缀的环境变量才能够成为客户端环境变量(import.meta.env),默认为VITE_
})

如上所示,就把这个拦截前缀改为了DEV_