区分开发or生产环境

​ 在正常开发流程中,我们会有生产环境、测试环境、预生产环境等,每个公司有着自己不同的实践。但他们都逃不开一个测试环境和生产环境,所以说在vite我们怎么区分生产环境和测试环境,这点就尤为重要。在vite中我们区分环境也很简单,我们在vite.config.js文件可以将defineConfig函数中传入一个函数,他会接收一个参数,这个参数是一个对象,该对象下面有一个command参数是供我们区分生产和开发环境,他有两个值:serve或者build。

1
2
3
4
5
6
7
8
9
import { defineConfig } from 'vite'
export default defineConfig((config) => {
console.log(config.command); // serve
return {
optimizeDeps: {
exclude: []
}
}
})

​ 当我们执行pnpm run dev的时候,这里的command得到的就是serve,当我们运行pnpm run build的时候,这个位置就拿到的是build。

既然我们写的vite.config.js是给node运行的,众所周知node端遵循的模块化方案是common js,那么为什么node端能认识我们的ES Module模块化方案呢? 原因也很简单,node端读取文件的时候,他拿到的是字符串,他将我们的ES Module替换为common js就可以了。

环境变量

​ 当我们确定项目跑在那个环境下后,自然而然需要给他注入对应的环境变量。环境变量就是我们在不同的环境下能拿到不同的结果。最典型的例子就是我们的请求前缀,测试环境和生产环境的请求地址是不一样的,如果我们每次都尝试自己去修改,自然也没问题,但是如果哪天我们忘记修改,那么上线后会产生极大的问题。所以我们就考虑借助环境变量,在不同的环境下去读取不同的环境变量。而vite是内置了dotenv这个库。他会自动去读取.env文件,然后帮我们注入到process对象下。但是Vite默认是不加载.env文件的。也就是说,虽然他内置了,但是他默认不会用,我给你提供这个功能,你用不用看你自己。当我们明确需要时,vite也给我们导出了一个函数loadEnv来加载指定.env文件。通常情况下.env文件我们会放一些所有环境通用的环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { loadEnv } from 'vite'
import { defineConfig } from 'vite'
import viteBaseConfig from './vite.base.config.js'
import viteDevConfig from './vite.dev.config'
import viteProdConfig from './vite.prod.config'
const envResolve = {
build: () => Object.assign({}, viteBaseConfig, viteProdConfig),
serve: () => {
console.log('环境: ', '测试环境');
return Object.assign({}, viteBaseConfig, viteDevConfig)
}
}

export default defineConfig(({ mode, command }) => {
console.log(mode); //mode变量我们在下面会讲到
const env = loadEnv(mode, process.cwd(), '');
console.log(env.APP);

return envResolve[command]()
})

loadEnv函数

​ loadEnv是vite给我们导出用于加载env文件函数,它的语法也很简单,三个参数,第一个mode,第二个是加载那个目录的env文件,第二个参数我们通常用process.cwd(),会返回node进程运行的目录。第三个是空字符串,来加载所有环境变量,而不管是否有 VITE_ 前缀。mode参数的来源就是我们在命令行运行项目的时候传递的参数,如下:

1
2
3
4
5
pnpm run dev #vite最终会补全成下面这种格式
pnpm run dev --mode development

pnpm run build #vite最终会补全成下面这种格式
pnpm run build --mode production

​ 他们的表现是一致的,当我们不给参数的时候,vite默认会帮我们补全mode参数。然后这个mode参数会拼接到路径后面,比如说我们默认加载的是env文件,他会帮我们再去加载对应的环境变量.env.[mode](.env.development)文件。

​ 那么我们如何在项目开发的时候拿到环境变量呢?这都是在服务端拿环境变量的方式。vite给我们提供了import.meta.env,通过它我们可以在任何一个配置文件拿到当前的环境变量。但是vite在将变量注入给他的时候会做一层拦截,直接注入以VITE_开头的变量,当然这个也是可以配置的。

1
2
3
4
5
6
// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
envPrefix: "DW_" //这样vite就只会注入以DW_开头的变量到import.meta.env
})