如何在Next.js运行时修改环境变量无需重新构建项目
Next.js Pages Router 一次构建多环境部署方案
针对你需要遵循十二要素应用、一次构建多环境部署的需求,核心思路是把环境变量从构建时注入改成运行时读取,以下是具体实现方案:
1. 服务端(SSR/API Routes)运行时加载配置
服务端代码在服务器运行时执行,直接读取环境变量或自定义.env文件,无需构建时注入:
- 编写自定义环境加载脚本
env-loader.js:
// env-loader.js const dotenv = require('dotenv'); const path = require('path'); // 根据部署环境指定对应.env文件,比如APP_ENV=sit就读取.env.sit const envType = process.env.APP_ENV || 'production'; const envFilePath = path.resolve(__dirname, `.env.${envType}`); dotenv.config({ path: envFilePath }); // 导出需要的配置项 module.exports = { API_URL: process.env.API_URL, API_KEY: process.env.API_KEY };
- 在服务端组件或API路由中引入使用:
// pages/api/data.js const envConfig = require('../../env-loader'); export default function handler(req, res) { // 直接使用运行时加载的配置 fetch(`${envConfig.API_URL}/data`, { headers: { 'X-API-KEY': envConfig.API_KEY } }) .then(response => response.json()) .then(data => res.status(200).json(data)) .catch(err => res.status(500).json({ error: err.message })); }
部署时只需设置APP_ENV环境变量(如APP_ENV=uat),或替换对应.env文件,重启服务即可,无需重新构建。
2. 客户端运行时获取配置
客户端代码无法直接读取服务器.env文件,需通过服务端接口暴露非敏感配置:
- 新建配置接口
pages/api/config.js:
// pages/api/config.js const envConfig = require('../../env-loader'); export default function handler(req, res) { // 仅返回非敏感配置,禁止暴露API_KEY等密钥 res.status(200).json({ API_URL: envConfig.API_URL }); }
- 在客户端组件中初始化时拉取配置:
// pages/index.js import { useEffect, useState } from 'react'; export default function Home() { const [appConfig, setAppConfig] = useState(null); useEffect(() => { async function loadConfig() { const response = await fetch('/api/config'); const configData = await response.json(); setAppConfig(configData); } loadConfig(); }, []); if (!appConfig) return <div>加载中...</div>; return <div>当前API地址:{appConfig.API_URL}</div>; }
修改服务端配置后,重启服务,客户端刷新即可获取最新配置。
3. 利用Next.js内置运行时配置
Next.js Pages Router支持通过next.config.js定义运行时配置,区分服务端和客户端可用配置:
- 修改
next.config.js:
// next.config.js const dotenv = require('dotenv'); const envType = process.env.APP_ENV || 'production'; dotenv.config({ path: `.env.${envType}` }); module.exports = { // 仅服务端可用的敏感配置 serverRuntimeConfig: { API_KEY: process.env.API_KEY }, // 客户端可用的非敏感配置 publicRuntimeConfig: { API_URL: process.env.API_URL } };
- 服务端组件中获取配置:
// pages/about.js import getConfig from 'next/config'; export async function getServerSideProps() { const { serverRuntimeConfig, publicRuntimeConfig } = getConfig(); return { props: { apiKey: serverRuntimeConfig.API_KEY, apiUrl: publicRuntimeConfig.API_URL } }; } export default function About({ apiKey, apiUrl }) { return ( <div> <p>API地址:{apiUrl}</p> <p>服务端密钥(仅服务端可见):{apiKey}</p> </div> ); }
- 客户端组件中获取非敏感配置:
// pages/index.js import getConfig from 'next/config'; const { publicRuntimeConfig } = getConfig(); export default function Home() { return <div>API地址:{publicRuntimeConfig.API_URL}</div>; }
关键注意事项
- 敏感配置(如API_KEY)绝对不能暴露到客户端,必须仅在服务端使用,或通过服务端接口转发请求。
- 使用自定义加载逻辑时,需安装
dotenv依赖:npm install dotenv - Docker部署时,可将.env文件挂载到容器,或通过环境变量传递配置,避免把配置打包进镜像。
内容的提问来源于stack exchange,提问作者mee maw
相关产品推荐
相关产品推荐

