Рубрики
Без рубрики

Требующие модулей в Node.js: все, что вам нужно знать

Обновление: эта статья теперь является частью моей книги «Node.js за пределы основы». Прочитайте обновленную версию этого контента и больше о узле на jscomplete.com/node-beyeyond-basics.node использует два основных модуля для управления модульными зависимостями: нужный модуль, который, кажется, должен быть доступен на глобальной области

Автор оригинала: Samer Buna.

Узел использует два основных модуля для управления модульными зависимостями:

  • требуется Модуль, который, кажется, должен быть доступен на глобальной области – нет необходимости требуют («требуют») Отказ
  • модуль Модуль, который также может быть доступен на глобальной области – нет необходимости требуют («модуль») Отказ

Вы можете думать о требуется Модуль как команда и модуль Модуль как организатор всех необходимых модулей.

Требуется модуль в узле, не осложняется концепции.

const config = require('/path/to/file');

Основной объект, экспортированный требуется Модуль – это функция (как используется в приведенном выше примере). Когда узел призывает это требовать () Функция с локальным пухом файла в качестве единственного аргумента функции, узел проходит через следующую последовательность шагов:

  • Разрешение : Найти абсолютный путь файла.
  • Загрузка : Чтобы определить тип содержимого файла.
  • Упаковка : Чтобы дать файл свой личный объем. Это то, что делает оба требуется и модуль Объекты локальные для каждого файла, который мы требуем.
  • Оценка : Это то, что VM в конечном итоге делает с загруженным кодом.
  • Кэширование Так что, когда нам снова требуется этот файл, мы не проводим все шаги в другое время.

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

Позвольте мне сначала создать каталог для размещения всех примеров, используя мой терминал:

mkdir ~/learn-node && cd ~/learn-node

Все команды в остальной части этой статьи будут запускаться из-за ~/Узел - узел Отказ

Разрешение локального пути

Позвольте мне представить вас с модуль объект. Вы можете проверить это в простом сеансе REPE:

~/learn-node $ node
> module
Module {
  id: '',
  exports: {},
  parent: undefined,
  filename: null,
  loaded: false,
  children: [],
  paths: [ ... ] }

Каждый объект модуля получает ID свойство, чтобы идентифицировать это. Это ID Обычно это полный путь к файлу, но в сеансе reft это просто .

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

Тем не менее, поскольку узел позволяет многим способам требовать файл (например, с относительным путем или предварительно настроенным путем), прежде чем мы сможем загрузить содержимое файла в память, нам нужно найти абсолютное местоположение этого файла.

Когда нам требуется «Найти-мне» Модуль, не указав путь:

require('find-me');

Узел будет искать find-me.js во всех путях, указанных на Модуль. Пути – чтобы.

~/learn-node $ node
> module.paths
[ '/Users/samer/learn-node/repl/node_modules',
  '/Users/samer/learn-node/node_modules',
  '/Users/samer/node_modules',
  '/Users/node_modules',
  '/node_modules',
  '/Users/samer/.node_modules',
  '/Users/samer/.node_libraries',
  '/usr/local/Cellar/node/7.7.1/lib/node' ]

Список путей в основном является список каталогов Node_Modules в каждом каталоге из текущего каталога к корневому каталогу. Он также включает в себя несколько устаревших каталогов, использование которых не рекомендуется.

Если узел не может найти find-me.js В любом из этих путей он бросит «не может найти ошибку модуля».

~/learn-node $ node
> require('find-me')
Error: Cannot find module 'find-me'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at repl:1:1
    at ContextifyScript.Script.runInThisContext (vm.js:23:33)
    at REPLServer.defaultEval (repl.js:336:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.onLine (repl.js:533:10)

Если вы сейчас создаете местный node_modules каталог и поставить find-me.js В тудах требовать («найти-я») линия найдет это.

~/learn-node $ mkdir node_modules 

~/learn-node $ echo "console.log('I am not lost');" > node_modules/find-me.js

~/learn-node $ node
> require('find-me');
I am not lost
{}
>

Если другой find-me.js Файл существовал в любом из других путей, например, если у нас есть node_modules каталог под домашним каталогом, и у нас есть другой find-me.js Файл там:

$ mkdir ~/node_modules
$ echo "console.log('I am the root of all problems');" > ~/node_modules/find-me.js

Когда мы требовать («найти-я») изнутри Учебный узел каталог – у которого есть свой node_modules/find-me.js , find-me.js Файл в домашнем каталоге не будет загружен вообще:

~/learn-node $ node
> require('find-me')
I am not lost
{}
>

Если мы удалим локальный node_modules каталог под ~/Узел - узел и попробуйте потребовать Найти-мне Еще раз, файл под домашним node_modules каталог будет использоваться:

~/learn-node $ rm -r node_modules/
~/learn-node $ node
> require('find-me')
I am the root of all problems
{}
>

Требует папки

Модули не должны быть файлами. Мы также можем создать Найти-мне Папка под node_modules и поместите index.js файл там. То же самое требовать («найти-я») линия будет использовать эту папку index.js файл:

~/learn-node $ mkdir -p node_modules/find-me

~/learn-node $ echo "console.log('Found again.');" > node_modules/find-me/index.js

~/learn-node $ node
> require('find-me');
Found again.
{}
>

Обратите внимание, как он проигнорировал домашний каталог node_modules путь снова, так как у нас сейчас есть местный.

index.js Файл будет использоваться по умолчанию, когда нам нужна папка, но мы можем контролировать, какое имя файла начинается с под папкой, используя Главная Недвижимость в Package.json Отказ Например, чтобы сделать требовать («найти-я») линия разрешит в другой файл под Найти-мне Папка, все, что нам нужно сделать, это добавить Package.json Файл там и укажите, какой файл должен использоваться для разрешения этой папки:

~/learn-node $ echo "console.log('I rule');" > node_modules/find-me/start.js

~/learn-node $ echo '{ "name": "find-me-folder", "main": "start.js" }' > node_modules/find-me/package.json

~/learn-node $ node
> require('find-me');
I rule
{}
>

потребовать

Если вы хотите разрешить только модуль и не выполнять его, вы можете использовать потребовать функция. Это ведет себя точно так же, как главный требуется Функция, но не загружает файл. Он все еще будет бросать ошибку, если файл не существует, и он вернет полный путь к файлу при найденном.

> require.resolve('find-me');
'/Users/samer/learn-node/node_modules/find-me/start.js'
> require.resolve('not-there');
Error: Cannot find module 'not-there'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.resolve (internal/module.js:27:19)
    at repl:1:9
    at ContextifyScript.Script.runInThisContext (vm.js:23:33)
    at REPLServer.defaultEval (repl.js:336:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.onLine (repl.js:533:10)
    at emitOne (events.js:101:20)
    at REPLServer.emit (events.js:191:7)
>

Это можно использовать, например, чтобы проверить, установлен ли дополнительный пакет или нет, и использовать только его только тогда, когда он доступен.

Относительные и абсолютные пути

Помимо разрешения модулей из в пределах node_modules Каталоги, мы также можем разместить модуль в любом месте, который мы хотим и требуют его с относительными путями ( ./ и .... ) или с абсолютными путями, начиная с / Отказ

Если, например, find-me.js Файл был под lib папка вместо node_modules Папка, мы можем потребовать ее с:

require('./lib/find-me');

Родитель-дочерние отношения между файлами

Создать lib/util.js Файл и добавьте console.log линия там, чтобы идентифицировать это. Также console.log модуль Сам объект:

~/learn-node $ mkdir lib
~/learn-node $ echo "console.log('In util', module);" > lib/util.js

Сделайте то же самое для index.js Файл, который мы будем выполнять с помощью команды узла. Сделать это index.js Файл требует lib/util.js :

~/learn-node $ echo "console.log('In index', module); require('./lib/util');" > index.js

Теперь выполните index.js Файл с узлом:

~/learn-node $ node index.js
In index Module {
  id: '.',
  exports: {},
  parent: null,
  filename: '/Users/samer/learn-node/index.js',
  loaded: false,
  children: [],
  paths: [ ... ] }
In util Module {
  id: '/Users/samer/learn-node/lib/util.js',
  exports: {},
  parent:
   Module {
     id: '.',
     exports: {},
     parent: null,
     filename: '/Users/samer/learn-node/index.js',
     loaded: false,
     children: [ [Circular] ],
     paths: [...] },
  filename: '/Users/samer/learn-node/lib/util.js',
  loaded: false,
  children: [],
  paths: [...] }

Обратите внимание, как главная индекс модуль (ID: '.') сейчас перечислены как родителя для lib/usil модуль. Тем не менее, lib/usil Модуль не был перечислен как ребенок индекс модуль. Вместо этого у нас есть [Циркуляр] Значение там, потому что это круговая ссылка. Если узел печатает lib/usil Объект модуля, он пойдет в бесконечную петлю. Вот почему это просто заменяет lib/usil Ссылка с [Циркуляр] Отказ

Что еще более важно, что происходит, если lib/usil Модуль требует главного индекс модуль? Здесь мы попадаем в то, что известно как круговая модульная зависимость, которая допускается в узле.

Чтобы лучше понять, давайте сначала понять несколько других концепций на объекте модуля.

Экспорт, модуль. Экспорты и синхронная загрузка модулей

В любом модуле экспорт является специальным объектом. Если вы заметили выше, каждый раз, когда мы напечатали объект модуля, он имел свойство экспорта, который до сих пор был пустым объектом. Мы можем добавить любой атрибут к этому специальному объекту экспорта. Например, давайте экспортируем атрибут ID для index.js и lib/util.js :

// Add the following line at the top of lib/util.js
exports.id = 'lib/util';

// Add the following line at the top of index.js
exports.id = 'index';

Когда мы сейчас выполняем index.js , мы увидим эти атрибуты, как управлять на каждом файле модуль объект:

~/learn-node $ node index.js
In index Module {
  id: '.',
  exports: { id: 'index' },
  loaded: false,
  ... }
In util Module {
  id: '/Users/samer/learn-node/lib/util.js',
  exports: { id: 'lib/util' },
  parent:
   Module {
     id: '.',
     exports: { id: 'index' },
     loaded: false,
     ... },
  loaded: false,
  ... }

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

// Add the following line in index.js before the console.log

module.exports = function() {};

Когда вы запустите index.js Теперь вы увидите, как Экспорт Объект – это функция:

~/learn-node $ node index.js
In index Module {
  id: '.',
  exports: [Function],
  loaded: false,
  ... }

Обратите внимание, как мы не делали Экспорт () {} сделать Экспорт объект в функцию. Мы не можем сделать это, потому что Экспорт Переменная внутри каждого модуля это просто ссылка на Module.exports который управляет экспортируемыми свойствами. Когда мы переназнаем Экспорт Переменная, эта ссылка потеряна, и мы будем представлять новую переменную вместо изменения Module.exports объект.

Module.exports Объект в каждом модуле это то, что требуется Функция возвращается, когда нам требуется этот модуль. Например, изменить требуют ('./lib/util') линия в index.js в:

const UTIL = require('./lib/util');

console.log('UTIL:', UTIL);

Выше приведено схватывает свойства, экспортированные в lib/usil в Util постоянный. Когда мы бежим index.js Теперь самая последняя линия выводится:

UTIL: { id: 'lib/util' }

Давайте также поговорим о загружен атрибут на каждом модуле. Пока что каждый раз мы напечатали модуль объекта, мы видели загружен атрибут на этом объекте со значением ложь Отказ

модуль Модуль использует загружен Атрибут для отслеживания, какие модули были загружены (истинное значение), и какие модули все еще загружаются (ложное значение). Мы можем, например, увидеть index.js Модуль полностью загружен, если мы распечатаем его модуль Объект в следующем цикле петли событий с использованием Setimmediate вызов:

// In index.js
setImmediate(() => {
  console.log('The index.js module object is now loaded!', module)
});

Вывод этого будет:

The index.js module object is now loaded! Module {
  id: '.',
  exports: [Function],
  parent: null,
  filename: '/Users/samer/learn-node/index.js',
  loaded: true,
  children:
   [ Module {
       id: '/Users/samer/learn-node/lib/util.js',
       exports: [Object],
       parent: [Circular],
       filename: '/Users/samer/learn-node/lib/util.js',
       loaded: true,
       children: [],
       paths: [Object] } ],
  paths:
   [ '/Users/samer/learn-node/node_modules',
     '/Users/samer/node_modules',
     '/Users/node_modules',
     '/node_modules' ] }

Обратите внимание, как в этом отложенном console.log Вывод обоих lib/util.js и index.js полностью загружены.

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

Это также означает, что мы не можем изменить Экспорт объект асинхронно. Например, мы не можем сделать следующее в любом модуле:

fs.readFile('/etc/passwd', (err, data) => {
  if (err) throw err;
  
  exports.data = data; // Will not work.
});

Круговой модуль зависимости

Давайте теперь попробуем ответить на важный вопрос о круговой зависимости в узле: что происходит, когда модуль 1 требует модуля 2, а модуль 2 требует модуля 1?

Чтобы узнать, давайте создадим следующие два файла под lib/ , module1.js и module2.js и у них потребуется друг друга:

// lib/module1.js

exports.a = 1;

require('./module2');

exports.b = 2;
exports.c = 3;

// lib/module2.js

const Module1 = require('./module1');
console.log('Module1 is partially loaded here', Module1);

Когда мы бежим module1.js Мы видим следующее:

~/learn-node $ node lib/module1.js
Module1 is partially loaded here { a: 1 }

Мы обязаны модуль2 до Модуль1 был полностью загружен, а с модуль2 Требуется Модуль1 Хотя это не было полностью загружено, что мы получаем от Экспорт Объект в точке – все свойства, экспортируемые до круглой зависимости. Только А Недвижимость сообщалось, потому что оба B и C . были экспортированы после модуль2 Требуется и напечатан Модуль1 Отказ

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

JSON и C/C ++ Addons

Мы можем врасходовать файлы json и файлы C ++ с помощью функции требуют. Вам даже не нужно указывать расширение файла для этого.

Если расширение файла не было указано, первое, что узел попытается разрешить это .js файл. Если он не может найти .js Файл, это попробует .json файл, и это будет разбирать .json Файл, если найдено в виде текстового файла JSON. После этого он попытается найти двоичный .node файл. Однако, чтобы удалить двусмысленность, вы, вероятно, должны указать расширение файла при необходимости чего-либо, кроме .js файлы.

Требование файлов JSON полезно, если, например, все, что вам нужно для управления в этом файле, – это некоторые значения конфигурации статики или некоторые значения, которые вы периодически читаете от внешнего источника. Например, если у нас было следующее config.json файл:

{
  "host": "localhost",
  "port": 8080
}

Мы можем потребовать его напрямую, как это:

const { host, port } = require('./config');

console.log(`Server will run at http://${host}:${port}`);

Запуск вышеуказанного кода будет иметь этот вывод:

Server will run at http://localhost:8080

Если узел не может найти .js или .json Файл, это будет искать .node Файл и это интерпретируют файл в виде сборного модуля Addon.

Сайт документации узла имеет Образец Addon file который написан на C ++. Это простой модуль, который подвергает Привет () Функция и функция Hello Functions «Мир».

Вы можете использовать Узел-GYP Пакет для компиляции и сборки .cc Файл в .node файл. Вам просто нужно настроить Binding.gyp файл, чтобы сказать Узел-GYP что делать.

Как только у вас есть Addon.node Файл (или любое имя, которое вы указываете в Binding.gyp ) Тогда вы можете вроде бы вроде, как и любой другой модуль:

const addon = require('./addon');

console.log(addon.hello());

Мы можем увидеть поддержку трех расширений, глядя на требовать. Эксплюция Отказ

Глядя на функции для каждого расширения, вы можете четко видеть, какой узел будет делать с каждым. Использует Модуль ._compile для .js Файлы, Json.parse для .json Файлы и Процесс.dlopen для .node файлы.

Вся код, который вы пишете в узле, будут обернуты в функции

Узел модулей в узле часто неправильно понят. Чтобы понять это, позвольте мне напомнить вам о Экспорт / Module.exports связь.

Мы можем использовать Экспорт Объект для экспорта свойств, но мы не можем заменить Экспорт объект напрямую, потому что это просто ссылка на модуль. Экспорты

exports.id = 42; // This is ok.

exports = { id: 42 }; // This will not work.

module.exports = { id: 42 }; // This is ok.

Как именно это это Экспорт Объект, который, кажется, глобальный для каждого модуля, определяется как ссылка на модуль объект?

Позвольте мне задать еще один вопрос, прежде чем объяснить процесс упаковки узла.

В браузере, когда мы объявляем переменную в скрипте, как это:

var answer = 42;

Что Ответ Переменная будет всемирно доступна во всех скриптах после скрипта, который его определил.

Это не так в узле. Когда мы определяем переменную в одном модуле, другие модули в программе не будут иметь доступа к этой переменной. Итак, как приходят переменные в узле волшебным образом охвачены?

Ответ прост. Перед составлением модуля узел обертывает код модуля в функции, которую мы можем проверить, используя обертка Собственность модуль модуль.

~ $ node
> require('module').wrapper
[ '(function (exports, require, module, __filename, __dirname) { ',
  '\n});' ]
>

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

Эта функция обертки имеет 5 аргументов: Экспорт , требуется , модуль , __Filename и __dirname Отказ Это то, что заставляет их выглядеть глобальными, когда на самом деле они специфичны для каждого модуля.

Все эти аргументы получают свои значения, когда узел выполняет функцию обертки. Экспорт определяется как ссылка на Module.exports до этого. требуется и модуль оба специфичны для выполнения функции, так и __Filename / __dirname Переменные будут содержать абсолютное имя файла и каталога обмороженного модуля.

Вы можете увидеть эту упаковку в действии, если вы запустите скрипт с проблемой на первой строке:

~/learn-node $ echo "euaohseu" > bad.js

~/learn-node $ node bad.js
~/bad.js:1
(function (exports, require, module, __filename, __dirname) { euaohseu
                                                              ^
ReferenceError: euaohseu is not defined

Обратите внимание, как выше, была первая строка скрипта, как указано выше, была функция обертки, а не плохая ссылка.

Более того, поскольку каждый модуль попадает в функцию, мы действительно можем получить доступ к аргументам функции с Аргументы ключевое слово:

~/learn-node $ echo "console.log(arguments)" > index.js

~/learn-node $ node index.js
{ '0': {},
  '1':
   { [Function: require]
     resolve: [Function: resolve],
     main:
      Module {
        id: '.',
        exports: {},
        parent: null,
        filename: '/Users/samer/index.js',
        loaded: false,
        children: [],
        paths: [Object] },
     extensions: { ... },
     cache: { '/Users/samer/index.js': [Object] } },
  '2':
   Module {
     id: '.',
     exports: {},
     parent: null,
     filename: '/Users/samer/index.js',
     loaded: false,
     children: [],
     paths: [ ... ] },
  '3': '/Users/samer/index.js',
  '4': '/Users/samer' }

Первый аргумент – это Экспорт Объект, который начинается пусто. Тогда у нас есть требуется / модуль Объекты, оба из которых являются экземплярами, которые связаны с index.js файл, который мы выполняем. Они не являются глобальными переменными. Последние 2 аргумента являются путь файла и путь его каталога.

Возвращаемое значение функции обертывания – Module.exports Отказ Внутри обернутой функции мы можем использовать Экспорт Объект для изменения свойств Module.exports , но мы не можем переназначить себя экспортировать, потому что это просто ссылка.

Что происходит примерно эквивалентно:

function (require, module, __filename, __dirname) {
  let exports = module.exports;
  
  // Your Code...
  
  return module.exports;
}

Если мы изменим весь Экспорт объект, это больше не будет ссылкой на Module.exports Отказ Это то, как справочные объекты JavaScript работают везде, а не только в этом контексте.

Требуется объект

Нет ничего особенного в отношении требуется Отказ Это объект, который действует главным образом в качестве функции, которая принимает имя или путь модуля и возвращает Module.exports объект. Мы можем просто переопределить требуется объект с нашей собственной логикой, если мы хотим.

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

require = function() {

  return { mocked: true };
  
}

После выполнения вышеупомянутой переназначения требуется каждый требовать («что-то») Вызов в сценарии просто вернется издевался объект.

Требуемый объект также имеет свойства собственного. Мы видели решить Свойство, которая является функцией, которая выполняет только решающий этап процесса требуется. Мы также видели требовать. Эксплюция выше.

Есть также требуется. Main которые могут быть полезны, чтобы определить, требуется ли сценарий или работает напрямую.

Скажи, например, что у нас есть этот простой printinframe Функция в Print-In-Frame.js :

// In print-in-frame.js

const printInFrame = (size, header) => {
  console.log('*'.repeat(size));
  console.log(header);
  console.log('*'.repeat(size));
};

Функция принимает числовой аргумент Размер и строковый аргумент Заголовок И он печатает, что заголовок в рамке звезд, контролируемых размером, который мы указываем.

Мы хотим использовать этот файл двумя способами:

  1. Из командной строки прямо нравится это:
~/learn-node $ node print-in-frame 8 Hello

Прохождение 8 и привет в качестве аргументов командной строки печатать «Привет» в рамке из 8 звезд.

2. С требуется Отказ Предполагая, что требуемый модуль будет экспортировать printinframe функция, и мы можем просто назвать это:

const print = require('./print-in-frame');

print(5, 'Hey');

Чтобы распечатать заголовок «Эй» в рамке из 5 звезд.

Это два разных использования. Нам нужен способ определить, работает ли файл в качестве автономного скрипта или если оно требуется другими сценариями.

Это где мы можем использовать это простое, если утверждение:

if (require.main === module) {
  // The file is being executed directly (not with require)
}

Таким образом, мы можем использовать это условие, чтобы удовлетворить требования к использованию выше, вызывая функцию printinframe по-разному:

// In print-in-frame.js

const printInFrame = (size, header) => {
  console.log('*'.repeat(size));
  console.log(header);
  console.log('*'.repeat(size));
};

if (require.main === module) {
  printInFrame(process.argv[2], process.argv[3]);
} else {
  module.exports = printInFrame;
}

Когда файл не требуется, мы просто называем printinframe Функция с Process.argv элементы. В противном случае мы просто изменим Module.exports объект, чтобы быть printinframe функция сама.

Все модули будут кэшировать

Кэширование важно для понимания. Позвольте мне использовать простой пример, чтобы продемонстрировать его.

Скажите, что у вас есть следующие ascii-art.js Файл, который печатает крутой заголовок:

Мы хотим отобразить этот заголовок каждый раз, когда мы требуется файл. Поэтому, когда мы требуем файла дважды, мы хотим, мы хотим, чтобы заголовок был дважды отображаться.

require('./ascii-art') // will show the header.
require('./ascii-art') // will not show the header.

Второе требование не покажет заголовок из-за кэширования модулей. Узел кэширует первый звонок и не загружает файл на второй вызов.

Мы можем увидеть этот кеш, печать require.acache После первого потребовать. Реестр кэша – это просто объект, который имеет свойство для каждого необходимого модуля. Эти значения свойств являются модуль Объекты, используемые для каждого модуля. Мы можем просто удалить свойство от этого require.acache объект для недействительности этого кэша. Если мы сделаем это, узел повторно загрузит модуль, чтобы повторно кэшировать.

Однако это не самое эффективное решение для этого случая. Простое решение – обернуть линию журнала в ascii-art.js с функцией и экспортом этой функции. Таким образом, когда нам требуется ascii-art.js Файл, мы получаем функцию, которую мы можем выполнить, чтобы принять линию журнала каждый раз:

require('./ascii-art')() // will show the header.
require('./ascii-art')() // will also show the header.

Это все, что у меня есть для этой темы. Спасибо за прочтение. До скорого!

Изучение реагировать или узел? Оформить заказ моих книг: