您构建的 Node.js 应用程序首先要在计算机上运行。您知道,应用程序在任何须要运行的地方都能工做是很重要的。这多是在你同事的电脑、公司内部服务器、云服务器或容器内部(可能使用Docker)。输入环境变量.。node
使用环境变量的说明性指南git
环境变量是使用 Node.js 开发的一个基本部分,它容许您的应用程序根据您但愿它们运行的环境而表现出不一样的行为。不管您的应用程序在哪里须要配置,您均可以使用环境变量。它们很是简单,并且很是漂亮!这篇文章将向您介绍如何建立和使用环境变量。docker
这篇文章将引导您建立和使用环境变量,从而建立一个能够在任何地方运行的 Node.js 应用程序。数据库
人们常常问我,我是如何决定什么是学习和投入时间的,什么是听任自流的。对我来讲,这是从这两个相同的问题开始的(例如,问为何和什么时候)。我敢打赌,你也会作相似的事情,不是吗?npm
为何和何时?json
当有人告诉你某件事情很重要,你应该使用它时,我建议问两个简单的问题。api
如今是你问我为何要使用环境变量的时候了。去吧;不要紧。安全
若是您关心使您的应用程序在任何计算机或云上运行(也就是您的环境),那么您应该使用它们。为何?由于它们将您的应用程序的全部环境特定方面外部化,并保持您的应用程序封装。如今,您能够经过修改环境变量在任何地方运行您的应用程序,而无需更改您的代码,也无需从新构建它! **何时?服务器
好了,如今你问我何时应该使用它们。简而言之,你的代码中任何会根据环境而改变的地方。当你看到这些状况时,对任何你须要改变或配置的地方都要使用环境变量。编辑器
下面是一些你应该考虑使用环境变量的常见场景的具体例子。
*指向开发、暂存、测试或生产数据库。
其余的例子多是服务器资源的URL,测试与生产的CDN,甚至是在UI中经过你的应用所处的环境来标记你的应用。
让咱们来探讨一下如何在Node.js代码中使用环境变量。
您可能正在为 Express 服务器设置端口号。一般状况下,不一样环境(例如;暂存、测试、生产)中的端口可能须要根据策略进行更改,并避免与其余应用程序发生冲突。做为开发人员,你不该该关心这些,实际上,你也不须要关心。下面是如何在代码中使用环境变量来抓取端口。
// server.js const port = process.env.PORT console.log(`Your port is ${port}`);
试试这个。建立一个名为 "env-playground "的空文件夹。而后建立一个名为server.js
的文件,并将上面的代码添加到其中。如今,当你执行node server.js时,你应该看到一条消息说 "Your port is undefined"。
你的环境变量不在那里,由于咱们须要把它们传递进来。让咱们考虑一些能够解决这个问题的方法。
1.使用命令行
.env
文件。将 port 传入您的代码的最简单方法是在命令行中使用它。在命令行中指定变量的名称, 后面是等号, 而后是值。而后调用您的 Node.js 应用程序。
PORT=8626 node server.js
你会看到端口显示在这样的消息中:"你的端口是8626"。
_这个8626是什么东西?为何不是4200或者3000或者更传统的端口?好吧,我是迪斯尼的忠实粉丝,有一个叫史迪奇的角色也被称为实验626._。
你能够重复这个模式,也能够添加其余变量。下面是一个传递两个环境变量的例子。
PORT=8626 NODE_ENV=development node server.js。
按照环境变量名后加等号再加值的模式。这很容易作到,但也太容易犯输入错误了。这就有了下一个选项。
一旦你定义了其中的几个,你脑海中的下一个念头可能就是如何管理它们,使它们不会成为维护的噩梦。想象一下,数据库链接、端口和密钥都有好几个。当你把它们都打在一条线上时,这并不能很好地扩展。并且可能会有私人信息,如密钥、用户名、密码和其余秘密。
从命令行运行它们固然很方便。但它也有它的缺点。
2.从命令行打字太容易出错了。
3.要记住全部的变量和它们的值并不理想。
4.即便使用npm脚本,你仍然必须保持它们的最新性。
对于如何组织和维护环境变量,一个流行的解决方案是使用.env
文件。我真的很喜欢这种技术,由于它使我能够在一个地方快速读取和修改它们变得超级容易。
在你的应用程序的根目录下建立.env
文件,并将你的变量和值添加到其中。
NODE_ENV=development PORT=8626 _# 在这里设置你的数据库/API链接信息。 _API_KEY=************************** API_URL=**************************
.env
文件是一个很好的方法,能够在一个地方看到全部的环境变量。只要确保不要把它们放到源代码控制中。不然,你的历史记录将包含对你的秘密的引用。
建立一个.gitignore
文件(或者编辑现有的文件,若是你已经有了),并添加.env
到其中,以下图所示。.gitignore
文件会告诉源控制忽略你列出的文件(或文件模式)。
当心将.env添加到.gitignore文件中,并在添加你的_.env
_以前提交该更改。不然,你就有可能将你的.env
_的早期版本提交到源代码控制中。
您能够经过使用 Visual Studio Code (VS Code)中的命令调色板将一个文件添加到您的.gitignore
文件中。按照如下步骤进行。
.gitignore
的文件。CMD
+SHIFT
+P
打开命令调色板,在Windows上用CTRL
+SHIFT
+P
打开。.gitignore
"这将把你当前打开的文件名添加到.gitignore
文件中。若是你没有建立.gitignore
文件,它将为你建立!
将.env加入到.gitignore中。
若是你使用VS Code,你会想要添加dotenv扩展。这将为你的.env
文件的内容提供语法高亮,并使你更容易使用.env
文件中的变量。
下面是安装了dotenv扩展的VS Code中的文件。
.env文件在VS Code中具备语法高亮功能。
如今你可能在想,有些东西必须寻找.env
文件,你是对的!你能够本身写代码来寻找文件,解析,并将它们读到你的Node.js应用中。
你能够写你本身的代码来找到这个文件,解析它,而后把它们读到你的Node.js应用中。或者你也能够经过npm找到一种方便的方法,将变量一次性读到你的Node.js应用中。你极可能会遇到npm上的dotenv包,它是个人最爱,也是我推荐你使用的。你能够像这样npm install dotenv
来安装它。
而后你能够在你的项目中要求使用这个包,并使用它的config
函数(config也有一个load的别名,以防你在野外看到)来寻找.env
文件,读取你定义的变量,并将它们提供给你的应用程序。
按照如下步骤进行。
package.json
文件2.安装dotenv的npm包。
3.写代码读取.env
。
4.运行代码
你须要一个package.json文件来配置你的版本,跟踪你的依赖关系,并包含你的npm脚本。经过运行如下命令来实现
npm init -y
这将建立一个 "package.json "文件,其中包含基本设置。
你须要读取.env
文件,而npm上的dotenv包能够很好地完成这个任务。运行如下命令安装dotenv包
npm install dotenv
这将把dotenv包和它的文件添加到你的node_modules
文件夹中,并在package.json
文件中为dotenv建立一个条目。
是时候用一点代码读取.env
文件了。用下面的代码替换你的server.js
文件的内容。
// 服务器.js
console.log(Your port is ${process.env.PORT}
); _// undefined
_const dotenv = require('dotenv');
dotenv.config();
console.log(Your port is ${process.env.PORT}
); _// 8626_。
该代码显示了PORT
环境变量的初始值,该变量将是未定义的。而后,它须要dotenv软件包,并执行其config
函数,读取.env
文件并设置环境变量。最后一行代码显示 "PORT "为8626。
如今,使用如下命令,在不传递端口的状况下,在命令行中运行代码
node server.js
请注意控制台日志信息显示端口最初是未定义的,后来变成了8626。dotenv软件包读取并设置这些值,其实是为您作了肮脏的工做。
如今,咱们有了一个在.env
文件中建立变量的单一地方,咱们可能会考虑如何在Node.js代码中轻松检索全部这些变量。为何要这样作?这个问题问得好! 好吧,你能够在代码中使用如下语法来引用变量。
process.env.YOUR_ENV_VAR_GOES_HERE
。
可是,你是否想在你须要的地方都这样作(你可能在多个地方须要它们)?仍是应该把咱们全部的环境变量收集在一个地方? 固然是后者! 为何这么说呢? 若是你真的在全部须要的地方都引用变量,可能会比在一个地方引用变量更难重构和维护。
我建议建立一个模块,负责收集环境变量。这样能够很容易地一次性看到它们,并将它们映射到可读的名称上。
这里有两个不错的选择能够考虑。
2.使用一个库来读取并在一个模块中导出它们。
这两种技术都涉及建立一个模块,但它们在环境变量的映射和暴露方式上有所不一样。让咱们仔细看看这两种技术,并权衡一下它们的区别。
建立一个模块(下面的例子显示的是config.js
),在这个模块中,你能够收集变量,将它们映射为名称明确且可读的属性,并将它们导出。
让咱们在一个名为config.js
的文件中建立一个新模块。而后将如下代码复制并粘贴到文件中。
// config.js _const_ dotenv = require('dotenv'); dotenv.config(); module.exports = { endpoint: process.env.API_URL, masterKey: process.env.API_KEY, port: process.env.PORT };
这个例子展现了咱们如何将环境变量整合到一个文件中。
让咱们再次修改server.js
,此次是导入config.js模块并使用它来访问咱们的环境变量。用下面的代码替换server.js
的内容。
// server.js _const_ { port } = require('./config'); console.log(`Your port is ${port}`); _// 8626_
使用node server.js
运行代码,你会看到 "你的端口是8626 "的消息。环境变量正在被config.js
文件中的dotenv代码读取。你的server.js
文件导入config.js
中的模块并提取端口变量。
你能够把config.js
文件导入到你须要的地方,而后用destructuring来提取你须要的东西。你只调出了port,但你固然能够调出模块中导出的任何一个值。
const { endpoint, masterKey, port } = require(‘./config’);
这个技术有什么价值?
1.它很容易
2.明确全部环境变量的映射方式。
3.你能够将变量重命名为更易读的属性。
4.你能够从非环境变量中添加其余配置属性。
这里的关键点是,config模块的目的变成了收集和暴露全部的配置,无论它来自哪里。
手动技术的一个后果是,当你添加一个新的环境变量时,你必须把它添加到config模块中。例如,若是你须要制做一个新的变量,你须要进入这个配置模块,并添加这样的内容。
visionApiUrl=process.env.VISION_API_URL
我不介意这个后果,由于不管如何我都要经过个人代码来使用新的值。但我指出这一点是由于有一种方法能够自动收集它们。
dotenv npm包中的dotenv.config()
函数会读取.env
文件,将变量分配给process.env
,而后返回一个包含内容的对象(命名为parsed
),若是失败的话,它还会抛出一个错误。
下面的代码读取.env
文件,并收集envs
对象中的变量。
// 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 { endpoint, masterKey, port } = require(‘./config’);
你应该用哪一个方案?这由你本身决定。但请考虑是否要将npm包dotenv做为运行时依赖。也许在更高的环境(好比生产环境)中,还有其余的方法来获取环境变量,在这些环境中,安全是最重要的。你甚至但愿你的node应用中的代码可以读取如此重要的文件吗?你可能会以为很酷,但若是有一种方法能够读取变量,并在你的package.json
文件中把dotenv包变成一个devDependency呢?
我建议你使用第一种技术,即在模块中手动设置环境变量,好比config.js
。这容许你删除dotenv做为运行时的依赖--假设你还作了一件事:预加载环境变量。这也容许你减小你的运行时依赖性。
你有不少对npm包的依赖。当你计划你的应用程序的生命周期和维护时,每个都是你应该考虑的。你可能已经在考虑如何将你的依赖性减小到最低限度。我也是这样作的。
dotenv包是很棒的,但咱们不须要它成为运行时的依赖。dotenv包提供了一个选项,你能够在你的代码以外预加载变量。你能够加载变量,并从咱们的代码中删除读取.env
文件的代码。更少的代码就是更少的行数,可能会中断或被维护。
还不放心吗?您是否考虑过如何在云中访问这些环境变量?你但愿你的代码试图读取一个文件吗?我对此投了一个响亮的 "不"。我更但愿个人代码不要试图读取文件,由于若是我把它带到云端,我但愿这些解决方案甚至没有.env
文件。
如何从咱们的代码中删除dotenv的运行时依赖,但又不失去已经得到的价值?首先,在安装dotenv npm包的时候,你能够像这样把它保存为开发依赖关系。
npm install dotenv --save-dev。
而后删除全部在dotenv上使用require的代码,包括本文以前提到的dotenv.config()
代码。这包括本文前面提到的dotenv.config()
代码。
如今的问题是,你以前是依靠dotenv来加载环境变量的。这就是预加载选项发挥做用的地方。
你可使用- require
( -r
) 命令行选项来预加载dotenv来运行你的node应用。下面的命令将使用dotenv从文件.env中预载全部环境变量,并使它们在你的应用程序中可用。因此你如今已经从你的代码中删除了全部对dotenv的引用。
node -r dotenv/config server.js
当你想让你的应用运行在文件不存在(也许不该该存在)的地方时,这颇有用,好比在运行中的docker容器或云服务器中。能够从node -h内看到-r选项的说明:
-r, --require=... module to preload (option can be repeated)
我强烈建议把你的命令放到一个npm脚本中。这使得它更容易运行,而不是输入全部这些标志。也许你能够为它建立一个自定义脚本或者使用npm启动脚本。下面是你使用自定义脚本时脚本的样子。
scripts: { "start_local": "node -r dotenv/config server.js" }
命令npm run start_local
就会启动这个命令。固然,你能够随意命名这个脚本。
为何不使用npm start
?问得好,你固然能够这样作。你固然能够这样作。我喜欢把npm start
保留给我在没有docker容器的状况下如何在生产中运行它,这可能只是像这样。
scripts: { "start": "node server.js" }
这里的关键是,不管使用哪一种npm脚本,你都在运行彻底相同的node代码!区别在于你的变量如何设置。区别在于如何设置你的变量。你如今已经从你的应用程序中抽象出了你的配置。
如何记住全部的npm脚本?这很简单 - 你不须要!我依靠伟大的工具来帮助运行个人npm脚本。虽然我喜欢伪装我知道全部的脚本名称和它们的具体做用,但事实上,我更但愿有一个工具能够显示出列表,我能够选择它。
在我选择的代码编辑器中,有两个很棒的工具能够作到这一点。VS Code。
1.npm的脚本大纲
npm脚本大纲是内置在VS Code中的,并显示在资源管理器视图中。请注意下面的截图显示了个人package.json文件中的npm脚本,若是你在你的项目中没有看到这个,请确保将npm.enableScriptExplorer
设置为true。若是你在你的项目中没有看到这个,请确保在VS Code的settings.json
中把npm.enableScriptExplorer
设置为true。
你能够右键点击一个npm脚本,而后打开、运行或调试它。
若是你像我同样喜欢用手敲键盘,那么你可能更喜欢VS Code的npm扩展。在安装了VS Code的npm扩展以后,你就能够在命令板上运行npm脚本了,在Mac上只要输入CMD
+SHIFT
+P
就能够了。
只要在Mac上输入CMD
+SHIFT
+P
,或者在Windows上输入CTRL
+SHIFT
+P
。而后开始输入npm
,选择 "npm: 运行脚本",以下图所示。
而后你会看到一个npm脚本的列表。从这里开始,你能够开始输入你想要的脚本的名字,直到你想要的脚本被高亮显示。或者你使用箭头选择你想要的脚本。而后按 "ENTER "来运行它。
我喜欢这样,由于它让个人手放在键盘上,这感受比在鼠标/触控板和键盘之间切换更有效率。
给一个这样的尝试。
你的应用程序没有意识到环境变量的来源。您运行它的方式,即预加载,是在您的本地机器上提供它们。
让咱们进一步探讨为何你可能但愿你的应用程序对其配置没有意识。
想象一下,咱们正在一个Docker容器中运行。容器的传统指导说,容器内的应用不该该知道它们的配置。这样一来,只要容器和运行容器的任何东西就必须提供哪些变量达成协议,容器就能够在任何地方运行。
当你把咱们的应用带到云端时,各类云提供商也都有办法让你设置环境变量。所以,再次强调,若是应用程序仅仅使用变量,而运行它的东西(在这种状况下,云提供商的服务)为您提供了定义这些变量的方法,您就能够了。
你的队友如何知道要为你的应用建立哪些环境变量?他们应该在你的代码中搜索这些变量吗?他们应该打电话问你吗?固然不是,你没有时间亲自去拜访每个开发者!
当你的.env
文件没有被推送到源码控制中时(这是不该该的),重要的是要让你们清楚这个文件的形状应该是什么样的。我推荐的技术是建立一个名为.env.example
的文件,其中包含变量,但使用假值。这个文件可能看起来像下面的模板。
NODE_ENV=开发
PORT=8626
# 在这里设置你的数据库链接信息 API_KEY=your-core-api-key-goes-here
你的团队能够把这个文件的内容复制到他们本身的.env文件中,而后输入他们须要的值。在示例文件中列出非机密的值是彻底正常的。注意到.env.example文件中的PORT
和NODE_ENV
都被设置了,但API_KEY
没有被设置。明智地选择你推送到源代码控制的内容。
而后,你能够在你的README.md
中引用这个文件,你的队友能够很快学会如何设置本身的值。问题解决了。
这只是对如何使用环境变量以及一些可使用环境变量的神奇工具的一瞥。总的来讲,我建议你使用环境变量,并遵循如下步骤。
.env
文件2.在你的.gitignore
文件中忽略它。
3.使用VS Code来编辑你的.env
文件。
4.安装VS Code的dotenv扩展
5.安装VS Code的npm扩展
6.读取dotenv npm包中的.env
文件做为开发依赖。
7.使用dotenv的预加载选项来删除对它的任何运行时引用。
8.使用npm脚原本运行你的node应用。
9.为你的变量建立一个名为.env.example
的模板文件。
若是你喜欢我使用的字体和主题,它们是Dank Mono和Winter is Coming (Blue)。你能够找到 这里的Dank Mono字体 并安装 这里的Winter is Coming主题_。我最后一次检查时,字体的价格是40英镑,而主题是免费的_。
可是等一下,你想让你的服务器有一个免费的字体吗?你但愿你的服务器有一个.env
文件吗?你使用Docker或云服务器吗?这些都是要问本身的好问题。你在这里学到的方法是一个基础,能够与其余解决方案协同工做。我很快会在将来的文章中深刻探讨这个问题,敬请期待。