require和module.exports:TypeError:X不是函数

时间:2019-04-01 14:08:09

标签: javascript node.js export require

文件结构:

server
├── controllers
│   ├── locationsController.js
│   ├── mainController.js
│   └── utilisateursController.js
├── models
│   ├── Locations.js
│   ├── Utilisateurs.js
|   └── ...
├── routes.js
└── server.js

mainController中,我有一个函数isValid用于检查字符串,将其放在此处是因为我想同时从utilisateursController.jslocationsController.js访问它。我将其导出如下:

mainController.js

const lc = require('./locationsController');
const uc = require('./utilisateursController');

// ...

module.exports = {
  // Associate all models
  associateAll: function () {
    lc.associateLocations();
    uc.associateUtilisateurs();
  },
  isValid: function(...fields) {
    for (let i = 0; i < fields.length; i++)
      if (fields[i] === undefined || fields[i] === null || fields[i] === '')
        return false;
    return true;
  }
};

问题

我可以从isValid访问函数utilisateursController.js,但是当我尝试从locationsController.js执行此功能时,出现此错误:

(node:6461) UnhandledPromiseRejectionWarning: TypeError: mc.isValid is not a function
    at exports.getAllTasks (.../server/controllers/locationsController.js:30:11)

代码

utilisateursController.js

从该文件中,我可以完美地访问isValid,没有错误。

const mc = require('./mainController');

// ...

exports.login = async function (req, res) {

  let response = {
    // ...
  }
  if (req.query == null) {
    response.infoMsg = 'Query empty...';
    res.send(response);
    return;
  }

  const usernameInput = req.query.username;
  const passwordInput = req.query.password;

  if (!mc.isValid(usernameInput, passwordInput)) {
    response.infoMsg = 'username or password is empty...'
    res.send(response);
    return;
  }

  // ...

}

locationsController.js

从该文件中,我得到上面提到的错误,我真的不知道为什么...

const mc = require('./mainController');

// ...

exports.getAllTasks = async function (req, res) {
  let response = {
    // ...
  }

  const usernameInput = req.params.username;

  if (!mc.isValid(usernameInput)) {
    response.infoMsg = 'No parameters given...';
    res.send(response);
    return;
  }

  // ...

}

我的想法

我认为可能是因为需求的解决顺序...

调试器怎么说

utilisateursController.js

utilisateurs

locationsController.js

locations

我真的不知道是什么原因导致了这个问题...

1 个答案:

答案 0 :(得分:2)

该问题是由于您在mainControllerutilisateursControllerlocationsController之间存在循环关系而引起的。 utilisateursControllerlocationsController都需要mainController,而mainContoller都需要utilisateursControllerlocationsController。结果,Node.js的CommonsJS样式的模块解析最终在至少一个模块(可能是两个模块)中运行带有占位符对象的顶级代码,以导出其他模块之一。 (显然,在您的情况下,locationsController获得了mainController出口的占位符。utilisateursController也可能会这样做,但不会尝试在顶层使用它。)< / p>

如果避免在顶层使用mc,而仅在稍后调用的函数中使用它,则该占位符将在您需要之前被填充,并且一切都会很好。您引用的代码似乎只在函数中使用mc,但是鉴于您遇到的错误,显然这与您的真实代码不符。

Node.js modules documentation's "Cycles" section中的更多内容。


旁注:本地JavaScript模块(通常将其称为“ E CMA S cript M odules”(通常称为“ ESM”)不会发生),因为即使存在循环依赖关系,它们也要在运行顶层模块代码之前得到解决。