You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS:应用启动时动态环境变量设置遇客户端process.env为空问题

解决Next.js 5.0.0客户端process.env为空的问题(单构建包多环境部署场景)

针对你遇到的Next.js 5.0.0客户端无法读取环境变量,但服务器端正常的问题,结合你单构建包部署到多环境的需求,我来拆解原因并给出适配的解决方案:

核心原因分析

Next.js 5.x版本不像新版有NEXT_PUBLIC_前缀自动暴露客户端环境变量的机制,浏览器环境本身也不存在process对象。而你使用的babel-plugin-inline-dotenv是编译时注入变量,如果是单构建包部署到多环境,这种方式会导致所有环境共用构建时的固定变量,既不符合你的需求,还可能因为客户端编译环节未正确触发插件,导致process.env为空。

推荐解决方案:服务器端动态注入环境变量到客户端

这种方式可以让单构建包在不同环境部署时,动态读取对应环境的变量,同时让客户端能正常获取到需要的变量:

1. 确保服务器端正确加载环境变量

首先安装dotenv(用来加载.env文件):

npm install dotenv --save

如果有自定义服务器入口文件(比如server.js),在顶部添加加载.env的代码:

require('dotenv').config();
const next = require('next');
const http = require('http');

const port = process.env.PORT || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  http.createServer((req, res) => {
    handle(req, res);
  }).listen(port, (err) => {
    if (err) throw err;
    console.log(`> Ready on http://localhost:${port}`);
  });
});

如果没有自定义服务器,Next.js默认的启动脚本也可以修改,在package.json里添加:

"scripts": {
  "start": "node -r dotenv/config node_modules/.bin/next start",
  "build": "node -r dotenv/config node_modules/.bin/next build"
}

2. 自定义_document.js注入变量到客户端

在pages目录下创建_document.js,通过服务器端的getInitialProps获取环境变量,然后挂载到浏览器的window对象上:

import Document, { Head, Main, NextScript } from 'next/document';

export default class CustomDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    // 只暴露客户端需要的非敏感变量,不要把密钥、密码等敏感信息放这里!
    const clientEnv = {
      API_BASE_URL: process.env.API_BASE_URL,
      APP_NAME: process.env.APP_NAME
    };
    return { ...initialProps, clientEnv };
  }

  render() {
    return (
      <html>
        <Head />
        <body>
          <Main />
          <script
            dangerouslySetInnerHTML={{
              __html: `window.__CLIENT_ENV__ = ${JSON.stringify(this.props.clientEnv)};`
            }}
          />
          <NextScript />
        </body>
      </html>
    );
  }
}

3. 客户端代码中使用环境变量

在客户端组件里,通过window.__CLIENT_ENV__访问变量,注意要判断是否在浏览器环境:

// 示例页面组件
const HomePage = () => {
  // 确保只在浏览器环境读取window变量
  const apiUrl = typeof window !== 'undefined' ? window.__CLIENT_ENV__.API_BASE_URL : '';

  return (
    <div>
      <h1>当前环境API地址:{apiUrl}</h1>
    </div>
  );
};

export default HomePage;

为什么不推荐继续用babel-plugin-inline-dotenv?

这个插件是编译时替换process.env的引用,意味着构建时变量就被硬编码到代码里了。如果你用单构建包部署到多环境,所有环境都会使用构建时的变量值,无法实现不同环境的变量差异,完全不符合你的部署需求。

内容的提问来源于stack exchange,提问作者AleG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:38:33