您在 Next.js 中以错误的方式读取环境变量
读取环境
如果您曾经编写过如下代码:
const url = `https://www.example.com/api/blog?api_key=${process.env.API_KEY}`
那你就做错了!
这就是为什么这是一个坏主意。
在您构建应用程序而没有设置API_KEY
环境变量的情况下,应用程序将使用环境变量undefined
。
显然undefined
这不是正确的 API 密钥,这将导致使用该 URL 的任何请求失败。
这里的问题是,当错误出现时,消息会非常具有误导性,看起来像这样:
Error: Unauthorized
并且仅当您尝试使用 url 获取博客文章时才会出现此错误。
如果获取博客文章是一项基本功能,那么在没有 API 密钥的情况下应用程序甚至不应该进行编译。
天真地期望API_KEY
环境变量存在会隐藏错误,并且由于误导性的错误消息,这个问题很难调试。
为了解决这个问题,我们需要做两件事。
- 当存在导致应用程序无法运行的问题时,应用程序需要立即且明显地失败。
- 一个有意义的抽象来封装环境变量的加载。
如何在 Next.js 中加载环境变量
这适用于任何 node.js 应用程序。Next.js 让这变得更容易,因为它附带了大量必要的样板代码。
让我向您展示如何在 Next.js 中正确使用环境变量,然后解释为什么这样做有效。
创建一个.env.local
文件。在这里,你将把所有想要在本地开发环境中使用的环境变量都放进去。
API_KEY=secret
Next.js 会自动添加此文件,.gitignore
因此您不必担心它最终会出现在您的版本控制系统中。
如果您使用的是 Next.js 以外的任何其他框架,则需要使用dotenv之类的包从文件中读取环境变量。
现在来谈谈面包和黄油。
使用此代码创建一个config.ts
文件,将环境变量读入您的配置中。
const getEnvironmentVariable = (environmentVariable: string): string => {
const unvalidatedEnvironmentVariable = process.env[environmentVariable];
if (!unvalidatedEnvironmentVariable) {
throw new Error(
`Couldn't find environment variable: ${environmentVariable}`
);
} else {
return unvalidatedEnvironmentVariable;
}
};
export const config = {
apiKey: getEnvironmentVariable("API_KEY")
};
并将我们之前编写的代码更改为:
import { config } from "./config"
const url = `https://www.example.com/api/blog?api_key=${config.apiKey}`
为什么这是加载环境变量的正确方法
如果您忘记添加环境变量,API_KEY
应用程序甚至不会构建/编译,并且会抛出如下错误:Couldn't find environment variable: API_KEY
。
我们的应用程序现在立即且明显地失败了。
这被称为快速失败。
它是清洁代码原则的一部分,您可以在此处阅读更多相关信息:https://www.martinfowler.com/ieeeSoftware/failFast.pdf
因为我们使用的是 TypeScript,所以我们可以 100% 确定配置中的所有值都存在。
此外,TypeScript 可以帮助我们避免小错误。
如果我们输入错误:
const url = `https://www.example.com/api/blog?api_key=${config.apiKeu}`
TypeScript 将给出以下错误:
Property 'apiKeu' does not exist on type '{ apiKey: string; }'. Did you mean 'apiKey'?
那太酷了!
这就像拥有超能力的编码一样。
封装逻辑
让我们看一下我们开始的例子:
const url = `https://www.example.com/api/blog?api_key=${process.env.API_KEY}`
你注意到那process.env
部分了吗?
为什么获取博客文章的功能应该了解应用程序当前正在运行的用户环境?
嗯,不应该。
获取博客文章的逻辑并不关心 API 密钥从何而来。无论是来自用户环境、文本文件还是 API,对它来说都没有任何区别。
因此,它不应该依赖于process.env
或任何其他低级抽象。
创建一个仅用于读取环境变量的配置封装了此功能并创建了有意义的高级抽象。
一个配置。
由于这一点,我们可以改变获取配置值的方式(如 api 密钥),而完全不触及博客文章功能!
另一个非常隐蔽的好处是,单元测试变得容易了十倍。我们不用再纠结于用户环境,只需用我们想要的值模拟配置即可。
结论
虽然这可能看起来很迂腐,但在编写代码时牢记这些小事会让你成为一名更好的软件工程师。
文章来源:https://dev.to/austinshelby/you-are-reading-environment-variables-the-wrong-way-in-nextjs-45da