环境变量简介及其使用方法

  • jdmedlock
  • 发布于 2020-07-01 11:17
  • 阅读 19

本文介绍了环境变量的基本概念及其在应用程序中的使用方式,特别是在NodeJS、dotenv包和webpack中的应用。文章详细说明了如何通过环境变量将配置与应用程序分离,以减少修改和重新发布应用程序的需求。

解耦配置与应用程序

照片由 Antoine Dautry 供稿,来源于 Unsplash

什么是环境变量?

任何计算机编程语言的两个基本组成部分是 变量常量。它们就像数学方程中的自变量一样,取决于其值可以改变程序的结果。变量和常量都代表唯一的内存位置,包含程序在计算中使用的数据。这两者之间的区别在于变量的值在执行过程中可能会改变,而常量的值则无法重新赋值。

环境变量 是一个变量,其值是在程序外部设置的,通常是通过操作系统或微服务内置的功能。环境变量由名称/值对组成,任何数量的环境变量可以创建并在某个时间点可供引用。

## 来自 NASA 开放数据门户的陨石数据集
REACT_APP_METEORITE_LANDING_HOMEPAGE="https://data.nasa.gov/Space-Science/Meteorite-Landings/gh4g-9sfh"
REACT_APP_METEORITE_STRIKE_DATASET="https://data.nasa.gov/resource/y77d-th95.json"

在应用程序初始化期间,这些变量被加载到 process.env 中,并通过在名称后缀上加上环境变量名来访问,如下所示。

fetch(process.env.REACT_APP_METEORITE_STRIKE_DATASET)
.then((response) => {
  return response.json();
})
.then((strikesJSON) => {
  this.setState({ meteoriteStrikes: strikesJSON });
  this.setState({ isDataLoaded: true});
});

在运行时,对环境变量名称的引用将被其当前值替换。在这种情况下,process.env.REACT_APP_METEORITE_STRIKE_DATASET 被其值 "https://data.nasa.gov/resource/y77d-th95.json" 替换。

环境变量的主要用例是减少因配置数据的更改而需要修改和重新发布应用程序的需求。从上面的例子来看,当 REACT_APP_METEORITE_STRIKE_DATASET 的 URL 更改时,无需对源代码进行修改、测试和部署修改后的应用程序。

修改和发布应用程序代码相对复杂,并增加了在生产环境中引入不良副作用的风险。当 URL 是通过环境变量而不是应用程序定义时,变更过程包括检查新 URL 的有效性,使用操作系统命令更新相应的环境变量或更新配置文件,并测试受影响的应用功能,以确保应用程序仍按预期工作。

环境变量的用例包括但不限于以下数据:

  • 执行模式(例如,生产、开发、预发布等)
  • 域名
  • API URL/URI
  • 公共和私有身份验证密钥(仅在服务器应用程序中是安全的)
  • 组邮件地址,例如用于营销、支持、销售等的地址
  • 服务账户名称

这些共同点在于它们的数据值变化不频繁,应用程序逻辑将它们视为常量,而不是可变变量。

接下来,我们来看一下如何使用本地操作系统、NPM 包 dotenv 和 webpack 来使用环境变量。

NodeJS 中的环境变量

图 1 — 操作系统环境变量

在后端应用程序中使用环境变量依赖于操作系统命令来定义环境变量及其值。系统管理员可以使用命令行界面定义这些变量,但通常通过 shell 脚本来定义更为合理。环境变量通常不会在操作系统之间全局可访问,通常是会话特定的。例如,使用 Linux 命令行:

setenv REACT_APP_METEORITE_LANDING_HOMEPAGE = "https://data.nasa.gov/Space-Science/Meteorite-Landings/gh4g-9sfh"

在运行时,NodeJS 会自动加载环境变量到 process.env 中,以便将其提供给应用程序。例如,fetch(process.env.REACT_APP_METEORITE_STRIKE_DATASET)

环境变量的管理和操作在不同的操作系统之间有所不同。此外,这在不同的微服务环境(如 Heroku)之间也有所不同,在这些环境中,环境变量的管理是通过管理面板进行的。因此,在应用程序中使用环境变量之前,理解特定平台的因素至关重要。

一种最小化这些差异的方法是使用 cross-env NPM 包,它提供了一种与操作系统无关的 POSIX 兼容命令来设置环境变量。

dotenv 包中的环境变量

在前端应用程序中使用环境变量的支持不是浏览器或 JavaScript 的“开箱即用”特性;需要使用像 dotenv 的包来启用它。需要说明的是,前端和后端应用程序都可以使用 dotenv。

使用这个包非常简单,

import dotenv from 'dotenv';dotenv.config();
console.log(process.env.REACT_APP_METEORITE_STRIKE_DATASET);

这个技术通过将数据从源代码移动到 .env 文件中的环境变量来实现数据的外部化。将 .env 文件名添加到 .gitignore 中可以防止 git push 命令将其上传到 GitHub 仓库,在公共仓库中它将对任何人可见。

图 2 — .env 文件使用

.env 中的环境变量格式为 name=value,以 # 开头的行被视为注释,空行被忽略。例如,

## 来自 NASA 开放数据门户的陨石数据集
REACT_APP_METEORITE_LANDING_HOMEPAGE="https://data.nasa.gov/Space-Science/Meteorite-Landings/gh4g-9sfh"
REACT_APP_METEORITE_STRIKE_DATASET="https://data.nasa.gov/resource/y77d-th95.json"

然而,许多流行的包,如 Create React App (react-scripts)、Gatsby、GraphQL CLI、Node Lambda 等,已经包含了 dotenv。如果你已经使用其中一个包,dotenv 可能已经可用于你的应用程序。例如,上面的代码片段来自一个由 Create React App 生成的应用程序,该应用程序要求环境变量以 REACT_APP_ 为前缀。

在 Create React App 的情况下,无需调用 dotenv.config(),因为 node_modules/react-scripts/config/env.js 会在应用程序启动时自动用 .env 文件的内容填充 process.env。有关 Create React App 的示例,请查看 GitHub 上的 Meteorite Explorer 仓库

由于浏览器环境不安全,应用程序必须特别小心,不要暴露敏感信息,如应用程序密钥。有关如何保护前端环境的更多信息,请查看“保护应用程序资产:如何保护你的秘密”一文。

webpack 中的环境变量

webpack 是一个打包工具,将应用程序中的许多不同模块、资源和资产转换、打包或一起处理,以便在浏览器中使用。webpack 的一个常见用法是为生产部署准备应用程序。例如,Create React App 的 build 脚本使用 webpack 创建包含应用程序生产版本的 build 目录。

虽然 webpack 实现了对使用环境变量的支持,但它是作为 webpack 命令的一个 选项。例如,

webpack --env.NODE_ENV=local

通过在 webpack 命令中指定多个 --env 选项来支持多个环境变量。这些将在 webpack 配置文件(例如 webpack.config.js)中作为 env. 后缀环境变量名进行引用。例如,console.log(env.NODE_ENV)

webpack 配置文件还可以使用 process.env 引用操作系统定义的环境变量,就像其他任何 JavaScript 模块一样。考虑以下来自 Create React App 的 webpack.config.prod.js 示例。

// 源映射占用资源较多,可能导致大源文件出现内存不足的问题。const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';

结束语

“抽象让世界进入更复杂的变量关系;它可以从显得虚无的事物中提取美、替代的地形、丑陋和强烈的现实。”—— Jerry Saltz

使用环境变量是一种通过将不经常更改的数据与代码分离来简化应用程序配置的方法。但是,尽管这个技术简单,其使用受到应用程序类型(前端或后端)和运行环境(操作系统或微服务)的影响。在充分利用环境变量的同时,理解其细微差别并能够高效安全地利用它们是区分经验丰富的 Web 开发者与缺乏经验的开发者的一个因素。与任何技术一样,诀窍不在于知道如何使用某样东西,而在于知道在何时使用它。

什么是 Chingu?

欢迎加入我们 Chingu.io,通过加入我们的远程 Voyage 项目团队来走出“教程地狱”,构建应用程序,提升“硬”技能,学习新的“软”技能。我们帮助开发者弥补他们所学知识与雇主所需技能之间的差距。

  • 原文链接: medium.com/chingu/an-int...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
jdmedlock
jdmedlock
江湖只有他的大名,没有他的介绍。