【问题标题】:how to access .env variables for Neo4j in Nestjs v8 app.module如何在 Nestjs v8 app.module 中访问 Neo4j 的 .env 变量
【发布时间】:2022-01-25 07:14:39
【问题描述】:

我有一个看似常见的问题,却没有一个共同的解决方案。我试图在导入 Neo4jModule 时从我的 Nestjs app.module 访问我的 .env 数据。如果我使用硬编码值,一切正常,但 process.env 或 configService 似乎都没有得到这些值。我似乎有很多这个问题的例子,但显然答案非常难以捉摸。我尝试了以下答案变体,但没有一个有效。我知道我们在初始化过程中有点早,但我不知道如何延迟请求直到初始化完成。

---->app.module
........
 import configuration from './config/configuration';
 import { Neo4jConfig, Neo4jModule } from 'nest-neo4j'
 import { ConfigModule, ConfigService } from '@nestjs/config';


 @Module({
     imports: [DbServerModule,
               ConfigModule.forRoot({
                 load: [configuration],
                 isGlobal: true
               }),
               Neo4jModule.forRootAsync({
                 imports: [ConfigModule],
                 useFactory: async (configService: ConfigService) => ({
                   scheme: 'bolt',                                    
                   host: configService.get('NEO4J_HOST'),            
                   port: configService.get('NEO4J_PORT'),               
                   username: configService.get('NEO4J_USERNAME'),    
                   password: configService.get('NEO4J_PASSWORD'),               
              }),
    
             inject: [ConfigService],
           }),
          ],
     ........

OR
@Module({
  imports: [DbServerModule,
            ConfigModule.forRoot({
              load: [configuration],
              isGlobal: true
            }),
            Neo4jModule.forRoot({
                scheme: 'bolt',                                   // 
                process.env.NEO4J_SCHEME, 
                host: process.env.NEO4J_HOST, 
                port: process.env.NEO4J_PORT,  
                username: process.env.NEO4J_USERNAME, 
                password: process.env.NEO4J_PASSWORD            
              }),

          ],

编辑………… 下面的代码显示我们可以访问 useFactory {} 块中的 .env 变量...console.log 记录了正确的 .env 值,但由于属性,Neo4j 连接仍然失败:

Neo4jModule.forRootAsync({
     inject: [ConfigService],
     useFactory: async (configService: ConfigService) => {         
     console.log(`USERNAME...
                .${configService.get('NEO4J_USERNAME')}`);
     return ({
              scheme: 'bolt',                                    
              host: configService.get('NEO4J_HOST'),            
              port: configService.get('NEO4J_PORT'),               
              username: configService.get('NEO4J_USERNAME'),    
              password: configService.get('NEO4J_PASSWORD'),               
            });
          },

我的生产部署将使用 Rancher 分配 env 变量,因此我将使用自定义配置文件..configuration.ts,我在 ConfigModule.forRoot 中加载。对此的任何帮助将不胜感激。

我需要向@adamCowley 致敬,感谢他在 Nest-neo4j 包装器上所做的工作。它消除了将 Nestjs 与 Neo4j 集成的许多复杂性......谢谢

编辑:每个请求: -config/configuration.ts

  .....
  NEO4J_SCHEME: process.env.NEO4J_SCHEME,       
    NEO4J_HOST: process.env.NEO4J_HOST,         
    NEO4J_USERNAME: process.env.NEO4J_USERNAME, 
    NEO4J_PASSWORD: process.env.NEO4J_PASSWORD, 
    NEO4J_PORT: process.env.NEO4J_PORT,
   ......

.env

........
NEO4J_SCHEME='bolt'
NEO4J_HOST='127.0.0.1',       
NEO4J_USERNAME='username'
NEO4J_PASSWORD='password'
NEO4J_PORT=7687
..........

  

【问题讨论】:

  • 感谢您提供配置文件,但更多关于 /configuration.ts 的内容可能会有所帮助。例如,这里的导出函数是什么,一个空的 lambda,你是否将结果包装在另一个对象中?为什么你只是返回完全相同的东西。您还可以尝试更清楚地了解您的HOST 变量,以及您想要设置它的位置和时间。我觉得它可能会在您的 configuration.ts 文件中使用 async-await 来解决,但在阅读您的编辑/评论后,我现在有点模糊。
  • 同时检查这是否适用于您的问题:nestjs ConfigModule.forRoot() asynchronuous
  • @YılmazDurmaz 也许我不清楚......让我再试一次。 Nestjs 使用 dotenv 从 .env 中收集值。我们也知道 Nestjs 然后通过 configuration.ts 文件和 ConfigService 使这些可用。这些似乎工作正常......这里没问题。当 app.module 尝试从 process.env 或 ConfigService 收集 .env 值时,就会出现问题。这是在 Neo4jModule.forRootAsync{.....useFactory: async(.....)} 中完成的。其中应返回五个值(SCHEME、HOST、USERNAME、PASSWORD 和 PORT)。除了 HOST,所有都可以使用 process.env 或 ConfigService 传递。
  • 好的,现在它变得更奇怪了。我以为你是从其他适合异步/等待的地方获取主机。现在你说一切都在同一个地方,只有 HOST 似乎不起作用。您是否检查了日志以了解有关格式问题的任何错误消息?

标签: node.js neo4j nestjs


【解决方案1】:

如果我正确理解了您的问题,您正在尝试访问包含在 .env 文件中的环境变量。这可以通过在src/main.ts 中使用dotenv 来实现:

import dotenv from 'dotenv'
dotenv.config()

添加这些行后,您可以像在问题中那样访问环境变量:process.env.SOME_VARIABLE

【讨论】:

  • 不仅可以访问 .env 变量,还可以将它们分配给 Neo4j 属性。我知道使用 dotenv 和其他选项,但似乎没有一个使变量可用于这些属性。我已编辑问题以显示更清晰。
  • 显然问题出在 neo4jmodule 对主机的解释中:。如果只有这个变量是硬编码的,那么一切正常......不知道为什么!
  • HINT The @nestjs/config package internally uses dotenv. nestjs config
  • @YılmazDurmaz 这我知道。问题似乎不是 config/dotenv 问题,而是执行 nest-neo4j 包装器的问题
【解决方案2】:

检查nestjs-neo4j-realworld-example,你的问题可能是useFactoryasync引起的。

如果Neo4jModule 触发useFactory 方法但没有await 进行返回,那么您仍然会在控制台中看到日志,但在此之前将使用空配置调用Neo4j。

试试这个改变

from:
useFactory: async (configService: ConfigService){}
----
to:
useFactory: (configService: ConfigService): Neo4jConfig{}

如果这不能解决您的问题,请编辑您的帖子并为这 4 个变量提供您的 ./config/configuration 文件的精简版本以及您的配置文件。


编辑: 感谢您添加配置内容。我已经将它们与我的配置进行了比较。如果你复制/粘贴你的材料,你的只是一个错字问题。您在 HOST 的行尾忘记了尾随逗号。

除了类型之外,.env 文件基本上被解析成 = 之前和之后两部分的数组,就像写的一样。因为它们首先被读取为字符串,所以不需要引号。还有一些图书馆可能会从引号中略读第二部分,但大多数不会,在我看来,省略它们会更安全。

NEO4J_SCHEME=bolt
NEO4J_HOST=127.0.0.1
NEO4J_USERNAME=username
NEO4J_PASSWORD=password
NEO4J_PORT=7687

PS:从您的评论回复中,我推断所有内容都在同一个地方,除了 HOST 之外的所有内容都可以正常工作,因此此编辑应该会有所帮助。如果没有,请编辑您的帖子以反映我们在 cmets 中的讨论,以便下一个人可以比我更清楚地看到问题并提供帮助。

【讨论】:

  • 感谢您的建议....但是没有用。要清楚,只有 HOST 参数必须在 APP.MODULE 中硬编码才能工作。其他参数...PORT、USERNAME、SCHEME 和 PASSWORD 都正确地接收来自 process.env 的值。所以它不应该是一个异步问题。
  • 你能多介绍一下它们吗?哪些必须在“.env”中,哪些在源代码中硬编码,哪些既不应该硬编码也不应该在“.env”中,而是动态读取。因为我现在对你的目标感到困惑。
  • @MichaelE,请检查答案的编辑。我希望它能解决问题。如果没有,我希望/希望其他人提供答案。
  • 尤里卡!!有用!!实际上,我必须删除拼写错误和引号才能使其正常工作......非常感谢......谢谢
  • @MichaelE,很高兴听到问题已解决。这些小问题对每个人都很有用,一旦解决,它们就会成为成为更好程序员的垫脚石。但我有一个以前没有遇到过的小问题。当赏金结束时,我得到 50 分,但同时,你的接受连同它的 15 分被删除。有什么想法吗?
猜你喜欢
  • 2021-02-11
  • 2020-01-20
  • 2016-06-11
  • 2021-08-07
  • 2021-01-03
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
  • 2017-09-22
相关资源
最近更新 更多