Node js, как подключить файл js

Обновлено: 21.11.2024

В модульной системе Node.js каждый файл рассматривается как отдельный модуль. Например, рассмотрим файл с именем foo.js:

В первой строке foo.js загружает модуль circle.js, который находится в том же каталоге, что и foo.js.

Вот содержимое circle.js:

Модуль circle.js экспортировал функции area() и окружность() . Функции и объекты добавляются в корень модуля путем указания дополнительных свойств в специальном объекте экспорта.

Переменные, локальные для модуля, будут частными, так как модуль обернут в функцию Node.js (см. оболочку модуля). В этом примере переменная PI является частной для circle.js .

Свойству module.exports можно присвоить новое значение (например, функцию или объект).

Ниже в bar.js используется модуль Square, который экспортирует класс Square:

Квадратный модуль определен в Square.js:

Модульная система CommonJS реализована в основном модуле модуля.

Node.js имеет две модульные системы: модули CommonJS и модули ECMAScript.

По умолчанию Node.js будет рассматривать следующие модули CommonJS:

Файлы с расширением .cjs;

Файлы с расширением .js, если ближайший родительский файл package.json содержит поле верхнего уровня "type" со значением "commonjs" .

Файлы с расширением .js, если ближайший родительский файл package.json не содержит поле верхнего уровня "тип" . Авторы пакетов должны включать поле «тип» даже в пакеты, где все исходники — CommonJS. Явное указание типа пакета облегчит средствам сборки и загрузчикам определение того, как следует интерпретировать файлы в пакете.

Файлы с расширением, отличным от .mjs , .cjs , .json , .node или .js (если ближайший родительский файл package.json содержит поле верхнего уровня «тип» со значением «модуль» , эти файлы будут распознаваться как модули CommonJS, только если они требуются, а не при использовании в качестве точки входа в командную строку программы).

Вызов require() всегда использует загрузчик модулей CommonJS. Вызов import() всегда использует загрузчик модулей ECMAScript.

Когда файл запускается непосредственно из Node.js, для параметра require.main устанавливается его модуль . Это означает, что можно определить, запускался ли файл напрямую, проверив require.main === module .

Для файла foo.js это будет true, если он запускается через узел foo.js, и false, если запускается с помощью require('./foo') .

Если точка входа не является модулем CommonJS, require.main не определено и основной модуль недоступен.

Семантика функции Node.js require() была разработана так, чтобы быть достаточно общей для поддержки разумных структур каталогов. Мы надеемся, что программы-менеджеры пакетов, такие как dpkg , rpm и npm, смогут создавать нативные пакеты из модулей Node.js без изменений.

Ниже мы даем рекомендуемую структуру каталогов, которая может работать:

Допустим, мы хотим, чтобы папка /usr/lib/node/ / содержала содержимое определенной версии пакета.

Пакеты могут зависеть друг от друга. Чтобы установить пакет foo, может потребоваться установить определенную версию пакета bar. Пакет bar сам по себе может иметь зависимости, а в некоторых случаях они могут даже конфликтовать или образовывать циклические зависимости.

  • /usr/lib/node/foo/1.2.3/ : содержимое пакета foo, версия 1.2.3.
  • /usr/lib/node/bar/4.3.2/ : содержимое пакета bar, от которого зависит foo.
  • /usr/lib/node/foo/1.2.3/node_modules/bar : символическая ссылка на /usr/lib/node/bar/4.3.2/ .
  • /usr/lib/node/bar/4.3.2/node_modules/* : символические ссылки на пакеты, от которых зависит bar.

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

Когда код в пакете foo требует('bar') , он получит версию, связанную символической ссылкой в ​​/usr/lib/node/foo/1.2.3/node_modules/bar . Затем, когда код в пакете bar вызовет require('quux') , он получит версию, связанную символической ссылкой в ​​/usr/lib/node/bar/4.3.2/node_modules/quux .

Кроме того, чтобы сделать процесс поиска модулей еще более оптимальным, вместо размещения пакетов непосредственно в /usr/lib/node мы могли бы поместить их в /usr/lib/node_modules/ / . Тогда Node.js не будет искать отсутствующие зависимости в /usr/node_modules или /node_modules .

Чтобы сделать модули доступными для Node.js REPL, может быть полезно также добавить папку /usr/lib/node_modules в переменную среды $NODE_PATH. Поскольку поиск модулей с использованием папок node_modules является относительным и основан на реальном пути к файлам, выполняющим вызовы require() , сами пакеты могут находиться где угодно.

Из-за синхронного характера функции require() невозможно использовать ее для загрузки файлов модуля ECMAScript.Попытка сделать это вызовет ошибку ERR_REQUIRE_ESM. Вместо этого используйте import().

Расширение .mjs зарезервировано для модулей ECMAScript, которые нельзя загрузить с помощью require() . Дополнительную информацию о том, какие файлы анализируются как модули ECMAScript, см. в разделе «Определение модульной системы».

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

Объединяя все вышеперечисленное, вот высокоуровневый алгоритм в псевдокоде того, что делает функция require():

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

При условии, что require.cache не изменен, многократные вызовы require('foo') не приведут к многократному выполнению кода модуля. Это важная особенность. С его помощью можно возвращать «частично выполненные» объекты, что позволяет загружать транзитивные зависимости, даже если они вызывают циклы.

Чтобы модуль выполнял код несколько раз, экспортируйте функцию и вызовите эту функцию.

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

Кроме того, в файловых системах или операционных системах, нечувствительных к регистру, разные разрешенные имена файлов могут указывать на один и тот же файл, но кэш по-прежнему будет рассматривать их как разные модули и перезагружать файл несколько раз. Например, require('./foo') и require('./FOO') возвращают два разных объекта, независимо от того, являются ли ./foo и ./FOO одним и тем же файлом.

Добавлен узел: поддержка импорта в require(. ) .

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

Основные модули определяются в исходном коде Node.js и находятся в папке lib/.

При наличии циклических вызовов require() модуль может не завершить выполнение на момент возврата.

Рассмотрите такую ​​ситуацию:

Когда main.js загружает a.js , тогда a.js, в свою очередь, загружает b.js . В этот момент b.js пытается загрузить a.js. Чтобы предотвратить бесконечный цикл, незаконченная копия объекта экспорта a.js возвращается в модуль b.js. Затем b.js завершает загрузку, и его объект экспорта передается в модуль a.js.

К тому времени, когда main.js загрузит оба модуля, они оба готовы. Таким образом, вывод этой программы будет таким:

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

Если точное имя файла не найдено, Node.js попытается загрузить требуемое имя файла с добавленными расширениями: .js , .json и, наконец, .node . При загрузке файла с другим расширением (например, .cjs) его полное имя должно быть передано в require(), включая расширение файла (например, require('./file.cjs')).

Файлы .json анализируются как текстовые файлы JSON, файлы .node интерпретируются как скомпилированные дополнительные модули, загружаемые с помощью process.dlopen() . Файлы с любым другим расширением (или вообще без расширения) анализируются как текстовые файлы JavaScript. Обратитесь к разделу Определение модульной системы, чтобы понять, какая цель синтаксического анализа будет использоваться.

Обязательный модуль с префиксом '/' представляет собой абсолютный путь к файлу. Например, require('/home/marco/foo.js') загрузит файл в /home/marco/foo.js .

Обязательный модуль с префиксом './' относится к файлу, вызывающему require() . То есть, Circle.js должен находиться в том же каталоге, что и foo.js, чтобы функция require('./circle') могла его найти.

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

Если указанный путь не существует, функция require() выдаст ошибку MODULE_NOT_FOUND.

Существует три способа передачи папки функции require() в качестве аргумента.

Во-первых, нужно создать файл package.json в корне папки, в котором указан основной модуль. Пример файла package.json может выглядеть так:

Если бы это было в папке ./some-library , то require('./some-library') попытается загрузить ./some-library/lib/some-library.js .

Если в каталоге нет файла package.json или если «основная» запись отсутствует или не может быть разрешена, то Node.js попытается загрузить файл index.js или index.node из этого каталога. каталог. Например, если в предыдущем примере не было файла package.json, то require('./some-library') попытается загрузить:

  • ./some-library/index.js
  • ./some-library/index.node

Если эти попытки не увенчаются успехом, Node.js сообщит об отсутствии всего модуля с ошибкой по умолчанию:

Во всех трех случаях вызов import('./some-library') приведет к ошибке ERR_UNSUPPORTED_DIR_IMPORT. Использование экспорта подпутей пакетов или импорта подпутей может обеспечить те же преимущества организации сдерживания, что и папки в качестве модулей, и работает как для require, так и для import .

Если идентификатор модуля, переданный в require(), не является основным модулем и не начинается с '/' , '../' или './' , то Node.js запускается в каталоге текущего module, добавляет /node_modules и пытается загрузить модуль из этого места. Node.js не будет добавлять node_modules к пути, который уже заканчивается на node_modules .

Если он там не найден, то он перемещается в родительский каталог и так далее, пока не будет достигнут корень файловой системы.

Например, если файл в '/home/ry/projects/foo.js' вызывается require('bar.js') , то Node.js будет искать в следующих местах в этом порядке:

  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

Это позволяет программам локализовать свои зависимости, чтобы они не конфликтовали.

Можно потребовать определенных файлов или подмодулей, распространяемых вместе с модулем, включив суффикс пути после имени модуля. Например, require('example-module/path/to/file') разрешает путь/к/файлу относительно того, где расположен пример-модуль. Путь с суффиксом следует той же семантике разрешения модуля.

Если для переменной среды NODE_PATH задан список абсолютных путей, разделенных двоеточием, Node.js будет искать модули по этим путям, если они не будут найдены где-либо еще.

В Windows NODE_PATH разделяется точкой с запятой ( ; ) вместо двоеточия.

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

NODE_PATH по-прежнему поддерживается, но теперь он менее необходим, поскольку экосистема Node.js приняла соглашение о расположении зависимых модулей. Иногда развертывания, которые полагаются на NODE_PATH, демонстрируют удивительное поведение, когда люди не знают, что NODE_PATH должен быть установлен. Иногда зависимости модуля изменяются, что приводит к загрузке другой версии (или даже другого модуля) при поиске NODE_PATH.

Кроме того, Node.js будет искать в следующем списке GLOBAL_FOLDERS:

  • 1: $HOME/.node_modules
  • 2: $HOME/.node_libraries
  • 3: $PREFIX/библиотека/узел

Где $HOME – это домашний каталог пользователя, а $PREFIX – настроенный Node.js node_prefix .

В основном это связано с историческими причинами.

Настоятельно рекомендуется размещать зависимости в локальной папке node_modules. Они будут загружаться быстрее и надежнее.

Перед выполнением кода модуля Node.js поместит в него оболочку функции, которая выглядит следующим образом:

При этом Node.js достигает нескольких целей:

  • Он сохраняет переменные верхнего уровня (определенные с помощью var , const или let ) привязанными к модулю, а не к глобальному объекту.
  • Это помогает предоставить некоторые глобальные переменные, которые на самом деле специфичны для модуля, например:
    • Модуль и экспортирует объекты, которые разработчик может использовать для экспорта значений из модуля.
    • Вспомогательные переменные __filename и __dirname , содержащие абсолютное имя файла модуля и путь к каталогу.

    Имя каталога текущего модуля. Это то же самое, что и path.dirname() для __filename .

    Пример: запуск node example.js из /Users/mjr

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

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

    См. __dirname для имени каталога текущего модуля.

    Запуск node example.js из /Users/mjr

    Даны два модуля: a и b , где b – это зависимость от a, а структура каталогов состоит из:

    • /Users/mjr/app/a.js
    • /Users/mjr/app/node_modules/b/b.js

    Ссылки на __filename в b.js возвращают /Users/mjr/app/node_modules/b/b.js, а ссылки на __filename в a.js возвращают /Users/mjr/app/a.js .

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

    Ссылка на текущий модуль, см. раздел об объекте модуля. В частности, module.exports используется для определения того, что модуль экспортирует и делает доступным через require() .

    Используется для импорта модулей, JSON и локальных файлов. Модули можно импортировать из node_modules. Локальные модули и файлы JSON можно импортировать по относительному пути (например, ./, ./foo, ./bar/baz, ../foo ), который будет разрешен для каталога с именем __dirname (если он определен) или текущего рабочего каталога. Относительные пути в стиле POSIX разрешаются независимо от ОС, а это означает, что приведенные выше примеры будут работать в Windows так же, как и в системах Unix.

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

    Также возможно добавление или замена записей. Этот кеш проверяется перед нативными модулями, и если в кеш добавляется имя, соответствующее нативному модулю, только вызовы node: -prefixed require будут получать нативный модуль. Используйте с осторожностью!

    Проинструктируйте require о том, как обращаться с определенными расширениями файлов.

    Обрабатывать файлы с расширением .sjs как .js :

    Устарело. В прошлом этот список использовался для загрузки модулей, отличных от JavaScript, в Node.js путем их компиляции по запросу. Однако на практике есть гораздо лучшие способы сделать это, например загрузить модули через какую-либо другую программу Node.js или заранее скомпилировать их в JavaScript.

    Избегайте использования require.extensions . Использование может привести к незначительным ошибкам, и разрешение расширений становится все медленнее с каждым зарегистрированным расширением.

    Объект модуля, представляющий сценарий входа, загружаемый при запуске процесса Node.js, или неопределенный, если точка входа программы не является модулем CommonJS. См. «Доступ к основному модулю».

    В скрипте entry.js:

    Теперь поддерживается параметр paths.

    • request Путь к модулю для разрешения.
    • параметры
      • paths Пути для разрешения местоположения модуля. Если они присутствуют, эти пути используются вместо путей разрешения по умолчанию, за исключением GLOBAL_FOLDERS, таких как $HOME/.node_modules, которые всегда включаются. Каждый из этих путей используется в качестве отправной точки для алгоритма разрешения модулей, что означает, что иерархия node_modules проверяется из этого расположения.

      Используйте внутренний механизм require() для поиска местоположения модуля, но вместо загрузки модуля просто верните разрешенное имя файла.

      Если модуль не может быть найден, выдается ошибка MODULE_NOT_FOUND.

      • request Путь к модулю, пути поиска которого извлекаются.
      • Возвращает: |

      В каждом модуле свободная переменная модуля является ссылкой на объект, представляющий текущий модуль. Для удобства module.exports также доступен через файл exports module-global. модуль на самом деле не является глобальным, а скорее локальным для каждого модуля.

      Объекты модуля, необходимые для этого в первый раз.

      Объект module.exports создается системой модулей. Иногда это неприемлемо; многие хотят, чтобы их модуль был экземпляром некоторого класса. Для этого назначьте нужный объект экспорта в module.exports. Назначение нужного объекта экспорту просто перепривязывает локальную переменную экспорта, что, вероятно, не совсем то, что нужно.

      Например, предположим, что мы делаем модуль с именем a.js :

      Тогда в другом файле мы могли бы сделать:

      Назначение module.exports должно быть выполнено немедленно. Это невозможно сделать ни в каких обратных вызовах. Это не работает:

      Переменная exports доступна на уровне файла модуля, и ей присваивается значение module.exports перед оценкой модуля.

      Это позволяет сократить путь, так что module.exports.f = . можно записать более кратко как exports.f = . . Однако имейте в виду, что, как и любой переменной, если для exports присваивается новое значение, оно больше не привязано к module.exports :

      Когда свойство module.exports полностью заменяется новым объектом, обычно также переназначаются экспорты:

      Чтобы проиллюстрировать поведение, представьте эту гипотетическую реализацию require() , которая очень похожа на то, что на самом деле делает require() :

      Полностью разрешенное имя файла модуля.

      Идентификатор модуля. Обычно это полностью разрешенное имя файла.

      • Тип: true, если модуль запущен на этапе предварительной загрузки Node.js.

      Независимо от того, завершена ли загрузка модуля или находится в процессе загрузки.

      В Node.js любой файл, состоящий из кода JavaScript в файле, оканчивающемся на .js, является модулем. Модуль может содержать определения функций, классов, объектов или переменных, на которые можно ссылаться или которые можно использовать в другом файле Javascript.

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

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

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

      • Создание и экспорт модуля
      • Импорт модуля
      • Экспорт нескольких функций и значений из модуля
      • Импорт модуля из каталога
      • Типы модулей

      Чтобы следовать этому руководству, создайте каталог nodejs в своем домашнем каталоге или в любом другом месте.

      Перейдите в каталог nodejs.

      Теперь все готово, чтобы следовать руководству и практиковаться в коде.

      Создание и экспорт модуля

      Создание модуля

      Модули создаются в Node.js путем создания файла JavaScript. Каждый раз, когда вы создаете новый файл с расширением .js, он становится модулем.

      Давайте напишем наш первый модуль. Мы начнем с создания двух функций для выполнения простых вычислений.

      Введите следующий код и сохраните его как lib.js в каталоге nodejs.

      lib.js

      Файл lib.js теперь является модулем. Две функции add() и subtract доступны только в нашем файле. Они инкапсулированы, то есть к ним нельзя получить доступ за пределами файла. если вы попытаетесь вызвать их в другом файле, вы получите ошибку.

      В папке node.js. Создайте еще один файл main.js. Попробуем вызвать функцию add() в нашем файле.

      main.js

      Запустите файл с помощью node.js.

      Вы получите сообщение об ошибке.

      Экспорт модуля

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

      Давайте экспортируем функцию add() в файл lib.js.

      Перейдите в конец файла lib.js и добавьте module.exports = .

      lib.js

      Сейчас в нашем файле lib.js мы добавили функцию add() к объекту module.exports. Добавление функции в module.exports сделает ее доступной в любом файле, который импортирует модуль lib.js.

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

      Импорт модуля в Node.js

      Чтобы включить в Node.js функции, определенные в другом файле, нам нужно импортировать модуль. мы будем использовать ключевое слово require в верхней части файла.

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

      Чтобы увидеть это в действии, давайте импортируем модуль lib.js, потребовав его внутри файла main.js, и вызовем функцию add() с записью через точку.

      main.js

      Если мы запустим наш код сейчас, мы должны получить следующий результат:

      В приведенном выше коде происходит импорт модуля lib.js.

      При импорте файла lib.js важно добавить к нему префикс ./ внутри require . Это сообщает Node.js, что мы импортируем локальный модуль (модуль, созданный вами, например модуль lib.js).

      При запросе модуля вы можете не указывать расширение файла, как мы сделали require('./lib'), или указать расширение файла (.js) файла, который вы хотите импортировать.

      Когда require импортирует модуль, он возвращает объект с помощью add() в качестве метода и сохраняет его в переменной lib.

      Объект, возвращаемый функцией require, представляет собой объект module.exports из модуля lib.js, где мы экспортировали только один метод add() .

      Поскольку объект — это то, что возвращается функцией require , для доступа к функции add() мы использовали точечную нотацию, добавив префикс к имени объекта (lib), чтобы вызвать функцию add(4, 4) и затем сохранить результат в переменной результата.

      Экспорт нескольких функций и значений

      Есть несколько способов экспортировать несколько функций и значений с помощью module.exports .

      lib.js

      В файл main.js вы можете импортировать их следующим образом:

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

      Еще один способ экспортировать несколько функций — определить функции внутри объекта module.exports.

      lib.js

      Вы также можете определить каждую функцию независимо как метод module.exports .

      lib.js

      Импорт модуля из каталога

      Внутри каталога проекта создайте каталог maths и переместите в него файл lib.js.

      Чтобы импортировать файл lib.js в каталог, укажите lib.js, добавив к нему префикс с именем каталога.

      Типы модулей в Node.js

      • Локальные модули
      • Основные модули
      • Сторонние модули.

      Локальные модули

      Это модули, которые вы можете создать самостоятельно и использовать в своем приложении. Хорошим примером локального модуля является модуль lib.js, который мы создали и импортировали в файл main.js в этом руководстве.

      импорт локальных модулей

      Подводя итог, чтобы импортировать локальный модуль, вам нужно require('./filename') или require('./filename.js') или require('./path/filename.js') .

      Вам не нужно добавлять расширение «.js», Node.js может загрузить ваш локальный модуль и без него, как мы узнали.

      Основные модули

      Эти модули входят в состав Node.js по умолчанию. Вам не нужно загружать их в свой проект.

      Некоторыми из самых популярных и часто используемых основных модулей являются fs , os , path и т. д.

      Импорт основных модулей

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

      Сторонние модули

      Сторонние модули — это модули, загружаемые с помощью диспетчера пакетов, например npm. Эти модули обычно хранятся в папке node_modules.

      Вы можете устанавливать сторонние модули глобально или локально в своем проекте.

      Примерами сторонних модулей являются express , mongoose , react и т. д.

      Импорт сторонних модулей

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

      Заключение

      В этом руководстве мы рассмотрели, как создать и экспортировать модуль, импортировать модуль, а также рассмотрели различные способы экспорта нескольких функций и значений, а также различные типы модулей в Node.js.

      Если у вас есть идеи или предложения, не стесняйтесь оставлять комментарии.

      Категории: узел

      Обновлено: 26 марта 2020 г.

      Вам также может понравиться

      Обзор 2021 года и планы на 2022 год

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

      Обзор 2020 года

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

      Асинхронное программирование с обратными вызовами в JavaScript

      В этой статье вы узнаете о синхронном и асинхронном программировании в JavaScript. После этого вы узнаете значение обратного вызова.

      Понимание цепочки методов в JavaScript

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

      В этой статье мы рассмотрим несколько различных способов включения файлов JavaScript. Мы сделаем это в двух средах: одна будет JavaScript в браузере, а вторая будет использовать Node.js.

      Если у вас не установлен Node, узнайте, как установить Node.js здесь.

      Невозможно было включить JavaScript из другого JavaScript

      Раньше не было возможности включать файлы JS. Для этого не было механизма.

      К счастью, в наши дни, с распространением JavaScript и шаблонов модулей, у нас есть несколько способов сделать это.

      Две разные среды

      Как уже упоминалось, мы будем экспериментировать с двумя средами: браузером и Node.js.

      JavaScript в браузере

      Представим, что мы работаем над нашим веб-сайтом и хотим иметь один файл JavaScript, который включает в себя другой код JS. Итак, у нас есть следующие файлы index.html, app.js и xyz.js. Наш индекс будет ссылаться на app.js, и этот файл будет внутри содержать xyz.js. Вот эти файлы:

      Начнем с файла xyz.js, который мы будем импортировать.

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

      Это позволяет нам импортировать идентификатор в другой файл JavaScript. Вот оно:

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

      После этого мы можем просто вызвать функцию logXyz().

      Теперь нам просто нужно связать этот файл из нашего index.html.

      Это самый обычный HTML-файл, но обратите внимание на тег script.

      Мы должны указать здесь type="module", если мы хотим импортировать наш файл xyz.js.

      ПРИМЕЧАНИЕ. Чтобы запустить эти примеры, вам необходимо разместить эти файлы на каком-либо локальном хосте. Простой способ сделать это — установить текстовый редактор Brackets, который по умолчанию имеет предварительный просмотр в реальном времени, и вы можете использовать JavaScript из коробки. Другой способ — установить редактор кода VSCode и добавить расширение Live Server. Извините за это.

      Теперь, когда мы обслуживаем наш index.html и открываем консоль JavaScript. Мы увидим запись XYZ. Потрясающе!

      Включить несколько функций

      Чтобы иметь несколько доступных функций, нам нужно просто добавить их в качестве наших идентификаторов, например:

      А также аналогичным образом настройте наш app.js:

      Функция прямого экспорта JavaScript

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

      Хорошо, вот как мы включаем файлы JavaScript в другой файл JavaScript при работе с браузерным JavaScript. Теперь давайте посмотрим на решения Node.js.

      Node.js не импортирует

      Да, это правда. На момент написания этой статьи Node.js не поддерживал импорт ES6. У узла свой путь. На самом деле Node сильно зависит от концепции модулей.

      Давайте импортируем несколько файлов в среду Node.js.

      Здесь модуль module.exports может показаться немного запутанным, но это основной модульный механизм Node.js. Просто подумайте об этом на пустом объекте, это в основном то, что есть. Все, что мы делаем, это добавляем атрибут к объекту модуля, и это наша функция sayXYZ.

      Теперь перейдем к app.js.

      Requirement — это способ импорта Node. Когда вы работаете с Node, вы видите его повсюду. Требуются модули слева и справа.

      Интересно, что require возвращает объект module.exports с добавленным атрибутом, который является нашей функцией sayXyz. xyz — это объект в данном случае.

      Теперь, если мы запустим app.js из нашего терминала с Node, мы получим XYZ, напечатанный на консоли.

      Если мы хотим экспортировать несколько функций, мы просто добавляем еще один атрибут к объекту module.exports следующим образом:

      Вот еще два пути к тому же результату. Во-первых, мы делаем module.exports равным объекту, который мы создаем. С атрибутом функции.

      И последний, пожалуй, самый знакомый способ:

      Импорт бонусного узла

      Если вы действительно хотите использовать импорт в своей среде Node, вы можете сделать это с помощью Babel. Babel – это компилятор JavaScript, который делает современный код JavaScript доступным в старых несовместимых средах JavaScript.

      Не превращая его в модуль, вы также можете включить файл в другой с функциями Node.

      В командной строке интерпретатор JavaScript не может сам включить файл в файл, который он интерпретирует, поскольку он предназначен для обработки файлов, уже загруженных в память браузером. Но с помощью модуля Node vm для загрузки файла мы можем заменить браузер. Vm — это основной модуль, который вам не нужно устанавливать.

      Например, мы хотим загрузить файл extfile.js со следующим содержимым:

      В основной файл импортированы модули fs и vm, а также добавлена ​​функция загрузки:

      Это можно сократить до одной инструкции:

      Затем в первом файле JavaScript можно напрямую использовать переменные и функции, содержащиеся во включенных файлах:

      Который отображает "hello external" и "500".

      Код демо включен в архив для скачивания.

      У этого метода есть два недостатка:

      1. Файл не предоставляет доступ к переменным, объявленным в основном файле.
      2. Вы не можете использовать функцию require во включенном файле, потому что vm использует V8 и поэтому игнорирует функции Node.
      3. Поэтому вы не можете использовать стандартную библиотеку во включенном файле.

      Для доступа к глобальному контексту, в том числе к объектам, назначенным require, вместо этого необходимо использовать функцию eval:

      Что устраняет все предыдущие ограничения. Добавление пустой строки в конец кода, загружаемого с помощью readFileSync, очень важно.

      Использование браузера

      Предыдущий метод необходим, если мы хотим взаимодействовать с программой из командной строки (используя fs.readSync для ввода данных).

      Если мы просто хотим отобразить результаты работы программы, мы также можем пропустить модуль загрузки с помощью браузера и сгенерировать результаты на HTML-странице. Код основного файла будет таким:

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

      Этот второй метод, вероятно, более эффективен, чем использование модуля vm или eval, но требует замены console.log на документ.запись.

      Файл для частого включения

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

      Имя модуля должно быть добавлено в качестве префикса, чтобы использовать его содержимое:

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

      Читайте также: