Next.js应用如何配置多环境env文件并实现API baseURL动态切换
这个问题是两个原因叠加导致的:
- Next.js 有内置的环境变量加载优先级,运行
next dev时默认会优先加载.env.development里的变量,优先级高于你通过 env-cmd 传入的变量 - env-cmd 默认不会覆盖已经存在的环境变量,所以只要
.env.development里有同名的BASE_URL,就会把 env-cmd 加载的变量覆盖掉
解决方案
方案1:给 env-cmd 增加 --override 参数(最简单快速)
env-cmd 提供了 --override 参数,允许覆盖已存在的环境变量,直接修改 package.json 里的 scripts 配置即可:
"scripts": { "dev": "next dev", "dev:staging": "env-cmd --override -f .env.staging next dev", "dev:production": "env-cmd --override -f .env.production next dev", "build": "next build", "build:staging": "env-cmd --override -f .env.staging next build", "build:production": "env-cmd --override -f .env.production next build", "start": "next start", "start:staging": "env-cmd --override -f .env.staging next start", "start:production": "env-cmd --override -f .env.production next start" }
改完之后重新运行命令,就会优先加载你指定的 env 文件里的变量。
方案2:使用 Next.js 内置能力加载自定义环境(更稳定,兼容多系统)
如果你不想依赖 env-cmd,可以直接用 Next.js 原生 + dotenv 实现自定义环境加载,兼容性更强:
先安装依赖:
npm install dotenv cross-env --save-dev
(cross-env 用来兼容 Windows、Mac、Linux 不同系统的环境变量设置语法)修改
next.config.js配置:
const dotenv = require('dotenv'); const path = require('path'); // 根据传入的环境标识加载对应的env文件 const currEnv = process.env.NEXT_APP_ENV || 'local'; dotenv.config({ path: path.join(__dirname, `.env.${currEnv}`), override: true }); /** @type {import('next').NextConfig} */ const nextConfig = { // 其他原有配置保持不变 } module.exports = nextConfig;
- 修改
package.json里的 scripts:
"scripts": { "dev": "cross-env NEXT_APP_ENV=local next dev", "dev:staging": "cross-env NEXT_APP_ENV=staging next dev", "dev:production": "cross-env NEXT_APP_ENV=production next dev", "build": "cross-env NEXT_APP_ENV=production next build", "build:staging": "cross-env NEXT_APP_ENV=staging next build", "build:production": "cross-env NEXT_APP_ENV=production next build", "start": "cross-env NEXT_APP_ENV=production next start", "start:staging": "cross-env NEXT_APP_ENV=staging next start", "start:production": "cross-env NEXT_APP_ENV=production next start" }
注意事项
- 如果你的
BASE_URL需要在客户端(浏览器端)的代码里访问,必须把变量名改成NEXT_PUBLIC_BASE_URL前缀,否则只有服务端代码能拿到该变量,客户端会拿到 undefined - 可以在创建 axios 实例的代码里加一行
console.log('当前BASE_URL:', process.env.BASE_URL),运行项目时看终端输出,确认变量是否正确加载
内容的提问来源于stack exchange,提问作者Paras Buda
相关产品推荐
相关产品推荐

