前奏曲
在现代前端项目中.env
文件随处可见,里面都是一些项目中的配置项,可以在项目中拿来就用,虽然这是一个不太起眼的东西,但是这些.env
文件在前端工程化中是有一定的用处和意义的。
就让我们通过这篇短文一起来看看。
process.env
现在的前端项目都是用 Node
来作为辅助开发工具,而 process
是 Node.js
中的 一个全局变量,提供来有关当前 Node.js 进程的信息并对其进行控制。而 process
中的 env
则是返回包含用户环境的对象。
通俗点说,就是可以通过 process.env
拿到当前项目运行环境的信息。
Mac下的基本环境信息:
// index.js
console.log(Object.keys(process.env));
设置环境变量
1、命令行
当需要在环境变量中加入自定义的一些配置,可以直接通过命令行的方式来进行设置:
console.log(process.env.PROT)
PROT=10086 node index.js
此时项目运行的环境变量中就有了 PROT
。
如果需要自定义其他变量,可以以键值的方式继续添加参数:
PROT=10086 NDOE_DEV=development node index.js
这样的方式虽然很简单,但是也有很多缺陷:
- 可阅读性低:不能很直观的看到环境变量的配置(辣眼睛)
- 容易输入错误:如果不只是端口号,还有数据库信息、应用密钥等等,全部键入一行(手动狗头)
- 难以管理:如何记住或者管理所有的环境变量及其值(手动狗头)
所以就有了下面一种方式。
2、.env文件
创建
直接在项目根目录中创建 .env
文件,然后键入环境变量及其值。
NDOE_ENV=development
PROT=10086
APP_KEY=***********
HOST_URL=**********
⚠️注意:不要把.env
文入放入代码版本管理中,因为这些环境变量都是项目中的隐私数据,否则将面临被暴露的风险。
读取
创建 .env
文件后,可以自己编写代码来查找解析文件并将其写入到你的项目中,或者利用第三方的npm
包,比如 dotenv
,点击这里查看repo。
yarn add dotenv
// .env
PROT=10086
const dotenv = require('dotenv');
dotenv.config();
console.log(process.env.PROT); // 10086
现在当你执行命令脚本的时候就不用传入环境变量及其值了,在 .env
文件里也能更直观的看到和管理各环境变量的配置。
更好的组织
如果不进行环境变量的组织,那么在使用的时候就会像这个样子:
process.env.PORT
但是一旦环境变量很多,是在每个地方都这样使用呢?还是将所有的环境变量集中管理更好呢?
显然是后者。
因为在所有需要使用的地直接引用变量与集中管理相比,重构和维护会更加困难。
所以创建一个负责收集环境变量的模块是一个更好的方式,这样可以轻松地一次查看环境变量并将它们映射为可读的名称。
手动整理
创建一个名为 config.js
的文件,然后写入变量,将其命名为具有良好可读性的属性进行映射并导出它们。
例如:
const dotenv = require('dotenv');
dotenv.config();
module.exports = {
hostUrl:process.env.HOST_URL,
secretKey:process.env.API_KEY,
port:process.env.PORT
};
然后就可以这样进行使用:
const {port} = require('./ config');
console.log(`端口为:$ {port}`); // 10086
这样有什么好处呢?
- 项目文件组织更为直观合理
- 清楚的知道环境变量的映射关系
- 变量重命名为更具可读性的属性
- 可以添加其他非环境变量的配置属性
但是如果要添加新的环境变量时,就必须将其添加到config
模块中。
这就是手动的方式,那么有自动收集方式吗?
当然有!
自动整理
前面提到的第三方 NPM
包 dotenv
就可以做到。
// config.js
const dotenv = require('dotenv');
const result = dotenv.config();
if (result.error) {
throw result.error;
}
const { parsed: envs } = result;
console.log(envs);
module.exports = envs;
然后就可以其他模块中这样引用:
const { HOST_URL, API_KEY, PROT } = require('./config');
所以现在需要用哪一种方式,这就取决于你了,无论哪一种方式,你得考虑以下是否让dotenv
成为项目运行的依赖项。
建议使用手动的方式进行整理环境变量,这样还可以删除 dotenv
的依赖,但前提是需要再做一下处理: 预加载环境变量。
减少依赖
在平时的项目中会有很多依赖,但是应该考虑如何将依赖性降低到最低,dotenv
这个 npm
包的确很方便,但这个不需要成为项目运行时的依赖。dotenv
提供了一个选项,您可以在其中预加载代码之外的变量。
但是如何删除 dotnev
运行时的依赖,然后又保留它的特性呢?
1、在安装 dotenv
的时候,安装为开发(dev)依赖,删除 dotenv
所有相关代码。
2、然后使用 -require(-r)
这个选项来进行预加载 dotenv
。
// config.js
module.exports = {
port: process.env.PORT
};
// index.js
const {port} = require('./config');
console.log(`端口号为:${port}`);
node -r dotenv/config index.js
生产环境
看到了这里,有人会说,开发环境(development)是可以通过 dotenv
的预加载来读取环境变量,但在生产环境(production)咋办?
在构建应用程序的12要素指南中也指出应用程序需要和配置进行分离,最好的方式就是保存在环境变量中,以为这些配置基本都是端口号、服务账户凭证、数据库链接等私密信息,如果项目中的配置是保存在代码中的,或者加入了代码的版本管理,那么你的项目暴露这些私密信息的几率是很大的。
如果你还不了解什么是12要素,你可以看看《涨知识了!用这 12 要素来构建你的应用程序》一文。
所以根据 配置项(config) 这一要素来看,.env
文件是一个私密文件,也不应该加入版本控制。
如果运行上云服务器上,则可以用云服务商提供的功能来进行设置。或者使用第三方的服务平台 Azure 来管理环境变量。可以通过它的 CLI 启动 Node 项目,然后就可以从云服务平台拿到环境变量信息。
如果在 Docker
中运行,则可以使用 Docker
的功能来加载环境变量。
对于生产环境如何对环境变量进行配置的细节将会在之后的文章就行阐述。
如何共享
由于.env
文件是保存项目的配置信息,这些信息都是私密的,不能对外暴露的,那么如何与项目组内其他同时共享这些配置信息呢?
.env.example
可以在项目根目录新建 .env.example
文件,写好所有环境变量的键值,然后可以写入假值或者键值的描述,在项目的 README.md
文件中进行说明如何获取设置环境变量的值。
例如:
// .env.example
APP_ENV=development
NODE_ENV=development
HOST=app.test.com
PORT=10086
GOOGLE_MAP_API_KEY=the-google-map-api-key
环境变量配置信息也可以保存在第三方的储存管理系统,例如 Vault 提供了对 Token,密码,证书,API key等的安全存储(key/value)和控制。
持久化配置
通过自建服务或者 Azure 开源的持久化配置服务,然后在服务器利用 SDK 来获取环境变量。
不过一般的云服务商都会打包这项服务,因为只有服务器和持久化配置服务都由一个供应商提供,供应商才能将持久化配置与服务器权限形成关联,让第三方服务器即便拿到 Token 也无法访问配置。
加密服务
如果项目的安全级别比较高,那么可以使用加密服务。
- 在加密平台注册,拿到密钥
- 在加密平台设置环境变量,加密平台会对内容进行加密
- 利用 Node SDK 获取到加密平台输出的密文
- 利用 SDK 和密钥解密成明文
最后
环境变量应该是存在于项目代码之外的,它只在项目运行时可用,这样使项目的配置与其代码脱离,从而使项目可以轻松地部署在不同的环境中。
对于以 Node.js
作为辅助开发的现代前端应用,可以通过process.env全局变量使用环境变量或者在运行node命令时设置环境变量,也可以使用 dotenv
。
最后一定要注意 .env
文件永远不应存在于源代码存储库中,加入代码的版本管理。
参考文章:
今天的文章【前端工程化】环境变量.env文件分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/13652.html