Использование без экспорта
У меня есть этот код (который отлично работает), который я заимствовал из онлайн-ресурса:
var express = require('express');
var bodyParser = require('body-parser');
var logger = require('morgan');
var app = express();
require('./init/db');
require('./init/cache'); //Bring in Redis
//Define Routes
var userRoutes = require('./routes/user');
module.exports = app;
Бит, который я не понимаю, "требуется" при использовании таким образом? Вот файл, который он вносит:
//db.js
var mongoose = require('mongoose');
var dbURI = <theURI>;
mongoose.connect(dbURI);
// CONNECTION EVENTS
mongoose.connection.on('connected', function() {
console.log('Mongoose connected successfully');
});
То же самое с моим соединением Redis:
//cache.js
var redis = require("redis");
var redisClient = redis.createClient(process.env.CACHE_PORT, process.env.CACHE_URL);
redisClient.auth(process.env.CACHE_PASS);
redisClient.on("ready", function () {
console.log("Cache is connected");
});
но, как видите, в файлах db.js
или cache.js
нет module.exports
! Когда я google это, чтобы понять, как это работает, примеры всегда говорят о module.exports
и require
вместе.
Вопросы
-
Может ли кто-нибудь объяснить, как нужно работать, когда он используется сам по себе?
-
Как я могу сделать доступ к кешу /Redis доступным, чтобы его можно было использовать в моем файле userRoutes
, используя что-то вроде: var userRoutes = require('./routes/user')(redis);
Ответы
Ответ 1
Может кто-нибудь объяснить, что происходит с этим кодом? Другими словами, как требуется работа, когда она не используется с экспортом.
Мы почти всегда видим, что require()
используется с module.exports
, но вам этого не нужно. Когда вы ничего не экспортируете, код импортированного модуля все равно будет запущен, но вы не сможете привязать импорт к переменной и взаимодействовать с ним.
Рассмотрим следующий модуль Foo.js
:
var foo = {};
foo.greet = function(){
console.log('Hello from Foo!');
}
foo.greet();
Я могу импортировать этот модуль в свой основной файл, например:
require('./foo');
Если я запустил этот главный файл, будет запущен код внутри модуля Foo.js
, а на консоли будет напечатан Hello from Foo!.
Однако я не могу напрямую взаимодействовать с объектом foo. Следующий код не будет работать:
require('./foo');
foo.greet(); //ReferenceError, foo is not defined
Я могу привязать импорт модуля к переменной, но даже это не сработает:
var foo = require('./foo');
foo.greet(); //TypeError, foo.greet is not a function
Чтобы заставить его работать, мне нужно экспортировать объект foo из моего модуля, используя module.exports
, с которым вы знакомы.
Это демонстрирует, что вам не нужно ничего экспортировать из своих модулей, так же как вам не нужно связывать импортированный модуль с переменной, когда вы это требуете. Разница в том, что вы не сможете взаимодействовать с кодом в импортированном модуле, если вы не экспортируете то, что вы не хотите делать видимым в этом модуле.
В коде вашего вопроса импортирование Redis работает, потому что этот модуль является автономным, вам не нужно взаимодействовать с ним в вашем коде. Вам нужно только импортировать код, чтобы он мог запускаться (требуется основной модуль Redis и создать клиент)
Ответ 2
При вызове require
модуль загружается и выполняется. Итак, у вас есть связанный мангуст. На самом деле require
выполняет функцию, которую вводит весь ваш код модуля и, наконец, запускается.
Нет, если вы хотите повторно использовать переменные, созданные в модулях, которые вы должны экспортировать. Например:
//cache.js
var redis = require("redis");
var redisClient = redis.createClient(process.env.CACHE_PORT, process.env.CACHE_URL);
redisClient.auth(process.env.CACHE_PASS);
redisClient.on("ready", function () {
console.log("Cache is connected");
});
module.exports = redisClient;
Ответ 3
Помимо необходимости использования модуля, который не включает экспорт для запуска его побочных эффектов, также возможно, чтобы модуль определял переменные в глобальной области, к которым можно получить доступ в файле, где требуется модуль. Это происходит путем определения переменных без ключевого слова var
. Это не хорошая или обычная практика, но вы можете столкнуться с ней где-нибудь, чтобы было хорошо знать, что происходит.
Пример:
// foo.js
bar = 5;
и
// test.js
require('./foo');
console.log(bar);
// prints 5
Если bar
было определено как:
var bar = 5;
он будет находиться в области модуля и не будет доступен в test.js
.