简体   繁体   English

require 和 module.exports : TypeError: X is not a function

[英]require and module.exports : TypeError: X is not a function

File structure :文件结构:

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

In mainController I have a function isValid to check a string, I put it there because I want to access it from both utilisateursController.js and locationsController.js .mainController我有一个函数isValid来检查一个字符串,我把它放在那里是因为我想从utilisateursController.jslocationsController.js访问它。 I export it as follow :我将其导出如下:

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;
  }
};

Problem问题

I can access the function isValid from utilisateursController.js , but when I try to do the same from locationsController.js , I have this error:我可以从utilisateursController.js访问函数isValid ,但是当我尝试从locationsController.js执行相同操作时,出现以下错误:

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

Code代码

utilisateursController.js

From this file, I can perfectly access isValid , there is no error.从这个文件,我可以完美地访问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

From this file, I get the error mentioned above, and I really don't know why...从这个文件中,我得到了上面提到的错误,我真的不知道为什么......

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;
  }

  // ...

}

What I think我的想法

I think it is maybe because of the order of the resolutions of the requires...我想这可能是因为需要的决议的顺序......

What the debugger says调试器说什么

utilisateursController.js

使用者

locationsController.js

地点

I really don't know what is causing this porblem...我真的不知道是什么导致了这个问题......

The problem is caused by the fact you have a circular relationship between mainController , utilisateursController , and locationsController .问题是由于您在mainControllerutilisateursControllerlocationsController之间存在循环关系。 Both utilisateursController and locationsController require mainController , and mainContoller requires both utilisateursController and locationsController . utilisateursControllerlocationsController都需要mainControllermainContoller需要utilisateursControllerlocationsController As a result, Node.js's CommonsJS-style module resolution ends up running the top-level code in at least one (probably both) of your modules with a placeholder object for the exports of one of the other modules.因此,Node.js 的 CommonsJS 样式模块解析最终会在至少一个(可能两个)模块中运行顶级代码,并带有一个占位符对象,用于导出其他模块之一。 (Apparently, in your case, locationsController gets a placeholder for mainController 's exports. utilisateursController probably does, too, but doesn't try to use it at the top level.) (显然,在您的情况下, locationsControllermainController的导出获取了一个占位符utilisateursController可能也有,但不会尝试在顶层使用它。)

If you avoid using mc at the top level, only using it in functions called later, that placeholder will get filled in before you need it and all will be well.如果您避免在顶层使用mc ,而只在稍后调用的函数中使用它,那么该占位符将在您需要之前被填充,一切都会好起来的。 The code you've quoted seems to only use mc within a function, but given the error you're getting, apparently that's not true of your real code.您引用的代码似乎只在函数中使用mc ,但考虑到您遇到的错误,显然您的真实代码并非如此。

More in the Node.js modules documentation's "Cycles" section .更多在Node.js 模块文档的“周期”部分


Side note: This doesn't happen with native JavaScript modules (often called "ESM" for " E CMA S cript M odules), because even when there are circular dependencies, they're resolved before the top-level module code gets run.附注:这不会与本地JavaScript模块发生(通常被称为“ESM”为“E CMA小号CRIPT中号odules),因为即使有循环依赖,顶层模块代码进行之前,他们正在解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM