【问题标题】:module.exports give undefined while print module indicates it's not undefined?module.exports 给出未定义,而打印模块表明它不是未定义的?
【发布时间】:2022-01-01 03:37:18
【问题描述】:

我正在尝试使用 CommonJs 模块,该模块根据 modulemodule.exports 是否未定义有条件地导出变量。我目前遇到的问题是,有时当我使用import { something } from 'themodule' 时,它会给我未定义的something。在查看源代码时,我发现了以下导出条件:

if (typeof module !== 'undefined' && module.exports) {
    module.exports = Prism;
}

所以我在文件中添加了一些日志,以查看是否满足条件:

console.log('module: ', module, 'module.exports: ', module.exports)
if (typeof module !== 'undefined' && module.exports) {
    console.log('module.exports!')
    module.exports = Prism;
}

然而这给了我奇怪的输出:

模块:{ 出口:[Getter/Setter] } module.exports:未定义

如您所见,module 日志似乎表明它具有 exports 属性,但是当单独记录 module.exports 时,它表示它是未定义的。这怎么可能 ?有人可以帮助理解为什么需要此检查以及为什么有时 module.exports 可以未定义?谢谢!

【问题讨论】:

  • 这个输出没有什么奇怪的。 console.log({ get exports(){ return undefined; }, set exports(_){} }); 记录同样的事情。该属性是一个getter / setter。使用module.exports调用 getter;它返回undefined拥有一个属性未定义的属性是两个不同的东西。 module.hasOwnProperty("exports") 检查属性是否存在; module.exports 改为检查真实性。 “为什么有时module.exports 可能是未定义的” — obj.xconst obj = { x: undefined }; 中是undefined
  • @SebastianSimon 太棒了。这就说得通了。但是无论如何,您知道为什么在导出变量时需要进行这样的检查吗?

标签: javascript node.js commonjs ecmascript-next


【解决方案1】:

这里有一些几乎不相关的问题。

我目前遇到的问题是,有时当我使用 import { something } from 'themodule' 时,它会给我一些未定义的东西

如果您的import 链中有循环依赖项,则可能会发生这种情况。如果 a.js 从 b.js 导入,b.js 从 c.js 导入,而 c.js 从 a.js 导入 - 那么,对于在这些模块的 顶级 运行的代码,无法保证在 other 模块的顶层运行的代码已被执行。虽然您可以进行试验并查看发生了什么,但更好的方法是

  • 删除循环依赖,和/或
  • 在您的代码中只有一个入口点,从该入口点调用所有其他有意义的东西,因此下游的循环依赖不会导致问题 - 让您的下游导出是 函数,没有顶级依赖于其他导入的代码。

然而这给了我奇怪的输出:

module: { exports: [Getter/Setter] } module.exports: undefined

这意味着:

  • exports 属性是一个 getter/setter
  • 当您调用 getter 时,它显然返回了 undefined。该属性存在,但调用 getter 不会返回任何内容。例如

const obj = {
  get prop() {
  }
};

console.log(obj.hasOwnProperty('prop'));
console.log(obj.prop);

有人可以帮助了解为什么需要此检查

检查

if (typeof module !== 'undefined' && module.exports) {

只是检查代码是否在 CommonJS 上下文中执行,如果是,则将 Prism 分配给导出。

【讨论】:

  • 很好的答案。根据您的解释,我的问题似乎是它没有在 CommonJS 上下文中执行,因为如果我执行 const {something} = require('themodule'),它可以工作,所以它不应该是循环依赖问题。你知道我如何检查我当前运行的上下文吗?
猜你喜欢
  • 2015-06-21
  • 2016-11-06
  • 2013-11-05
  • 2016-04-13
  • 2016-09-05
  • 2017-09-29
  • 1970-01-01
  • 2021-09-29
  • 2012-07-27
相关资源
最近更新 更多