在本文中,你将了解 Vanilla JavaScript 中的环境变量。你还将了解如何通过 Netlify 构建命令为你的应用程序提供 API 密钥。

什么是 JavaScript 环境变量?

当你使用 React 或 Vue 等 JavaScript 框架在服务器端创建前端用户界面或 NodeJS 时,环境变量非常常见。

环境变量的全部意义(或者至少,按我理解)是它们让你可以灵活地设置条件,以让应用程序或软件适应不同模式——开发和生产。

当软件的 UI/前端与需要身份验证方法的 API 或后端服务器交互,以提供一个操作结果(如 API 调用)时,你会创建这些条件。最常见的方法是在完成请求之前提供 API 密钥。

如果你之前尝试过从 API 获取数据,则必须提供此 API 密钥,以便数据请求成功。这涉及向 API 调用添加 Authorization 标头。

下面是典型的获取请求及其授权标头。

const apiCall = () => {
    fetch(url, {
    	headers: {
            Authorization: `bearer ${private_api_key}`
        }
    })
    .then(res => res.json())
    .then(data => console.log(data))
    .catch(err => JSON.stingify(err))
}

顾名思义,环境变量存储变量。分配给这些变量的值可能是你执行某些请求或操作所需的 API 密钥。

要创建环境变量,你需要做的就是在你正在处理的项目的根文件夹中创建一个名为 .env 的新文件。然后,你可以开始添加不想向任何人透露的所有变量。

.gitignore 文件包含 Git 不应跟踪的文件列表,.env 文件将在此文件中。

如何在 VanillaJS 中使用 .env 文件

你在应用程序的后端使用环境变量。现在,你可能在想“但我可以在 React 应用程序中创建一个 .env 文件”。

事实是,你说得非常对——但是 React 已经以这样一种方式引导,Node.js 被包含在其中。这意味着你需要使用 Node 包管理器来执行某些操作。

你还可以在使用 VanillaJS 时创建一个 .env 文件,但你将无法访问 Node 在运行时提供的 process.env 全局变量。Node 将 .env 文件视为一个对象,因此它有能力这样做:process.env.env_variable.

const env = {
    env_variable: "bgrtyaqQtyfadV0F08BHGvfsgskl",
    topic_id: "F08BHGvfsgsklgrtyaqQtyfadV0F08"
}

console.log(process.env.env_variable)

// prints bgrtyaqQtyfadV0F08BHGvfsgskl to the console

你在客户端使用 VanillaJS,因此创建 .env 并使用环境变量实际上并不可行。这是因为你不能在浏览器中使用 node 提供的 process.env 全局变量(以访问在 .env 文件中创建的变量)。

那么如何才能真正使用环境变量呢?尤其是因为你不能在编写客户端 JavaScript 时使用环境变量(我的意思是 VanillaJS)。

名为 dotenv 的 npm 包提供了一种解决方案,因为它可以访问 Node 全局变量 process.env

一旦你安装了这个包,一个 node_modules 将自动创建一个带有两个文件的文件夹,package.jsonpackage-lock.json。这些包含应用程序的详细信息。

但是一旦你使用它,JavaScript 就会抛出一个错误,说 require 没有定义:

require("dotenv").config()

const apiCall = () => {
    fetch(url, {
    	headers: {
            Authorization: `bearer ${process.env.env_variable}`
        }
    })
    .then(res => res.json())
    .then(data => console.log(data))
    .catch(err => JSON.stingify(err))
}

发生此错误是因为 require 不在使 dotenv 包运行的 node_module 或包列表中。

简而言之,dotenv 需要 require 才能运行。你可以从 RequireJS 获取 require,但这是另一个麻烦。你必须通读文档,了解如何应用使 Node 的全局变量在客户端可用的脚本。

为什么要经历这些麻烦?

为什么?

人们通常将公共 API 用于个人项目或困惑于一些他们还没有完全掌握的概念。

大多数情况下,这些 API 不需要使用私有(API)密钥进行身份验证。当你处理仅允许使用 GET 方法获取数据的端点时,这很常见。

像 GitHub 或 Twitter 这样的 API 要求在允许请求通过之前,使用 api_keys 对用户进行身份验证。例如,GitHub GraphQL API 需要访问令牌才能成功调用 API。但是访问令牌有一些问题,其中之一是能够在一小时内执行 5000 个请求。

你永远无法将此访问令牌提交到项目的 Git 工作流程中。如果你提交了它,GitHub 将出于安全原因将其删除。这就是 VanillaJS 无法保存环境变量的问题。

GitHub 提供的访问令牌(一旦提交到工作流中,最终会被删除)将不允许应用程序在生产模式下运行。它在开发中工作得很好——但是一旦它被删除,并且存储库/项目被部署到 Netlify,那么 Netlify 就无法再次访问密钥。

你如何解决这个问题?

Netlify 有一个“构建和部署”设置选项卡。这允许你更改持续部署过程如何在 GitHub 上的项目或存储库中进行。

一旦 Netlify 检测到推送到主分支,你可以决定停止所有并发自动构建,停用所有构建,直到项目在开发模式下完全完成,还有更多我不记得的功能。

但是,这不是本文的重点。我们关心的是如何在本地使用 GitHub 访问令牌(通过确保它不会进入提交历史),然后允许 Netlify 在生产中访问它。

下图显示了 Netlify 上的“构建和部署”选项卡。

Screenshot-from-2021-05-31-10-39-42

注意到构建命令输入字段了吗?使用下面的代码片段:

cd js && echo -e "const TOKEN = 'api-token';\n\nexport default TOKEN;" > config.js

上面的命令将在构建过程中简单地在 js 文件夹中注入一个名为 config.js 的新文件。这使 Netlify 可以访问你的 API 密钥(访问令牌)。

如果你的项目中没有 js 文件夹,即你的项目根目录下所有文件都在,你可以简单地添加 echo -e "const TOKEN = 'api-token';\n\nexport default TOKEN;" > config.js 作为构建命令。

const TOKEN = 'api-token';

export default TOKEN;

为了确保你能够在 JavaScript 文件中使用 ES6 import 语句,你需要在脚本标签中添加 type="module" 属性。

<script src="./index.js" type="module"></script>

总结

这似乎不是使用环境变量的最佳实践或方法。这是因为在互联网上查看或访问你的应用程序的任何人,当他们在浏览器上打开 devtools 时,可能仍然可以看到你的 API 密钥。

但它帮助我绕过了 GitHub 删除这些密钥的问题,这反过来会阻止应用程序在生产环境中运行。

仅当你使用 API 时才应考虑此方法。当你的 API 密钥被泄露时,第三方使用它时不会造成太大伤害。

感谢你阅读这篇文章。希望它对你有帮助。;)

原文:How to Use Environment Variables in VanillaJS,作者:Caleb Olojo