require nodejs что это

Основы работы с модулями в Node.js

Любой проект посложнее «Hello World» состоит из некоторого количества файлов, по которым разносят код. Это дает возможность структурировать проект, вынести независимые части, которые можно будет использовать в других проектах и вообще сделать код нагляднее.

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

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

Поэтому нет необходимости указывать файл с расширением, так как require(‘./lib/users.js’) и require(‘./lib/users’) подключит один и тот же модуль.

Представим, что у нас есть модули и один и них logger представлен в виде папки с файлами:

Подключение модуля logger заключается в том, что мы просто передадим путь к этой папки:

Дальше Node.js сам попытается определить какой из файлов папки представляет собой точку входа для модуля. Для начала будет проверено или существует в папке файл package.json в котором будет указано в поле main имя файла, который нужно подключить.

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

Это поведение можно изменить, если после каждого вызова модуля удалять его из кэша.

module — это параметр, который вы передавали функции require для подключения модуля.

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

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

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

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

В объекта module есть свойство exports и ему нужно присваивать все что вы хотите вернуть из модуля. Именно module.exports вернется как результат подключения модуля.

После подключения модуля с данным кодом, в ответе будет объект с данным методом.

Источник

nodejs основы

NODE.JS – программное средство для выполнения js.

Nodejs = V8 + I/O + библиотеки

V8: быстро, современно, экономно

Преимущества

Установка

при установке nodejs прописывает себя в переменную PATH (+ npm), [администрирование – переменные среды]; можно проверить в командной строке:
set PATH

Как правило под nodejs запускают файлы: напишем простой скрипт и запустим его посредством командной строки:

Скрипт будет выполнен и результат отобразится в командной строке.

Документация по nodejs

Модули nodejs

Функции растут (проект развивается) и со временем нам потребуется вынести функцию-конструктор USER в отдельный файл. Вот тут-то в дело вступают модули.

Модули этого своего рода способ, который предлагает nodejs для организации проекта.

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

require

Модуль-директория DIR/index

exports – это объект и то, что туда положено, вернется как результат require (exports.jpg). Таким образом модуль может объявить свои приватные переменные/функции и экспортировать лишь то, что необходимо.

Для глобальных переменных и т.д. существует объект global

Итог

Объект module

Модуль или приложение? module.parent

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

пс: как говорится на stackoverflow.com Родетелем является модуль, который вызвал скрипт для интерпретации

Правильное использование module.exports

В контексте модуля:

module.exports = exports = this (данные конструкции равнозначны)

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

Кеширование модулей

В нашем случае для var db = require(«../db»);
и для var db = require(«./db»); берется один и тот же объект. Поэтому принцип следующий: в первый раз, когда используется модуль, он инициализируется и в дальнейшем мы его только подключаем и пользуемся им (то есть в нашем случае нам не нужно использовать db.connect() дважды, то есть в разных файлах).

Расположение модулей: порядок поиска модулей в nodejs

Как сделать так, чтобы db подключалась всегда без указания специфичного пути:

Если же указать require(«db»); и при этом модуль не является встроенным, то будет произведен поиск директории node_modules относительно текущего положения (если найдет, то попытается взять модуль из нее). Если директория node_modules отсутствует, то директория node_modules будет искаться выше и т.д.

Помимо указания конкретного пути для модуля, nodejs может искать модули следующим образом:

Введение в npm – менеджер пакетов для Node.JS

Модуль npm идет вместе со стандартной установкой node. В этом модуле содержится консольная утилита ( npm ), которая дает доступ к громадной базе данных модулей. (https://www.npmjs.com/ ) Как правило, если стоит стандартная задача по программированию, то модуль для нее найти не составит труда. Для того чтобы поделиться модулем с другими людьми необходимо:

Вывод по npm:

npm init
nmp adduser
npm publish
npm search ключевые слова
npm install модуль
npm update модуль
npm remove модуль
npm help команда

Структура пакета NPM

Установка нужной версии, например: npm i express@3.0.0

Последнюю версию модуля можно получить в том случае, если модуль разрабатывается, используя систему версинирования git, например, на github. Достаточно получить Git Read-Only (url): https://github.com/strongloop/express.git и в консоли:

Читайте также:  орлова что где когда биография

npm i https://github.com/strongloop/express.git

dependencies в package.json

dependencies указывает на те модули, от которых зависит данный.

devDependencies

Модули прописанные в devDependencies не ставятся, если модуль подтягивается как зависимость. Они ставятся лишь для разработки и их можно установить, если, например, зайти в модуль в папке node_modules и прописать npm i (или при установке флага npm config).

поле main задает точку входа в пакет

Глобальные модули

Источник

Модули: модули CommonJS¶

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

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

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

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

В square модуль определен в square.js :

Модульная система реализована в require(‘module’) модуль.

Доступ к основному модулю¶

Советы менеджера пакетов¶

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

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

Поскольку Node.js ищет realpath любых загружаемых модулей (то есть разрешает символические ссылки), а затем ищет их зависимости в node_modules папки, эту ситуацию можно разрешить с помощью следующей архитектуры:

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

Все вместе. ¶

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

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

Кеширование¶

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

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

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

Предупреждения о кешировании модулей¶

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

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

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

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

Основные модули также можно идентифицировать с помощью node: префикс, и в этом случае он обходит require кеш. Например, require(‘node:http’) всегда будет возвращать встроенный HTTP-модуль, даже если есть require.cache запись с этим именем.

Циклы¶

Когда есть круговые require() вызовы, модуль мог не завершить выполнение, когда он был возвращен.

Рассмотрим эту ситуацию:

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

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

Файловые модули¶

Папки как модули¶

Удобно организовать программы и библиотеки в автономные каталоги, а затем предоставить единую точку входа в эти каталоги. Существует три способа передачи папки в require() как аргумент.

Это степень осознания package.json файлы в Node.js.

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

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

Загрузка из node_modules папки¶

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

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

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

Загрузка из глобальных папок¶

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

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

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

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

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

Это в основном по историческим причинам.

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

Оболочка модуля¶

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

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

Объем модуля¶

__dirname ¶

Пример: бег node example.js из /Users/mjr

__filename ¶

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

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

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

Бег node example.js из /Users/mjr

exports ¶

module ¶

require(id) ¶

require.cache ¶

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

Читайте также:  повелитель стихий азула актриса

require.extensions ¶

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

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

require.main ¶

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

В entry.js сценарий:

require.resolve(request[, options]) ¶

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

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

require.resolve.paths(request) ¶

В module объект¶

module.children ¶

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

module.exports ¶

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

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

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

exports ярлык¶

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

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

module.filename ¶

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

module.id ¶

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

module.isPreloading ¶

module.loaded ¶

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

module.parent ¶

Модуль, который первым требовал этого, или null если текущий модуль является точкой входа текущего процесса, или undefined если модуль был загружен чем-то, что не является модулем CommonJS (например: REPL или import ).

Источник

Модули JavaScript

При разработке front-end части приложения на языке JavaScript, мы можем столкнуться с рядом традиционных проблем. Все они решаются при помощи модульных подходов. Ниже мы рассмотрим самые популярные подходы для описания модулей в JavaScript, которые существуют на сегодняшний день.

Итак, какие проблемы имеются в виду:

Большие файлы. Довольно часто возникает такая ситуация, когда в проекте есть файлы, названные в стиле app.js или common.js, в которых все просто свалено в одну кучу: функции, хелперы, виджеты и т.д. Работать и поддерживать код в таких файлах довольно тяжело. Приходится постоянно прокручивать туда-сюда, выискивая нужный кусочек кода, ставить много закладок при помощи IDE, чтобы не потерять нужные места в файле. Также есть тенденция, что чем больше размер файла, который содержит в себе кучу общей логики, тем быстрее он продолжает расти. Плюс ко всему, в большой команде это может стать причиной постоянных конфликтов в системе контроля версий.

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

Неструктурированный и не очевидный код. Еще одна довольно неприятная ситуация — когда нет четких границ, разделяющих логические куски кода. Когда, не вникая в код, сразу и не скажешь, какие другие части приложения он использует.

Первые модули

Изначально в JS не было возможности создавать настоящие модули. Хотя раньше это и не требовалось: на сайтах было относительно маленькое количество JS-кода. В основном нужно было где-то «прикрутить карусель», где-то красивое анимированное меню, и на этом все. Но затем web-приложения по сложности интерфейса и насыщенной функциональности начали догонять традиционные настольные. И тогда стал популярным так называемый паттерн «модуль».

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

CommonJS

Первый стандарт, который описывает API для создания и подключения модулей, был разработан рабочей группой CommonJS. Этот стандарт был придуман для использования в серверном JS, и его реализацию можно увидеть, например, в node.js.

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

НО! В браузере, просто так, такой синтаксис не заработает. Для этого нужно использовать специальный сборщик. Например, популярны browserify или Brunch, которые работают на node.js. Эти инструменты довольно удобны, их функциональность не ограничивается только лишь возможностью создавать CommonJS-модули, и многие разработчики предпочитают использовать их в своих проектах. Суть у них одинакова: сборщик проходится по дереву зависимостей модулей и собирает все в один файл, который в свою очередь будет загружаться браузером. Даже при разработке в debug-режиме нужно постоянно запускать сборщик из командной строки, или, что удобнее, запускать watcher, который будет следить за изменениями в файлах и автоматически производить сборку. Стоит заметить, что отлаживать приходится не исходные файлы, а то, что сгенерирует сборщик. Если вы не планирует отлаживать ваш код в старых браузерах, то это не будет проблемой, потому что сборщики умеют генерировать Source Maps, благодаря которым результирующий сжатый файл будет связан с исходниками. Это позволит вести отладку так, как будто вы работаете с самим исходным кодом. Также, сборка в один файл — это не всегда хорошо. Например, если мы хотим подгружать модуль удаленно, с CDN, или загружать часть кода только по требованию.

Будущее уже наступило

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

Читайте также:  Узи вен для чего

Один модуль, как и в CommonJS, — это один файл. Область видимости также ограничена этим файлом. Ключевое слово export экспортирует нужные значения в остальные части программы. Его можно использовать где угодно: посреди кода модуля или в конце, экспортируя все скопом.

…или сразу несколько.

Либо можно импортировать весь модуль в качестве объекта со всеми экспортированными значениями.

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

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

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

В качестве единственного параметра необходимо передавать путь к модулю. В результате выполнения System.import() возвращается объект Promise. Таким образом, поток выполнения не блокируется и код, который не имеет отношения к импорту модуля, будет выполняться дальше.

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

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

Вот уже несколько лет подход под названием Asynchronous Module Definition позволяет разбивать код приложений на модули во всех популярных браузерах (IE6+), используя при этом только возможности браузера.

AMD — это подход к разработке, который позволяет создавать модули таким образом, чтобы они и их зависимости могли быть загружены асинхронно и параллельно. Это позволяет ускорить загрузку страницы, так как загрузка JS-модулей не будет блокировать загрузку остального контента сайта. Плюс, AMD дает возможность загружать модули по мере их востребованности. Например, есть страница со сложным модальным окном, в котором сосредоточено много логики: разные «визарды», несколько форм и т.д. При этом предполагается, что окно будет использоваться крайне редко. В таком случае, AMD позволяет загружать JS-код для этого окна не со страницей, а перед тем, как оно будет открыто пользователем.

Самая популярная реализация подхода AMD — библиотека RequireJS.

RequireJS

Скачать библиотеку можно с официального сайта, или же можно воспользоваться любым популярным пакетным менеджером. Например, с NuGet можно установить ее, выполнив команду Install-Package RequireJS.

В RequireJS методы require и define имеют несколько вариаций.

Метод define может принимать три параметра:

Первый параметр — это id модуля. id можно использовать вместо пути к файлу, чтобы подключить модуль как зависимость другого модуля, но только когда файл с кодом модуля уже был загружен в браузере. На самом деле, это необязательный параметр. И не просто необязательный, его даже нежелательно использовать в разработке. Он, скорее, нужен для корректного управления зависимостями в том случае, если в одном файле определено сразу несколько модулей. Оптимизационный инструмент, использующийся для сборки модулей в один файл для production, автоматически добавляет эти id.

define может принимать только остальные два параметра:

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

Есть одна проблема — вызов define может выглядеть вот так:

Также можно определить модуль как простой объект.

Такие модули удобно использовать как набор констант.

Есть возможность делать вложенные вызовы require внутри callback-функции или внутри определения модуля.

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

Подключение

При помощи первого параметра baseUrl можно указать путь, относительно которого будут загружаться все JS-файлы. Если файлы вдруг переедут в другое место, то достаточно в одном месте поменять корневой путь. Если его не указать, то базовой будет директория, в которой находится файл самой библиотеки require.js. Параметр path позволяет «мапить» пути к модулям, чтобы использовать потом более короткие варианты.

RequireJS позволяет загружать не только JS-файлы, но и, например, HTML, используя плагин text.

В данном примере require загрузит файл module.html и вернет строку, содержащую HTML-код файла. Это удобно для работы с клиентскими шаблонами, не нужно мучатся с HTML-кодом внутри JS-файлов.

Сборка

Загружать много мелких файлов удобно при разработке и отладке, но не очень производительно, поэтому не подходит для production. И тут на помощь приходит утилита оптимизации r.js, которая идет в поставке с require.js.

Работает эта утилита на JS, поэтому на компьютере должен быть установлен node.js. Перед тем как запускать оптимизацию, нужно ее сконфигурировать. Для этого в приложении нужно создать файл app.build.js, который будет содержать обычный JS-объект с набором параметров.

Будет удобно добавить эту команду, например, в pre-build event в Visual Studio, чтобы JS-код собирался в тот же момент, когда запускается компиляция проекта.

Profit

Итак, выгоды, которые дает использование RequireJS:

Источник

Обучающий онлайн портал