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

Next.js仅首次渲染使用HOC的页面时出现process未定义报错

问题根因

Next.js 中 getInitialProps 会同时在服务端和客户端执行:

  • 直接刷新页面、首次输入地址访问时,getInitialProps 在服务端运行,能正常读取 Node 环境的 process 变量,所以访问正常
  • 当通过客户端路由(比如Next.js的Link组件跳转)进入页面时,getInitialProps 会在浏览器环境运行,浏览器不存在process全局变量,就会抛出你遇到的报错。

你之前用getServerSideProps没有问题,是因为getServerSideProps只会在服务端执行,永远不会跑到客户端运行。


解决方案1:改用getServerSideProps封装逻辑(推荐)

既然你之前用getServerSideProps没有问题,优先选择这个方案,避免客户端执行的问题,HOC 可以调整为合并页面原有getServerSideProps和环境变量读取逻辑:

// src/components/app/withEnvironment.tsx
import {
  EnvironmentValues,
  readPublicEnvironmentValues,
} from 'config/environment';
import { NextPage, GetServerSideProps } from 'next';
import { EnvironmentProvider } from 'providers';

export function withEnvironment<TProps extends {}>(
  Page: NextPage<TProps>,
  pageGetServerSideProps?: GetServerSideProps<TProps>
): NextPage<TProps & {environmentValues: EnvironmentValues}> {
  const PageWithEnvironment = ({
    environmentValues,
    ...props
  }: TProps & {environmentValues: EnvironmentValues}) => {
    return (
      <EnvironmentProvider value={environmentValues}>
        <Page {...props as TProps} />
      </EnvironmentProvider>
    );
  };

  // 封装getServerSideProps,只会在服务端执行
  const getServerSideProps: GetServerSideProps = async (ctx) => {
    const environmentValues = readPublicEnvironmentValues();
    // 合并原页面的getServerSideProps返回值
    if (pageGetServerSideProps) {
      const pageRes = await pageGetServerSideProps(ctx);
      if ('props' in pageRes) {
        return {
          ...pageRes,
          props: {
            ...pageRes.props,
            environmentValues
          }
        }
      }
      return pageRes;
    }
    return {
      props: {
        environmentValues
      }
    }
  }

  (PageWithEnvironment as NextPage).getServerSideProps = getServerSideProps;

  return PageWithEnvironment;
}

页面使用的时候可以传入自己的getServerSideProps:

// src/pages/change-sets/index.tsx
import {withEnvironment} from 'components/app';
import {useEnvironment} from 'providers'

function ChangeSetPage(): JSX.Element {
  const environmentValues = useEnvironment();
  return (
    <div>
        <h1>ChangeSetPage</h1>
    </div>
  );
}

// 页面如果有自己的getServerSideProps可以作为第二个参数传入
export default withEnvironment(ChangeSetPage/*, yourPageGetServerSideProps */);

解决方案2:兼容getInitialProps的执行环境

如果你一定要保留getInitialProps的写法,可以在执行读取环境变量逻辑前判断当前运行环境,同时把服务端读取到的环境变量同步到客户端:

  1. 先调整getInitialProps的逻辑,判断是否是服务端环境:
(PageWithEnvironment as NextPage).getInitialProps = async (ctx) => {
  let environmentValues: EnvironmentValues;
  // 有req对象说明是服务端执行
  if (ctx.req) {
    environmentValues = readPublicEnvironmentValues();
  } else {
    // 客户端直接从window上取服务端注入的环境变量
    environmentValues = window.__ENVIRONMENT_VALUES__;
  }
  // 合并原页面的getInitialProps返回值
  const pageInitialProps = Page.getInitialProps ? await Page.getInitialProps(ctx) : {};
  return {
    ...pageInitialProps,
    environmentValues
  };
};
  1. 在自定义_document.tsx中把环境变量注入到客户端window对象:
// src/pages/_document.tsx
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { readPublicEnvironmentValues } from 'config/environment'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    const environmentValues = readPublicEnvironmentValues()
    return {
      ...initialProps,
      environmentValues
    }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <script
            dangerouslySetInnerHTML={{
              __html: `window.__ENVIRONMENT_VALUES__ = ${JSON.stringify(this.props.environmentValues)}`
            }}
          />
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

注意事项

  • 所有需要在客户端访问的环境变量,记得加上NEXT_PUBLIC_前缀,Next.js会自动把这类变量注入到客户端代码中,不需要额外处理就能直接访问
  • 你原来的HOC直接覆盖了getInitialProps,如果原页面本身定义了getInitialProps,原有逻辑会丢失,上面的示例代码已经补充了合并原页面getInitialProps/getServerSideProps的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:24:07