【问题标题】:Dynamic import based on environment variable基于环境变量的动态导入
【发布时间】:2021-12-25 10:42:41
【问题描述】:

在一个项目中,我有一个环境变量,应该用于指定我们是否要使用 HTTPS:

SSL_ENABLED=1

基于这个环境变量,我现在尝试使用 https 或 http 模块:

import * as http from parseInt(process.env.SSL_ENABLED || '', 10) ? 'https' : 'http'

const server = http.createServer(...)

上面的导入抛出以下打字错误:

TS1141: String literal expected.

当然我可以解决这个问题,分别导入 https 和 http,但我想知道是否有办法通过一次导入来解决上述问题?

没有打字稿,以下工作就可以了:

const http = require('http' + parseInt(process.env.SSL_ENABLED || '', 10) ? 's' : ''))

【问题讨论】:

  • 不,这会导致承诺,在这种情况下,我需要使用await 对吗?
  • 也许您可以同时导入两者,然后对某个变量进行条件赋值并使用它?

标签: javascript node.js typescript javascript-import


【解决方案1】:

dynamic import() 可以做到这一点,与top-level await 结合使用最方便:

const http = await import(parseInt(process.env.SSL_ENABLED || '', 10) ? 'https' : 'http');
// ...

请注意,动态导入可能会对捆绑程序产生负面影响(因为它们无法静态分析模块图以创建捆绑包),但这看起来像是您可能没有捆绑的 Node.js 代码。

或者如果你因为任何原因不能使用顶级await,直接使用promise:

import(parseInt(process.env.SSL_ENABLED || '', 10) ? 'https' : 'http')
.then(http => {
    // ...use `http` here...
});

【讨论】:

  • 我认为他正在尝试使用 Typescript
  • @DevZer0 - 我认为问题的 TypeScript 部分实际上是因为他们知道如何使用 CommonJS 而不是 ESM。否则,我认为 TypeScript 在这里并不重要(但我没有查看 http 与 https 的类型,它们可能不同;可能还需要一些类型的恶作剧)。这个问题似乎集中在导入而不是打字。
  • 不,我没有捆绑,所以这不是问题。仍然因为等待是在顶层,我仍然有这个问题。我想我需要以某种方式将整个东西包装在一个函数中。
  • @Cyclonecode - Node.js 支持顶级await,因此您不需要将其包装在函数中。 TypeScript 仅在您拥有 "module": "esnext" 和 "target": "es20917"(或更高版本)时才支持它,这可能是问题所在。但是,如果您使用 TypeScript 执行此操作,则正确选择类型可能会很棘手。我不确定我会走哪条路,动态导入或同时导入两者并使用包装器来处理 HTTP/HTTPS 方面。
  • @Cyclonecode - Node.js 现在很好超越了 ES6 (2015)。即使您使用的是旧版 ESR,您仍然可以使用 ES2017+。
猜你喜欢
  • 2020-12-27
  • 2018-11-14
  • 2019-10-30
  • 2014-07-08
  • 1970-01-01
  • 1970-01-01
  • 2021-05-26
  • 1970-01-01
  • 2016-11-13
相关资源
最近更新 更多