Рассмотрим некоторые аспекты работы с модулями в Node.js. Прежде всего надо отметить, что подключаемые модули кэшируются. В частности, в файле https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js есть такие строки:
const filename = Module._resolveFilename(request, parent, isMain);
const cachedModule = Module._cache[filename];
if (cachedModule !== undefined) {
updateChildren(parent, cachedModule, true);
if (!cachedModule.loaded) {
const parseCachedModule = cjsParseCache.get(cachedModule);
if (!parseCachedModule || parseCachedModule.loaded) {
return getExportsForCircularRequire(cachedModule);
}
parseCachedModule.loaded = true;
} else {
return cachedModule.exports;
}
}
Это, с одной стороны, увеличивает производительность, а с другой, может создать некоторые проблемы, если мы не будем учитывать этот аспект. Например, определим файл greeting.js со следующим образом:
module.exports.name = "Alice";
В файле определена только одна строка, которая устанавливает свойство name.
Далее определим основной файл приложения - файл app.js:
const greeting1 = require("./greeting.js");
console.log(`Hello ${greeting1.name}`); //Hello Alice
const greeting2 = require("./greeting.js");
greeting2.name= "Bob";
console.log(`Hello ${greeting2.name}`); //Hello Bob
// greeting1.name тоже изменилось
console.log(`Hello ${greeting1.name}`); //Hello Bob
Несмотря на то, что здесь два раза получаем модуль с помощью функции require, но обе переменных - greeting1 и greeting2 будут указывать на один и тот же объект.
c:\app> node app.js Hello Alice Hello Bob Hello Bob c:\app>
Нередко модули приложения образуют какие-то отдельные наборы или области. Такие наборы модулей лучше помещать в отдельные каталоги. Например, пусть у нас есть следующая структура проекта:
Папка messages, которая содержит следующие файлы
index.js
morning.js
evening.js
Главный файл приложения app.js
В файл morning.js поместим следующую строку:
module.exports = "Доброе утро";
Аналогично изменим файл evening.js:
module.exports = "Добрый вечер";
Эти два файла определяют сообщения приветствия в зависимости от времени суток.
И определим в файле index.js следующий код:
const morning = require("./morning");
const evening = require("./evening");
module.exports = {
getMorningMessage : function(){ console.log(morning);},
getEveningMessage : function(){ console.log(evening);}
}
В модуле определен объект, который имеет две функции для вывода приветствий.
Теперь используем этот модуль в файле app.js:
const messages = require("./messages");
messages.getMorningMessage();
messages.getEveningMessage();
Несмотря на то, что нет такого файла как "messages.js", но если в проекте есть каталог "messages", который содержит файл с именем index.js, то мы можем обращаться к модулю по имени каталога, как в данном случае.
Запустим приложение, и на консоль будут выведены оба приветствия:
c:\app> node app.js Доброе утро Добрый вечер c:\app>