RequireJS в Node
- Разве в Node уже есть загрузчик модулей?
- Могу ли я использовать серверные модули, написанные в формате модулей CommonJS?
- Как его использовать?
Разве в Node уже есть загрузчик модулей?
Да, в Node есть. Этот загрузчик использует формат модулей CommonJS. Формат модулей CommonJS является не оптимальным для браузера, и я не согласен с некоторыми компромиссами, принятыми в формате модулей CommonJS. Используя RequireJS на сервере, вы можете использовать один формат для всех ваших модулей, независимо от того, работают ли они на стороне сервера или в браузере. Таким образом, вы сможете сохранить преимущества скорости и удобства отладки, которые вы получаете с RequireJS в браузере, и не будете беспокоиться о дополнительных затратах на перевод при переходе между двумя форматами.
Если вы хотите использовать define() для своих модулей, но всё равно запустить их в Node без необходимости запуска RequireJS на сервере, см. раздел ниже об использовании amdefine.
Могу ли я использовать модули Node, уже написанные в формате модулей CommonJS?
Да! Адаптер Node для RequireJS, называемый r.js, будет использовать реализацию require в Node и пути поиска Node, если модуль не найден с использованием конфигурации, используемой RequireJS, поэтому вы можете продолжить использование ваших существующих модулей на основе Node, не внося в них изменений.
RequireJS сначала будет использовать свои Параметры конфигурации. Если RequireJS не может найти модуль с использованием своей конфигурации, предполагается, что это модуль, использующий тип модулей и конфигурацию Node. Поэтому настраивайте расположения модулей только с помощью RequireJS, если они используют API RequireJS. Для модулей, которые ожидают API, конфигурацию/пути Node, просто установите их с помощью менеджера пакетов Node, например npm, и не настраивайте их расположение с помощью RequireJS.
Лучшая практика: используйте npm для установки пакетов/модулей только для Node в директорию node_modules проекта, но не настраивайте RequireJS для поиска внутри директории node_modules. Также избегайте использования относительных идентификаторов модулей для ссылки на модули, которые являются только модулями Node. Поэтому не делайте что-то вроде require("./node_modules/foo/foo").
Дополнительные замечания:
- RequireJS в Node может загружать только модули, которые находятся на локальном диске — загрузка модулей через http, например, в настоящее время не поддерживается.
- Параметры конфигурации RequireJS, такие как map, packages, paths, применяются только если RequireJS загружает модуль. Если RequireJS должен обратиться к системе модулей Node, оригинальный идентификатор передаётся в Node. Если вам нужен модуль Node, работающий с конфигурацией map, работают встроенные вызовы define(), как показано в этой теме форума.
Как его использовать?
Существует два способа получения адаптера Node:
npm
Используйте npm для его установки:
npm install requirejs
Этот вариант установит последнюю версию.
Загрузка r.js
Если вы предпочитаете не использовать npm, вы можете получить r.js напрямую:
- Загрузите r.js со страницы загрузки и поместите его в свой проект.
- Получите исходный код из репозитория r.js и либо сгенерируйте r.js с помощью "node dist.js", либо возьмите снимок из директории dist.
Использование
Эти инструкции предполагают установку 'requirejs' с помощью npm. Если вы используете файл r.js напрямую, замените require('requirejs') на require('./path/to/r.js'). Основное использование:
- require('requirejs')
- Передайте функцию "require" основного файла js в конфигурацию для requirejs.
Пример:
var requirejs = require('requirejs');
requirejs.config({
//Pass the top-level main.js/index.js require
//function to requirejs so that node modules
//are loaded relative to the top-level JS file.
nodeRequire: require
});
requirejs(['foo', 'bar'],
function (foo, bar) {
//foo and bar are loaded according to requirejs
//config, but if not found, then node's require
//is used to load the module.
});
Убедитесь, что вы прочитали примечания в разделе 2 о настройке RequireJS, чтобы он мог загружать только модули Node, установленные с помощью npm.
Чтобы увидеть более полный пример, в котором загружается модуль с помощью RequireJS, но используются модули Node для других вещей, см. встроенный тест в репозитории r.js.
Примечание: requirejs([], function() {}) будет вызывать функцию обратного вызова асинхронно в RequireJS 2.1+ (в более ранних версиях она вызывалась синхронно). Однако при запуске в Node загрузка модулей будет загружаться с использованием синхронных вызовов IO, а плагины загрузчика должны решать вызовы в их методе load синхронно. Это позволяет синхронно использовать модуль requirejs в node с помощью вызовов requirejs('stringValue'):
//Retrieves the module value for 'a' synchronously
var a = requirejs('a') Создание модулей node с AMD или RequireJS
Если вы хотите создать модуль, который будет работать с RequireJS и в Node, без необходимости использования RequireJS пользователями вашей библиотеки в Node, вы можете использовать пакет amdefine для этого:
if (typeof define !== 'function') {
var define = require('amdefine')(module);
}
define(function(require) {
var dep = require('dependency');
//The value returned from the function is
//used as the module export visible to Node.
return function () {};
});
Оптимизатор RequireJS, начиная с версии 1.0.3, будет удалять использование 'amdefine' выше, поэтому его безопасно использовать для ваших веб-проектов тоже. Просто убедитесь, что используете точное выражение if с 'amdefine' и его содержимое, как показано выше. Различия в пробелах/переводах строк разрешены. См. проект amdefine для получения дополнительной информации.
Если вы хотите использовать RequireJS напрямую для кодирования вашего модуля, а затем экспортировать значение модуля в Node, чтобы его можно было использовать в других программах Node без необходимости использования RequireJS в этой программе, вы можете использовать подход, указанный в следующем примере.
Лучше всего установить baseUrl конкретно в каталог, содержащий модуль, чтобы он работал правильно, когда он вложен внутри иерархии node_modules. Используйте синхронный requirejs('moduleId') для получения модуля с помощью конфигурации и правил в requirejs, а затем используйте Node's module.exports для экспорта значения вашего модуля:
var requirejs = require('requirejs');
requirejs.config({
//Use node's special variable __dirname to
//get the directory containing this file.
//Useful if building a library that will
//be used in node but does not require the
//use of node outside
baseUrl: __dirname,
//Pass the top-level main.js/index.js require
//function to requirejs so that node modules
//are loaded relative to the top-level JS file.
nodeRequire: require
});
//foo and bar are loaded according to requirejs
//config, and if found, assumed to be an AMD module.
//If they are not found via the requirejs config,
//then node's require is used to load the module,
//and if found, the module is assumed to be a
//node-formatted module. Note: this synchronous
//style of loading a module only works in Node.
var foo = requirejs('foo');
var bar = requirejs('bar');
//Now export a value visible to Node.
module.exports = function () {};
Использование оптимизатора как модуля Node
Модуль Node также предоставляет оптимизатор RequireJS в качестве метода optimize для использования оптимизатора RequireJS через вызов функции вместо инструмента командной строки:
var requirejs = require('requirejs');
var config = {
baseUrl: '../appDir/scripts',
name: 'main',
out: '../build/main-built.js'
};
requirejs.optimize(config, function (buildResponse) {
//buildResponse is just a text output of the modules
//included. Load the built file for the contents.
//Use config.out to get the optimized file contents.
var contents = fs.readFileSync(config.out, 'utf8');
}, function(err) {
//optimization err callback
});
Это позволяет создавать другие рабочие процессы оптимизации, такие как веб-строитель, который может быть использован, если вы предпочитаете всегда разрабатывать с подходом "один файл скрипта включён перед тегом </body>". Оптимизатор, работающий в Node, достаточно быстрый, но для больших проектов, которые не хотят перегенерировать сборку для каждого запроса браузера, а только если вы измените скрипт, который является частью сборки. Вы можете использовать Node's fs.watchFile() для отслеживания файлов и запуска сборки при изменении файла.
Обратная связь
Если у вас возникла проблема и вы хотите сообщить об этом, используйте страницу GitHub Issues r.js.
© jQuery Foundation and other contributors
Licensed under the MIT License.
http://requirejs.org/docs/node.html