Node进程环境变量process.env.VARIABLE_NAME返回undefined。

68
我在我的Mac上使用环境变量来存储一些敏感的凭证,并尝试通过Node访问它们。我用以下方式将它们添加到我的环境配置文件中: export VARIABLE_NAME=mySensitiveInfo 当我使用echo $VARIABLE_NAME时,我会收到正确的输出(我的敏感信息)。
然而,当我试图在Node中访问同一变量并尝试在控制台上打印它时,我得到一个未定义的结果。尽管其他环境变量看起来都可以正常使用。例如,当我执行console.log(process.env.FACEBOOK_CALLBACK_URL)时,它会将正确的值打印到我的控制台上。我几天前添加了FACEBOOK_CALLBACK_URL
我需要重新启动机器吗?在Node中环境变量变为可用之前需要一定的时间吗?我在SO上看到的最接近的答案是这篇帖子,但没有人能够弄清楚为什么会发生这种情况。

环境配置文件是什么?.bash_profile是什么? - shaochuancs
你是如何运行Node程序的? - Jeremy Rodi
@JeremyRodi 我正在使用Visual Studio Code,并使用nodemonnode app.js来启动我的程序。 - Yu Chen
@shaochuancs 我实际上在.bash_profile不起作用后添加了.profile.bash_profile两个文件。所以现在我两个都有。 - Yu Chen
10个回答

59

nodemon.json文件仅用于设置nodemon特定的配置,因此要创建自定义环境变量,我们可以使用dotenv包。

首先,安装dotenv包。

npm install dotenv --save

在此之后,在根目录下创建 .env 文件,并将环境变量包括在下面

MONGO_ATLAS_PW=xxxxx
JWT_KEY=secret

最后,在您的 app.js 文件中,在导入之后插入以下内容。

require('dotenv').config()

那么你可以像这样使用环境变量

process.env.MONGO_ATLAS_PW
process.env.JWT_KEY

3
这对我直接有效。谢谢。 - Heila Al-Mogren
2
请注意:OP所说的“在此之后在根目录下创建.env文件”是指您需要在与package.json相同的文件夹中创建.env文件。这对我很有效 :) - anurag1905
1
注意:在通过Discord发送.env文件时,“.”会被删除,留下一个“env”文件。确保以点号开头!此外,我不建议通过Discord发送。请尝试使用USB或其他安全方法。 - billy bud
1
这是最好的答案! - Pamela Sillah
非常感谢你的准确回答。简直太棒了,效果非常好。 - Aman Jha

50

process.env.VARIABLE_NAME返回undefined,因为Node.js执行环境还不知道新添加的VARIABLE_NAME。要解决此问题,需要重新启动Node.js执行环境(例如IDE)。

以下步骤可用于重现此问题:

  1. 打开WebStorm等IDE并编写一个简单的Node.js程序:console.log(process.env.VARIABLE_NAME)。它将按预期打印undefined,因为VARIABLE_NAME尚未定义。保持IDE运行状态,不要关闭它。
  2. 打开环境配置文件,例如.bash_profile,并在其中添加export VARIABLE_NAME=mySensitiveInfo
  3. 打开系统控制台并运行source .bash_profile,以便执行上述export语句。从现在开始,每当打开系统控制台时,VARIABLE_NAME环境变量都存在。
  4. 在系统控制台中执行步骤1中的Node.js程序,它将打印mySensitiveInfo
  5. 切换到IDE并执行Node.js程序,它将打印undefined
  6. 重新启动IDE并执行Node.js程序,这次它将打印mySensitiveInfo

1
只需取消运行 npm run watch 命令,然后再次运行 npm run watch 命令即可解决问题。 - UMAIR ALI
重新启动IDE解决了我的问题 - 谢谢! - Meowntain
1
如果变量只需要添加到本地终端进程中,该怎么办?如果我们重新启动IDE,那么变量将会丢失。 - gaurav5430
那么我认为变量可以在本地终端中定义。当IDE关闭(本地终端退出)时,该变量将消失。 - shaochuancs

20

对于未来可能遇到此问题且上述解决方案均无效的所有人,这也可能是因为您在子文件夹或子目录中运行node <filename>.js,而由于您的.env文件在根文件夹中,所以processs.env.<variable>始终返回未定义。

检查的一种简单方法是尝试以下代码

const test = require('dotenv').config()
console.log(test)

在控制台中,我们得到了以下错误
{   error: Error: ENOENT: no such file or directory, open 'C:\Users\vxcbv\Desktop\voisascript-auth\model\.env'
      at Object.openSync (node:fs:585:3)
      at Object.readFileSync (node:fs:453:35)
      at Object.config (C:\Users\vxcbv\Desktop\voisascript-auth\node_modules\dotenv\lib\main.js:72:42)
      at Object.<anonymous> (C:\Users\vxcbv\Desktop\voisascript-auth\model\db.js:1:32)
      at Module._compile (node:internal/modules/cjs/loader:1105:14)
      at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
      at Module.load (node:internal/modules/cjs/loader:981:32)
      at Function.Module._load (node:internal/modules/cjs/loader:822:12)
      at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
      at node:internal/main/run_main_module:17:47 {
    errno: -4058,
    syscall: 'open',
    code: 'ENOENT',
    path: 'C:\\Users\\vxcbv\\Desktop\\voisascript-auth\\model\\.env'   } }

强调: Error: ENOENT: no such file or directory, open。 要解决此问题,只需返回至根目录并在那里运行文件,但需要从根目录指定文件的完整路径,例如: node /<子文件夹>/<文件.js>


谢谢谢谢谢谢谢谢 - Jordan
太棒了! - tmurv
谢谢,我是从任务管理器中运行脚本解决了这个问题。 require('dotenv').config({path:'complete_path/.env'}) - ClearBoth
这是唯一有效的答案。注意! - undefined

5

对于任何陷入React困境的人。

这篇文章帮助我理解了React中的.env:

变量必须以“REACT_APP_”为前缀,否则变量将无法正常工作。

在您的.env文件中,它应该看起来像这样:

REACT_APP_YOUR_VARIABLE_NAME=SOMETHING

只返回翻译文本,不包括这个(我所拥有的并且未定义的):NOT

MY_VARIABLE_NAME=SOMETHING

谢谢!我有一个Vue应用程序,其中VUE_APP_SOMEVARIABLE变量被传递了,但其余部分被省略了。我完全忘记了VUE_APP_前缀的要求。 - Kevin Driessen

4
请检查.env文件的位置,如果在您的app.js或(abc.js)同一目录下,则将.env移到上一级目录。

2
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community
这正是我的问题。我将.env文件和服务器根文件放在同一个目录中。将.env文件移动到父目录中,问题解决了。谢谢! - Hard_Whey

4

我刚刚遇到了一个问题,使用以下Webpack配置解决了它:

const plugins = [
    new webpack.NoEmitOnErrorsPlugin(),
    // after compile global will defined `process.env` this Object
    new webpack.DefinePlugin({
      BUILD_AT : Date.now().toString(32),
      DEBUG: process.env.NODE_ENV !== 'production',
          'process.env': {
              'NODE_ENV': JSON.stringify(process.env.NODE_ENV || "development"),
              'VARIABLE_NAME': JSON.stringify(process.env.VARIABLE_NAME)
     }
   })
]

4

我遇到了同样的问题。在我的情况下,env文件和db.js都在一个名为configs的子文件夹中。

因此,在index/server.js中导入dotven时,我使用了以下代码:

require('dotenv').config({path: './configs/.env'});

这样我的环境变量就被访问了。
希望我的例子能帮到你!

1
关闭代码运行器或者IDE环境,然后重新打开。 如果你使用的是VS Code,请彻底地关闭它(或CMD或Power Shell等)。

0
在我的情况下,我忘了在文件名前加上一个点。花了我一些时间才弄清楚,因为很难发现。
文件名应该是"env.development",而不是".env.development"。

0
在使用dotenv.config()访问.env变量时,访问这些变量的函数在调用dotenv.config()之前被调用了。
之前 ❌
const dotenv = require('dotenv');
authController.insertAdmin();
dotenv.config();

完成后 ✅

const dotenv = require('dotenv');
dotenv.config();
authController.insertAdmin();

只需执行require("dotenv").config(),一次完成即可。 - bfontaine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接