序
当我们完成本地开发并准备将项目部署到测试或生产环境时,我们需要处理不同环境下的参数配置问题。在各个环境中,某些配置通常会有所不同,例如服务端 API 接口地址。那么,我们应该如何配置环境变量?这涉及哪些步骤?不同的框架(如Next.js/Ice.js)之间有何差异?常见的配置项又具有什么含义?本文将对这些问题进行详细解答。
配置思路
- 第一步,创建不同环境的配置文件;
- 第二步,在配置文件中配置不同环境的变量;
- 第三步,配置启动命令,让不同环境对应配置文件;
- 第四步,在代码中访问对应环境的变量。
配置文件
每个环境新增一个配置文件,以.env.[env]命名
- 开发:
.env.development
- 线上:
.env.production
说明: .env.local
:本地配置文件,不上传。适合存储一些敏感信息如密码等,.gitignore中要记得配置该文件。 该配置中的优先级高于其他配置文件,会覆盖。
环境变量
在各环境配置文件中,配置环境变量,格式:VARIABLE=VALUE
,无需引号。 不同框架中,对环境变量有命名要求,譬如:
- next.js:需要配置NEXT_PUBLIC_开头
- ice.js:需要配置ICE_开头
注意点:
- 如果不是以框架要求命名开头,则访问不到
- process.env.[var]访问
启动命令
最后,需要配置启动命令。 启动命令在不同框架中定义不一样,有些是预置环境的,有些是通过命令指定环境的,需要查阅具体文档。
webpack中
用--mode [env]
来启动
json
"scripts": {
"dev": "webpack --mode development"
}
nextjs中
不同命令对应不同环境
json
"scripts": {
"dev": "next dev", // dev脚本对应.env.development配置
"build": "next build", // build脚本对应.env.production配置
}
如果多余两个环境变量,可以配合dotenv来匹配配置环境
json
"scripts": {
"dev": "dotenv -e .env.development next dev",
"build:test": "dotenv -e .env.test next build",
"build:prod": "dotenv -e .env.production next build",
}
icejs中
默认也提供了.env.development和.env.production配置文件;但多环境下,比nextjs灵活很多。
json
"scripts": {
"start": "icejs start",
"build:test": "NODE_ENV=test icejs build", // 对应.env.test
"build:prod": "NODE_ENV=production icejs build" // 对应.env.production
}
检验配置
如果你想在构建完成后快速检查构建过程中使用的是哪个环境变量配置,你可以在构建过程中打印出环境变量。
例如,在 Next.js中,你可以在你的 next.config.js
文件中添加以下代码:
js
module.exports = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
console.log('APP_ENV: ', process.env.APP_ENV);
return config;
},
};
这段代码会在构建过程中打印出 APP_ENV
环境变量的值。这样,你就可以知道构建过程中使用的是哪个环境变量配置。
然后,你可以运行 npm run build:test
或 npm run build:prod
命令来构建你的应用,并查看控制台输出,你应该能看到 APP_ENV
环境变量的值。
注意:这种方法只能用来检查构建过程中使用的环境变量,不能用来检查运行应用时使用的环境变量。
访问环境变量
process.env.[变量名]
来访问。process.env是 Node.js 提供的一个全局变量,用于访问当前进程的环境变量。
值得注意的是,有时候开发小伙伴在测试环境变量是否配置正确的时候,会直接console.log(process.env)查看,结果发现这是一个空的对象,这是为什么呢?
其实,为了安全性和性能考虑,框架在构建时会替换 process.env.yourVariable 的引用为实际的值。这是通过 webpack 的 DefinePlugin 实现的。这意味着 process.env不是一个真实的对象,因此你不能使用 process.env 来获取所有环境变量的列表。
备注
最后,如果是windows系统中运行启动/构建脚本,你可能需要使用一个库,如 cross-env,来确保你的命令在所有平台上都能正确运行。
实际案例
需求:需要在不同环境配置接口地址
- 开发环境://localhost:3000
- 测试环境://test-api.xxx.com
- 线上环境://prod-api.xxx.com
步骤:
- 添加两份环境配置,设置环境变量 NEXT_PUBLIC_API_HOST
js
.env.development
NEXT_PUBLIC_API_HOST=//localhost:3000
//.env.production
NEXT_PUBLIC_API_HOST=//prod-api.xxx.com
- package.json脚本命令
json
"scripts": {
"dev": "APP_EN=development next dev -p 3001", // .env.development
"build:test": "APP_ENV=test next build", // .env.production
"build:prod": "APP_ENV=production next build", // .env.production
}
备注:可以把环境变量直接放入到启动命令中,区分不同环境,process.env.APP_ENV可以直接获取到变量值。这在next.js仅支持两个环境的默认设置下,可以在代码中识别这里配置的APP_ENV从而作一些区分。
- 访问环境变量
js
// 可访问到不同环境的API地址,用于不同环境的请求
await fetch(`${process.env.NEXT_PUBLIC_API_HOST}/api/ai/image/generate`
结束语
至此,我们已经完成了环境变量配置的基本介绍,希望这对不熟悉此方面的开发者有所帮助。