【问题标题】:circular imports with webpack returning empty objectwebpack 循环导入返回空对象
【发布时间】:2015-08-03 09:16:00
【问题描述】:

目前正遇到这个确切的问题:

FileA:
var b = require file B
var c = require file C

FileB:
var a = require file A

FileC:
var a = require file A

当我运行代码时,文件 C 中出现错误:

A.doSomething is not a function

在那里扔了一个调试器,发现 A 是一个空对象。 真正奇怪的是,我只在文件 C 中收到错误,而不是在文件 B 中。这里超级困惑。

【问题讨论】:

标签: javascript node.js webpack


【解决方案1】:

这不是 webpack 问题,而是 CommonJS 模块的属性。

当第一次需要一个 CommonJS 模块时,它的 exports 属性在后台被初始化为一个空对象。

module.exports = {};

然后模块可以决定扩展这个exports 属性,或者覆盖它。

exports.namedExport = function() { /* ... */ }; // extends

module.exports = { namedExport: function() { /* ... */ } }; // overrides

所以当A 需要B 并且B 需要A 之后,A 不会再次执行(这会产生无限循环),但会返回其当前的exports 属性。由于A 在文件的最顶部需要B,因此在导出任何内容之前,B 模块中的require('A') 调用将产生一个空对象。

循环依赖的一个常见解决方法是将导入放在文件末尾,您导出其他模块所需的变量之后。

A:

module.exports = { foo: 'bar' };
require('B'); // at this point A.exports is not empty anymore

B:

var A = require('A');
A.foo === 'bar';

【讨论】:

  • 嘿你 :) 谢谢它帮助我理解了这个问题。但是如果在 A 中,您需要访问 B 导出的某些属性怎么办?在我的代码库中,我刚刚将module.exports 替换为exports.attribute,它现在可以工作了,但感觉不是很自然
  • 你总是可以在 B 中做同样的事情。module.exports = { bar: 'foo' }; var A = require('a');,然后是module.exports = { foo: 'bar' }; var B = require('B');。如果您的导出相互依赖,那么您应该通过扩展 exports 而不是覆盖它来逐步构建它们。
  • 这是 Stack Overflow 上给出的最重要的答案。你是英雄。
  • 救了我的培根。谢谢!
  • 我们遇到了这个问题,这个答案解决了这个问题,但是在我们构建 mocha 时不起作用。 :(
猜你喜欢
  • 2016-11-16
  • 2021-10-17
  • 2020-05-12
  • 2017-02-26
  • 2019-08-18
  • 1970-01-01
  • 2012-06-26
  • 2016-11-12
  • 2020-10-13
相关资源
最近更新 更多