2016-10-08 2 views
0

Я установил веб-сервер, используя узел JS и модуль Express. Мой код выглядит следующим образом:Проблема определения области с использованием require() в узле JS

дерево файлов:

/src 
| 
+-- server.js 
+-- /app 
    | 
    +-- routes.js 

server.js

// set up ====================================================================== 
var express = require('express'); 
var app  = express(); 
var mongoose = require('mongoose'); 

...

// configuration =============================================================== 
mongoose.connect(configDB.url); 

...

// routes ====================================================================== 
require('./app/routes.js')(app, passport); 

// launch ====================================================================== 
app.listen(port); 

routes.js

module.exports = function(app, passport) { 
     app.get('/some-route', function(req, res) { 
      // this line bugs out 
      var User = mongoose.model('User', userSchema); 
     }); 
    }; 

Мой вопрос:

Вызывающие mongoose.model() в routes.js выдает следующее сообщение об ошибке

ReferenceError:mongoose is not defined

Почему мангуст не известен в этом контексте, когда я включил его в server.js, файл, в который входит route.js? Должен ли я потребовать() mongoose снова в routes.js? Что мне здесь не хватает?

ответ

1

Переменные, определенные внутри модуля, являются локальными только для этого модуля. Они не входят в объем других модулей, которые вы используете с этим модулем require(). Вот почему mongoose не знает вашего модуля маршрутов. Операция require() не вставляет код прямо в вызывающий модуль. Вместо этого он загружает этот код с диска, а затем вставляет его в свою собственную функцию и вызывает эту функцию. Это дает каждому загруженному модулю собственную независимую область. Он не вставлен в текущий объем.

В подобных случаях, у вас есть несколько вариантов:

  1. Require() в модуле мангустов снова в маршрутах. Обычно это предпочтительнее, потому что это делает модуль маршрутов более самодостаточным и более легким для повторного использования, поскольку он требует того, что ему нужно.

  2. Пройдите в объект, который хотите поделиться с конструктором маршрутов, точно так же, как вы проходите в app и passport. Этот метод является предпочтительным, когда элемент, необходимый другому модулю, является не просто результатом простой загрузки модуля. Например, app является результатом вызова функции-конструктора, поэтому единственный способ использовать один и тот же экземпляр app - это передать его.

  3. У вас могут быть маршруты, вызывающие какой-либо другой модуль для запроса информации. Например, поскольку вы уже передали объект app маршрутам, вы можете поместить объект mongoose в качестве свойства объекта app, чтобы на него можно было ссылаться таким образом, или вы могли бы добавить метод к объекту app для его получения через вызов метода.

В этом случае, поскольку mongoose является только кэшированным модулем, вероятно, имеет наибольший смысл только require() его снова, но ни один из этих трех методов будет выше работой.

+0

Так что если я правильно понимаю; В случае номер один модуль мангуста будет кэшироваться и не вызвать дополнительную нагрузку? – matthiasdv

+1

@matthiasdv - Да, узел кэширует все модули, поэтому он во второй раз просто возвращает маркер кэшированного модуля. Он не загружает и не запускает какой-либо новый код. – jfriend00

1

Модули, которые включены в файл, не отображаются в другом файле. Здесь вы можете найти список глобальных объектов, которые доступны на каждом модуле, который вы создаете:

https://nodejs.org/api/globals.html

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

В вашем случае у вас должно быть require('mongoose') в необходимых вам файлах, и он построен так, чтобы поддерживать существующее соединение с базой данных.

Смежные вопросы