webpack 循环导入返回空对象

Posted

技术标签:

【中文标题】webpack 循环导入返回空对象【英文标题】:circular imports with webpack returning empty object 【发布时间】: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 中。这里超级困惑。

【问题讨论】:

我写了一个工具来检查你的 Webpack 项目的循环依赖:github.com/DelvarWorld/webpack-cyclic-dependency-checker 【参考方案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 时不起作用。 :(

以上是关于webpack 循环导入返回空对象的主要内容,如果未能解决你的问题,请参考以下文章

为啥 process.env 返回一个空对象,而 process.env.prop 返回 prop 值?

在使用 gulp 构建的 Webpack 包中导出 Typescript 函数,浏览器中的空对象

js 判断一个对象是否是空对象

导入自定义 npm 包会导致空/空对象

判断一个对象是否是空对象的处理办法

判断一个对象是否是空对象的处理办法