【前端工程化】环境变量.env文件

前奏曲

在现代前端项目中.env文件随处可见,里面都是一些项目中的配置项,能够在项目中拿来就用,虽然这是一个不太起眼的东西,可是这些.env文件在前端工程化中是有必定的用处和意义的。javascript

就让咱们经过这篇短文一块儿来看看。前端

process.env

如今的前端项目都是用 Node 来做为辅助开发工具,而 processNode.js 中的 一个全局变量,提供来有关当前 Node.js 进程的信息并对其进行控制。而 process 中的 env 则是返回包含用户环境的对象。java

通俗点说,就是能够经过 process.env 拿到当前项目运行环境的信息。node

Mac下的基本环境信息:git

// index.js
console.log(Object.keys(process.env));
复制代码

mac环境

设置环境变量

一、命令行

当须要在环境变量中加入自定义的一些配置,能够直接经过命令行的方式来进行设置:github

console.log(process.env.PROT)
复制代码
PROT=10086 node index.js
复制代码

此时项目运行的环境变量中就有了 PROT数据库

若是须要自定义其余变量,能够以键值的方式继续添加参数:npm

PROT=10086 NDOE_DEV=development node index.js
复制代码

这样的方式虽然很简单,可是也有不少缺陷:前端工程化

  • 可阅读性低:不能很直观的看到环境变量的配置(辣眼睛)
  • 容易输入错误:若是不仅是端口号,还有数据库信息、应用密钥等等,所有键入一行(手动狗头)
  • 难以管理:如何记住或者管理全部的环境变量及其值(手动狗头)

因此就有了下面一种方式。api

二、.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模块中。

这就是手动的方式,那么有自动收集方式吗?

固然有!

自动整理

前面提到的第三方 NPMdotenv 就能够作到。

// 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 运行时的依赖,而后又保留它的特性呢?

一、在安装 dotenv 的时候,安装为开发(dev)依赖,删除 dotenv 全部相关代码。

二、而后使用 -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 文件永远不该存在于源代码存储库中,加入代码的版本管理。

参考文章:

相关文章
相关标签/搜索