浅析环境变量
为什么需要环境变量
现代前端项目往往有很多环境,比如开发环境、联调环境、测试环境、灰度环境、线上环境,不同环境请求的接口服务是不同的,如果人工维护请求服务的地址,一旦虚心大意忘记切换服务地址,很有可能导致线上出现事故。
能否有一个自动的环境管理方案保证接入的服务无误呢
environment variables使用方式
命令行中手动指定环境变量
pnpm run dev NODE_ENV=development
.env
文件统一配置
1 |
|
1 |
|
常见项目中的environment variables
基于vite构建
存: .env
文件中VITE_变量名=xxx
取:import.meta.env.VITE_变量名
注意,不以VITE_
开始的自定义变量不会被存入环境变量,这是为了避免滥用和误用
利用create-react-app或vue-cli等基于webpack的脚手架构建
存: *.env
文件中REACT_APP_变量名=xxx
取:process.env.REACT_APP_变量名
注意,除了NODE_ENV
,不以REACT_APP_
或VUE_APP_
开始的变量不会被存入环境变量,这是为了避免滥用和误用
基于webpack构建
webpack打包后的结果运行在浏览器上,浏览器上并没有process.env对象,所以需要通过definePlugins自己定义到全局环境
注意:
- webpack的mode并不是指定环境变量,而是指定打包模式
- webpack运行在node环境,打包结果运行在浏览器上,浏览器环境并没有process.env,需要在webpack中处理,使得浏览器可以访问环境变量
1 |
|
深入解析
process.env到底是什么?
process.env
是 Node.js 中的一个全局对象,用于访问当前进程的环境变量。环境变量是在操作系统或运行 Node.js 进程的环境中定义的键值对。
管理process.env——cross-env
无论是webpack还是vite都是运行在nodejs环境上,而node环境下process.env原本是没有NODE_ENV属性的,所以需要通过命令行修改环境变量
不同操作系统的node命令差别比较大,比如想要添加一个NODE_ENV变量:
- Windows写法:
"dev": "set NODE_ENV=test && node test.js"
- Mac写法:
"dev": "export NODE_ENV=test && node test.js"
为了解决在不同操作系统上设置环境变量的差异性,引入第三方库cross-env,它是一个在跨平台环境下设置环境变量的命令行工具和nodejs包,提供了一个统一的方式来设置环境变量,无论在哪个操作系统上运行,都可以正常工作
"dev": "cross-env NODE_ENV=test node test.js"
读取.env文件并注入process.env——dotenv
node不会自动读取.env文件,可以借助第三方库dotenv,自动解析根目录下所有.env的文件
1 |
|
import.meta.env VS process.env
process.env是一个node环境中的全局变量,浏览器端并不能访问
因此虽然运行在node环境下的打包工具可以访问,但是运行在浏览器上的打包结果并不能访问process.env
对于这个问题,webpack给出了解决方案,简单来说就是通过definePlugins将process.env定义到全局
随着ESM的发展,tc39终于在ES2020中新增了import.meta作为模块的元属性,可以在支持ESM的浏览器中获取环境变量,但不能在旧版本浏览器和node环境下使用,vite目前已经支持这种更原生的方式
流程总结
- 通过命令行(一般用cross-env保证跨操作系统的兼容性)赋予代码运行时的NODE_ENV变量
- 通过dovenv读取当前环境下的.env文件
- 把dotenv读取到的数据注入到代码全局环境
实际应用
1 |
|
后续发送请求的时候可以在axios里面设置request interceptor,将config.baseURL作为基本路径,后续再拼接陆路由