WebPack将模块解析为对象而不是函数

时间:2018-10-30 05:19:51

标签: javascript webpack

我在同一目录中有entry-point.jsFirst.jsSecond.js

entry-point.js

var First = require('./First.js'); // If I take out this line the error will go away.
var Second = require('./Second.js');

Second();

First.js

var Second = require('./Second.js'); // And if I take out this line the error will go away.

module.exports = () => {
  console.log('FIRST')
};

Second.js

var First = require('./First.js');

module.exports = () => {
  First();
};

当我使用非常基本的Webpack配置编译entry-point.js时(实际上没什么,我什至不想污染它),我得到了错误First is not a function。我猜这是因为存在一些递归依赖关系,但是我无法真正解决这个问题。

P.S。我有点知道如何解决它,我只是想知道为什么它确实无法正常工作。

2 个答案:

答案 0 :(得分:1)

您的问题是循环依赖性:First取决于SecondSecond取决于First

这是由于有一个依赖周期,并且正在文件末尾将module.exports分配给新对象。

由于循环,module.exports对象在Second的第一行传递到First,这是一个空对象。

此后,Firstmodule.exports的值重新分配给一个函数,但是该对象已经传递给Second,这就是为什么会出现错误的原因。

要解决此问题,请消除循环依赖。循环依赖关系令人困惑,通常是紧密耦合的代码的症状,最好以一种通用的依赖关系提取到其自身模块的方式对函数进行模块化。

如果无法消除循环依赖关系,则需要避免重新分配module.exports

First.js:

var Second = require('./Second.js');

module.exports.first = () => {
  console.log('FIRST')
};

Second.js

var First = require('./First.js');

module.exports = () => {
  First.first();
};

答案 1 :(得分:1)

当您在try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback) try AVAudioSession.sharedInstance().setActive(true) 中需要First时,加载程序将开始加载entry-point,而这需要First.js。由于Second.js尚未完全加载完毕,因此它是一个空对象,这就是为什么会出现First错误的原因。

有很多方法可以解决循环依赖问题。一种方法是添加包含所有导入内容的文件,然后从中进行输入。

not a function