require и module.exports: TypeError: X не является функцией - PullRequest
0 голосов
/ 01 апреля 2019

Структура файла:

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

В mainController У меня есть функция isValid, чтобы проверить строку, я поместил ее туда, потому что хочу получить к ней доступ как из utilisateursController.js, так и locationsController.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 Ответ

2 голосов
/ 01 апреля 2019

Проблема вызвана тем, что у вас есть круговые отношения между mainController, utilisateursController и locationsController.Для utilisateursController и locationsController требуется mainController, а для mainContoller требуется utilisateursController и locationsController.В результате при разрешении модуля в стиле CommonsJS в Node.js код верхнего уровня запускается как минимум в одном (вероятно, в обоих) из ваших модулей с объектом-заполнителем для экспорта одного из других модулей.(Очевидно, в вашем случае locationsController получает заполнитель для экспорта mainController. utilisateursController, вероятно, тоже, но не пытается использовать его на верхнем уровне.)

Есливы избегаете использовать mc на верхнем уровне, только используя его в функциях, вызываемых позже, этот заполнитель будет заполнен раньше, чем вам это понадобится, и все будет хорошо.Код, который вы процитировали, кажется, использует только mc внутри функции, но, учитывая полученную ошибку, очевидно, это не относится к вашему реальному коду.

Больше в Node.jsРаздел «Циклы» документации по модулям .


Примечание: этого не происходит с собственными модулями JavaScript (часто называемыми «ESM» для « E CMA »).S cript M odules), поскольку даже при наличии циклических зависимостей они разрешаются до запуска кода модуля верхнего уровня.

...