在 NextJS 中将 docker 运行时环境变量与应用程序路由器/服务器组件一起使用?

Mic*_*sen 7 environment-variables docker next.js

如果您在 NextJS 中使用 Pages 路由器,则有多种方法可以在运行时获取环境变量(除了可以在Craigs Wardmans 博客中了解有关 NextJS + docker 的更多信息之外,还可以使用诸如React-env / next-runtime- env 之类的工具) )。getStaticProps

但是,当您在应用程序路由器中使用服务器组件(可从 NextJS 13 获得)时,如何做到这一点?

可以在Dockerfile中构建 NextJS 项目ENTRYPOINT,但我不想要缓慢的启动和大图像。我想搜索替换方法也适用于应用程序路由器,但这感觉有点hacky。

Ian*_*non 0

在 NextJS 13 中,使用 App 路由器,组件可以是服务器组件或客户端组件,它们在不同的环境中呈现

\n

您可以访问服务器和客户端组件中的环境变量,但您需要注意某些行为:

\n
    \n
  • 服务器组件可以访问任何环境变量。
  • \n
  • 客户端组件只能访问名称开头的环境变量NEXT_PUBLIC_文档)。
  • \n
  • 布局是服务器组件,除非通过字符串"use client"文档)指定为客户端组件。
  • \n
  • 环境变量值将在构建时内置,除非:\n
      \n
    • 该组件是服务器组件,并且
    • \n
    • 该组件是动态的(请注意force-dynamic下面的示例)。您可以通过观察构建输出中组件左侧的符号来检查组件是静态还是动态。圆圈\xe2\x97\x8b表示静态组件,lambda\xce\xbb表示动态组件。
    • \n
    \n
  • \n
\n

因此,如果您希望在客户端组件中运行时访问环境变量,则必须以某种方式从服务器组件传递它。例如,如果您希望应用程序的大部分在客户端环境中运行并使其使用运行时环境变量,则可以将整个元素包装在客户端组件中,如下所示。然后,您可以在组件中运行任何客户端代码,例如将环境变量添加到 React Context。bodyClientBody

\n

app/layout.jsx:

\n
import ClientBody from "@/components/Body";\n\nexport const dynamic = "force-dynamic"\nconst myVar = process.env.NEXT_PUBLIC_MY_VAR;\n\nexport default function RootLayout ({\n  children,\n}) {\n  console.log(process.env.NEXT_PUBLIC_MY_VAR, myVar);\n\n  return (\n    <html lang="en">\n      <ClientBody\n        myVar={myVar}\n      >\n        {children}\n      </ClientBody>\n    </html>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

components/Body.jsx

\n
"use client";\n\nimport Header from "@/components/Header";\nimport Footer from "@/components/Footer";\n\nexport default function ClientBody({\n  myVar,\n  children\n}) {\n  console.log(process.env.NEXT_PUBLIC_MY_VAR, myVar);\n\n  return (\n    <body>\n      <Header />\n      {children}\n      <Footer />\n    </body>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

向 Docker 提供运行时值,如下所示:docker run -e NEXT_PUBLIC_MY_VAR="..." ...

\n

在该示例的控制台输出中,您将看到 的值process.env.NEXT_PUBLIC_MY_VAR将在客户端组件中的构建时显示为冻结,但 prop 的值myVar将是运行时环境的值。

\n