コンテンツにスキップ

Environment Variables

このコンテンツはまだ日本語訳がありません。

环境变量

Remix 不会直接对环境变量执行任何操作(本地开发期间除外),但我们发现一些有用的模式将在本指南中分享。

环境变量是服务器上可供应用程序使用的值。您可能熟悉无处不在的NODE_ENV。您的部署服务器可能会自动将其设置为生产

如果 process.env.NODE_ENV 的值与有效模式相对应,则运行 remix build 会使用该值进行编译:productiondevelopmenttest。如果 process.env.NODE_ENV 的值无效,则默认使用production

以下是您可能在现实中发现的一些示例环境变量:

  • DATABASE_URL:Postgres 数据库的 URL
  • STRIPE_PRIVATE_KEY:结帐工作流将在服务器上使用的密钥
  • STRIPE_PUBLIC_KEY:结帐工作流将在浏览器上使用的密钥

如果您在过去几年的 Web 开发经验主要是使用 JS 框架,那么您可能会认为这些是供您构建使用的东西。虽然它们对于捆绑代码很有用,但传统上它们是构建参数而不是环境变量。环境变量在服务器运行时最有用。例如,您可以更改环境变量以更改应用程序的行为,而无需重建甚至重新部署。

服务器环境变量

本地开发

如果您使用 remix dev 服务器在本地运行您的项目,它内置了对 dotenv 的支持。

首先,在项目根目录中创建一个 .env 文件:

Terminal window
touch .env

不要将您的 .env 文件提交到 git,因为它包含机密!

编辑你的 .env 文件。

SOME_SECRET=super-secret

然后,当运行remix dev时,您将能够在加载器/操作中访问这些值:

export async function loader() {
console.log(process.env.SOME_SECRET);
}

如果您使用的是 @remix-run/cloudflare-pages@remix-run/cloudflare 适配器,环境变量的工作方式会略有不同。您需要在 .dev.vars 文件中定义本地环境变量。它的语法与上面提到的 .env 示例文件相同。

然后,它们将通过 Remix 的 context.cloudflare.env 在您的 loader/action 函数中使用:

export const loader = async ({
context,
}: LoaderFunctionArgs) => {
console.log(context.cloudflare.env.SOME_SECRET);
};

请注意,.env.dev.vars 文件仅用于开发。您不应在生产中使用它们,因此 Remix 在运行 remix serve 时不会加载它们。您需要按照主机的指南通过以下链接将机密添加到生产服务器。

生产

部署到生产环境时的环境变量将由您的主机处理,例如:

浏览器环境变量

有些人问 Remix 是否允许他们将环境变量放入浏览器包中。这是构建繁重的框架中的常见策略。但是,这种方法存在一些问题:

  1. 它实际上不是一个环境变量。您必须在构建时知道要部署到哪个服务器。
  2. 如果不重建并重新部署,则无法更改值。
  3. 很容易意外将机密泄露到可公开访问的文件中!

相反,我们建议将所有环境变量保留在服务器上(所有服务器机密以及浏览器中的 JavaScript 所需的内容),并通过window.ENV将它们公开给浏览器代码。由于您始终拥有服务器,因此您不需要在包中提供此信息,您的服务器可以在加载器中提供客户端环境变量。

  1. 从根加载器返回客户端的 ENV - 在加载器内部,您可以访问服务器的环境变量。加载器仅在服务器上运行,并且永远不会捆绑到客户端 JavaScript 中。
导出异步函数 loader() {
返回 json({
ENV: {
STRIPE_PUBLIC_KEY: process.env.STRIPE_PUBLIC_KEY,
FAUNA_DB_URL: process.env.FAUNA_DB_URL,
},
});
}
导出函数 Root() {
返回 (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<Outlet />
<Scripts />
</body>
</html>
);
}
  1. ENV 放在窗口上 - 这就是我们将值从服务器传递到客户端的方式。确保将其放在 <Scripts/> 之前
导出异步函数 loader() {
返回 json({
ENV: {
STRIPE_PUBLIC_KEY: process.env.STRIPE_PUBLIC_KEY,
},
});
}
导出函数 Root() {
const data = useLoaderData<typeof loader>();
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<Outlet />
<script
dangerouslySetInnerHTML={{
__html: `window.ENV = ${JSON.stringify(
data.ENV
)}`,
}}
/>
<Scripts />
</body>
</html>
);
}
  1. 访问值
`@stripe/stripe-js`导入{loadStripe};
导出异步函数 redirectToStripeCheckout(
sessionId
) {
const stripe = await loadStripe(
window.ENV.STRIPE_PUBLIC_KEY
);
return stripe.redirectToCheckout({ sessionId });
}