node dotenv无效

时间:2014-11-17 13:10:56

标签: node.js environment-variables

我正在尝试使用节点dotenv模块,它不适合我。我在config / config.js上有一个文件,其中包含以下内容:

'use strict';

var dotenv = require('dotenv');
dotenv.load();
console.log('config');

我的app文件夹的根目录下也有一个名为.env的文件。我也有像TWILIO_ACCOUNT_SID这样的环境变量。这是我尝试在某个函数中使用环境变量时经历的过程:

Omes-MacBook-Pro:sidetime ome$ node
> require('./config/config.js');
config
{}
> process.env.TWILIO_ACCOUNT_SID
undefined

我在.env文件中定义了TWILIO_ACCOUNT_SID,但是当我尝试在控制台上输出值时,我得到的错误是未定义的。如果您对如何解决此问题有任何建议,我将非常感激。

35 个答案:

答案 0 :(得分:36)

就我而言,每次尝试使用process.env.MY_KEY获取密钥表单.env文件时,都会返回undefined

因为我将文件命名为keys.env而不是.env文件

,因此我遇到了这个问题两个小时

所以这里是troubleshooting list

  1. 确保文件名为“。env”(我认为“。env.test”是可以接受的)

  2. 使用此声明确保您在申请中要求As early as possible require('dotenv').config();

  3. 确保.env文件为in the root directory of your project

  4. 确保您关注的是file writing rules DB_HOST=localhost,因为无需将它们包装成双引号或单引号
  5. 还要查看npm网站https://www.npmjs.com/package/dotenv

    上的软件包文档

    希望这可以节省您的时间

答案 1 :(得分:24)

我解决了使用

require('dotenv').config({path: __dirname + '/.env'})

或使用路径绝对:

C:\\asd\\auhsd\\.env

如果他找不到 .env 文件,则会离开未定义

答案 2 :(得分:7)

我没有像dotenv模块文档那样将环境变量放在正确的格式中,例如我正在导出TWILIO_CALLER_ID =“+ wwehehe”,所以dotenv模块没有正确解析我的文件。当我注意到我从声明中删除了export关键字,一切正常。

答案 3 :(得分:7)

最近有同样的问题。 请检查.env文件并执行以下操作:

key=value

而不是

key:value

答案 4 :(得分:5)

确保尚未设置变量。 Dotenv won't override them.

如果设置了变量,则必须将其删除。在powershell中,您可以使用以下命令-as mentioned here

Remove-Item Env:\MyTestVariable

答案 5 :(得分:5)

为您节省一些故障排除时间并记录您的要求电话,如下所示:

console.log(require('dotenv').config())

您应该会看到一个错误,其中包含有关该问题的更多详细信息。

答案 6 :(得分:4)

请注意,您还要从 ROOT 文件夹中执行节点脚本。

E.g。我在名为./bin/test.js的子文件夹中使用了测试脚本。 把它称为:node ./bin/test.js完全正常。 从子文件夹中调用它,如:

$ pwd
./bin
$ node ./test.js

导致dotenv找不到我的./.env文件。

答案 7 :(得分:4)

我遇到了同样的问题,我试了4个小时才发现错误。就我而言,这很奇怪。

当我尝试“node app.js”时,它有效。当我想要一个守护进程启动它时,它不起作用。

我是如何解决我的问题的? 我换了:

var dotenv = require('dotenv');
dotenv.load();

使用:

var dotenv = require('dotenv').config({path: path.join(__dirname, '.env')})

答案 8 :(得分:4)

确保将pm2配置中的cwd设置为对dotenv.config()的任何调用的正确目录。

实施例: 你的index.js文件在/ app / src中,你的.env文件在/ app中。你的index.js文件有这个

dotenv.config({path:“../。env”});

你的pm2 json配置应该有: “cwd”:“/ app / src”,“script”:“index.js”

你也可以使用dotenv.config({path:path.join(__ dirname,“.. /。env”)});避免CWD问题。如果将.env或index.js文件相对于彼此移动,则仍会出现问题。

答案 9 :(得分:4)

工作解决方案:

如果您正在使用webpack(肯定应该这样做),请使用非常方便的插件dotenv-webpack,该插件可以解决从.env文件读取环境变量的问题

确保.env在项目的根目录中。

安装插件的步骤:

  1. npm i -D dotenv-webpack
  2. webpack.config文件中:
     const Dotenv = require('dotenv-webpack');
     module.exports = {
          ...
          plugins: [
                new Dotenv(),
                ...
          ],
          ...
     };

现在您可以使用任何.env文件中的process.env调用js文件中定义的任何环境变量

答案 10 :(得分:4)

我使用的代码结构如下所示

-.env
-app.js
-build
-src
   |-modules
        |-users
            |-controller
                  |-userController.js

我的app.js顶部需要.env

require('dotenv').config();
import express = require('express');
import bodyParser from 'body-parser';
import mongoose = require('mongoose');

process.env.PORT在我的app.listen函数中起作用。但是,在我的userController文件上,不确定这是怎么发生的,但是我的问题是,当我使用console.log()检查时,我正在获取secretKey值并以字符串形式输入,但是在jwt.sign()例如上尝试时却未定义

console.log('Type: '+ process.env.ACCESS_TOKEN_SECRET)
console.log(process.env.ACCESS_TOKEN_SECRET)

结果:

string
secret

jwt.sign给出错误

let accessToken = jwt.sign(userObj, process.env.ACCESS_TOKEN_SECRET); //not working 

错误是

    Argument of type 'string | undefined' is not assignable to parameter of type 'Secret'.
  Type 'undefined' is not assignable to type 'Secret'.

我的解决方案: 阅读文档后。我再次需要在文件中添加env(我可能应该首先拥有它)并将其保存到变量'environment'

let environment = require('dotenv').config();

控制台日志记录环境可以提供:

{
parsed: {
    DB_HOST: 'localhost',
    DB_USER: 'root',
    DB_PASS: 'pass',
    PORT: '3000',
    ACCESS_TOKEN_SECRET: 'secretKey',
  }
}

在jwt.sign上使用它不起作用

let accessToken = jwt.sign(userObj, environment.parsed.ACCESS_TOKEN_SECRET);

希望这会有所帮助,我被困了几个小时。请随时在我的答案中添加任何内容,这可能有助于进一步解释。

答案 11 :(得分:3)

我正在Windows 10上使用NodeJS。我使用 process.env.var-name 来访问变量,但失败了,因为它为我提供了Windows路径变量作为JSON对象 >,所以我安装了dotenv(npm install dotenv)。 dotenv 从您的项目的.evn文件

中获取过程环境变量
  1. npm install dotenv或yarn add dotenv

enter image description here

  1. const dotenv = require('dotenv'); dotenv.config();

enter image description here

  1. process.env.variable_name

enter image description here enter image description here

  1. 输出

enter image description here

答案 12 :(得分:3)

我有同样的问题。我意识到我的文件以某种方式编码在use Illuminate\Database\Eloquent\ModelNotFoundException;中。将我的UCS-2 BE BOM文件转换为.env可以解决该问题(例如,您可以使用Notepad ++轻松完成此操作)。

答案 13 :(得分:3)

对于使用create-react-app模板创建的React应用,您无需直接使用dotenvreact-scripts为您做到了。

只需在项目的顶级目录中创建一个.env文件,然后在其中添加所有环境,但是请注意,它们必须REACT_APP开头,否则将被忽略。

更多详细信息in their documentation。我花了几个小时来处理这个问题,希望它可以为您节省一些时间。

答案 14 :(得分:2)

我的问题很愚蠢。我在文本编辑器中创建了.env,当我保存它时,实际上保存为

'.env.txt' 

只有在我做了

之后才能看到
'ls -a'
终端中的

并看到了文件名。

快点:

mv .env.txt .env

我在做生意

答案 15 :(得分:2)

“。env”文件应位于节点js服务器文件的根目录(server.js或对我而言)。

如果将“ .env”文件放在项目的根目录下,它将无法正常工作。我的错误是我将server.js文件嵌套在名为“ controller”的文件夹中。

所以我不得不通过将.env文件放置在与server.js文件相同的目录中来对其进行修复。

答案 16 :(得分:1)

我有同样的问题。我创建了一个名为.env的文件,但实际上该文件最终是.env.txt。

我创建了一个新文件,并将其保存为“无扩展名”并且繁荣起来,该文件是真实的.env文件,并且运行良好。

答案 17 :(得分:1)

.env变量未加载且为undefined时,我也遇到了问题。

我尝试过的事情:

index.js:

import dotenv from 'dotenv';
dotenv.config();
import models from './models';

models.js

import Sequelize from 'sequelize';
const sequelize = new Sequelize(
    process.env.DATABASE,
    process.env.DATABASE_USER,
    process.env.DATABASE_PASSWORD,
    {
        dialect: 'postgres',
    }
);

显然,由于在nodejs中加载导入的工作方式,index.js中的模型导入会导致models.js在dotenv.config()之前执行。因此,我从process.env中获得了未定义的值。

当我更改models.js以进行dotenv配置时:

import Sequelize from 'sequelize';
import dotenv from 'dotenv';
dotenv.config();
const sequelize = new Sequelize(
    process.env.DATABASE,
    process.env.DATABASE_USER,
    process.env.DATABASE_PASSWORD,
    {
        dialect: 'postgres',
    }
);

开始工作!

答案 18 :(得分:1)

这是我解决问题的方式

最初是在我项目根目录的.env中

const db_port = 90101
const db_host="localhost"
const db_username="name"
const db_password="pwd"
const db_name="db"

我所有的env变量都未定义。

我通过删除所有const并仅使用插入的key = value来修复它 const key =“ value”

db_port = 90101
db_host=localhost
db_username=name
db_password=pws
db_name=db

答案 19 :(得分:1)

有同样的问题。我使用了dotenv-webpack,需要定义

plugins: [
  new Dotenv()
]
两者 Webpack生产和Webpack基本文件中(我使用Webpack合并)。 如果两个文件中都未定义,则无法正常工作。

答案 20 :(得分:1)

您的项目中是否安装了dotenv?

尝试在项目中使用npm install dotenv安装它。

安装完成后,请使用const env = require('dotenv').config()将其加载到需要的任何文件中。

然后您可以在需要的任何行中使用。例如,从.env呼叫端口,请使用:process.env.PORT

答案 21 :(得分:1)

如果您使用“ firebase-functions”托管服务器端渲染的应用程序,则应注意以下内容:

错误:错误:ENOENT:没有这样的文件或目录,打开'C:\ Codes \ url_shortener \ functions \ .env'

意味着您还必须将.env文件存储在functions文件夹中。

通过以下方式找到了这个人

console.log(require('dotenv').config())

答案 22 :(得分:1)

我从Github克隆了一个仓库,并仔细阅读了这里的所有建议。经过很多挫败之后,我意识到changeList(e){ this.setState({ currentInput: e.target.value }) } 没有安装任何模块,而我的npm install文件夹一直都是空的。

快速修复:
1)删除您的node_modules文件夹
2)删除您的node_modules
3)运行package-lock.json

答案 23 :(得分:1)

1) query a (get list of items for project dropdown)
2) call create_a function (create project dropdown, trigger subproject process)
3) query b (get list of items for subproject dropdown)
4) call create_b function (create subproject dropdown)
5) select an option from projects dropdown (triggers subprojects query and subrprojects dropdown)
6) select and option from subprojects dropdown (triggers subprojects on(change) event)

答案 24 :(得分:0)

我自己在这里发现了一些东西。

我已经正确定义了.env,等等,并且在那里定义了DATABASE_URL,但是尽管这样做了,但还是引用了另一个DATABASE_URL,如果存在的话,是否引用了全局环境变量?

无论如何,我发现当我在TEST中定义CONNECTION_STRING.env时,都正确引用了DATABASE_URL,而autoprefixer仍然没有被引用。

谢谢

迈克尔

答案 25 :(得分:0)

关于此主题和这些答案有很多困惑。我并不惊讶,没有一个答案被接受。希望如此。

The answer by Basheer确实解决了大多数问题。但是,您仍然需要了解几件事。尤其是,如果您像我一样来自前端背景,并且想为前端添加秘密,那么。可能与应用程序中某些服务器端渲染(SSR)逻辑的引入有关。

作为前端开发人员,您很可能已经在前端应用程序的webpack设置中看到此代码,以解决此问题。

/* Custom webpack properties. */
const dotenv = require('dotenv-webpack');

module.exports = {
  plugins: [
    new dotenv(), // Handle environemntal variables on localhost, but on the Server-Side Rendering (SSR). There's no access to "process.env" on the browser.
  ],
};

现在,如果.env文件位于项目的根目录中,并且在整个应用程序的服务器(SSR)上进行渲染,则效果很好。 但是,如果您有一些与服务器相关的自定义设置,则可能无法正常工作。这种情况的一个示例是Angular UniversalNuxt.js的处理{{1} }放在您的require('dotenv').config()中,使您生活愉快。这是由于next.config.jsAngular在处理SSR的方式上存在差异。要从Vue.js获得Angular Universal应用程序只是1个命令,但是SSR应用程序的组织性却不如Angular。从Nuxt.js生成Nuxt.js应用程序需要付出一定的代价,由于Vue.js和{之间的某些差异,您基本上必须生成一个新的Nuxt.js项目并复制文件{1}}设置。不知道Nuxt.js / Vue.jsReact / Next.js如何解决这个问题,但是如果与Svelte类似,那么您也可以考虑进一步阅读。

现在,您在名为 server 的单独文件夹中具有与服务器相关的逻辑,并且可以说该文件名为Sapper。也许除了该文件中的SSR外,您还可以具有发送邮件(Angular?)逻辑。然后,您想使用main.ts,但即使您已在nodemailer中定义了逻辑,显然也无法使用。那就是需要process.env的地方,即使您使用不同的导入语法(例如webpack),require('dotenv').config();也可以那样工作。不要感到困惑。只要import { Express } from 'express';位于应用程序的根目录中(不要与require('dotenv').config();文件夹混淆),并且变量在该文件中具有正确的语法,例如

.env

可以。

最后一种情况,在SSR应用程序中,您意识到要托管此应用程序,您需要使用无服务器/云功能/ FaaS。在这里,我只知道server的情况。在您的项目中,要部署这样的应用程序,在本示例中,您可能具有MAIL_ACCOUNT=mymail@mydomain.com MAIL_HOST=smtp.mydomain.com MAIL_PORT=587 文件夹,将从该文件夹将SSR应用程序部署到Firebase。出乎意料的是,部署邮件无法正常工作,经过数小时弄清楚日志中正在发生的事情,您可以看到functions。原因是as of today the CLI cannot merge files from other locations and indeed the .env file has to be manually copied to the functions folder。将Cloud Functions for Firebase文件复制/粘贴到process.env.VARIABLE_NAME returning undefined并进行部署后,它将可以使用。

可用于调试的是其中之一:

.env

但是,请谨慎对待您的秘密,因为这些秘密将在完成functions设置后显示出来。尝试访问其中一个机密并将其值记录在日志中可能是更安全的选择。尤其是,如果您有很多秘密并且不想全部重写。

希望如此,这篇文章将涵盖大多数情况。

答案 26 :(得分:0)

就我而言,我正在创建一个 vscode 扩展,其中 __dirname 指的是诸如 d:\extension\my_extension\out 之类的东西。

根文件夹是 my_extension,但 __dirname 指向 my_extension\out

所以我通过写作修复了它

require('dotenv').config({path: __dirname.slice(0,-3)+'/.env'});

答案 27 :(得分:0)

我遇到了类似的问题。我通过修剪解决了它。请检查,path.resolve 可能会在路径末尾添加额外的空间。

var path = require('path');
const envPath = path.resolve(process.cwd()+'/config','.env.'+process.env.NODE_ENV).trim()
require('dotenv').config({ path: envPath })

我的包脚本是这样使用多个.env的:

 "scripts": {
    "start": "set NODE_ENV=development && nodemon ./bin/www",
    "prod": "set NODE_ENV=production && node ./bin/www"
  },

答案 28 :(得分:0)

就我而言,在我的 MacBook Pro 上读取我的 .env 文件的相同代码库没有读取我的临时服务器 ubuntu 18.04 上的 .env 文件,所以我尝试了 @user3006381 建议,我注意到代码正在尝试查看对于我的用户目录“/home/myusername/.env”中的 .env 文件,而不是“/home/myusername/project/.env”, 如果您知道为什么会发生这种情况,请添加评论。

答案 29 :(得分:0)

在某些操作系统上(大多数是Linux发行版,我正在用raspbian看着您),. env文件不起作用。重命名它们并导入

答案 30 :(得分:0)

我花了很多时间进行这些修复。我在本地进行开发,由于.env文件没有被热重新加载,因此只需要重新启动服务器即可。

答案 31 :(得分:0)

如果您遇到此问题,则可能是在需要特定变量的文件之后添加/加载了环境变量

const express = require('express');

const app = express();
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const morgan = require('morgan');

const passport = require('passport'); //you want to use process.env.JWT_SECRET (you will get undefined)

dotenv.config();

在上述情况下,您将获得undefined的{​​{1}}

因此解决方案是将process.env.JWT_SECRET放在dotenv.config()之前

const passport = require('passport');

答案 32 :(得分:0)

我解决了这个问题,只是将文件重命名为.env y文件名为config.env,当我重命名为.env时,它可以工作。

答案 33 :(得分:0)

.env文件实际上不需要使用任何名称,只有.env扩展名并保存该文件即可。

答案 34 :(得分:0)

就我而言,我创建了一个包装器JS文件,在其中,我可以根据自己的环境动态选择正确的变量。

我有这两个函数,一个是简单的dotenv功能的包装,另一个是区分环境并将结果设置为process.env对象。

setEnvVariablesByEnvironment : ()=>{
		return new Promise((resolve)=>{

			if (process.env.NODE_ENV === undefined || process.env.NODE_ENV ==='development'){
				logger.info('Lower / Development environment was detected');

				environmentManager.getEnvironmentFromEnvFile()
					.then(envFile => {
						resolve(envFile);
					});

			}else{
				logger.warn('Production or Stage environment was detected.');
				resolve({
					payload: process.env,
					flag: true,
					status: 0,
					log: 'Returned environment variables placed in .env file.'
				});
			}


		});
	} ,

	/*
	Get environment variables from .env file, using dotEnv npm module.
	 */
	getEnvironmentFromEnvFile: () => {
		return new Promise((resolve)=>{
			logger.info('Trying to get configuration of environment variables from .env file');

			env.config({
				debug: (process.env.NODE_ENV === undefined || process.env.NODE_ENV === 'development')
			});

			resolve({
				payload: process.env,
				flag: true,
				status: 0,
				log: 'Returned environment variables placed in .env file.'
			});
		});
	},

因此,在我的server.js文件中,我仅添加了引用:

const envManager = require('./lib/application/config/environment/environment-manager');

在我的入口点(server.js)中,使用起来很简单。

envManager.setEnvVariablesByEnvironment()
.then(envVariables=>{
    process.env= envVariables.payload;

    const port = process.env.PORT_EXPOSE;
    microService.listen(port, '0.0.0.0' , () =>{

        let welcomeMessage = `Micro Service started at ${Date.now()}`;
        logger.info(welcomeMessage);

        logger.info(`${configuration.about.name} port configured  -> : ${port}`);
        logger.info(`App Author: ${configuration.about.owner}`);
        logger.info(`App Version: ${configuration.about.version}`);
        logger.info(`Created by: ${configuration.about.author}`);

    });
});