Существуют ли библиотеки для JavaScript в браузере, обеспечивающие такую же гибкость / модульность / простоту использования, как у Node's require
?
Чтобы предоставить более подробную информацию: причина require
настолько хороша, что она:
- Позволяет динамически загружать код из других мест (на мой взгляд, стилистически лучше, чем связывать весь ваш код в HTML)
- Предоставляет согласованный интерфейс для построения модулей
- Для модулей легко зависеть от других модулей (так что я мог бы написать, например, API, который требует jQuery, чтобы я мог использовать
jQuery.ajax()
- Загруженный javascript имеет значение scoped , что означает, что я могу загрузить с помощью
var dsp = require("dsp.js");
, и я смогу получить доступ к dsp.FFT
, что не будет мешать моему локальному var FFT
Мне еще предстоит найти библиотеку, которая делает это эффективно. Обходные пути, которые я обычно использую:
coffeescript-concat - достаточно просто потребовать другие js, но вы должны скомпилировать его, что означает, что он менее хорош для быстрой разработки (например, для создания тестируемых API)
RequireJS - Это популярно, просто и решает 1-3, но недостаток области видимости действительно нарушает условия сделки (я думаю, что head.js похож в том смысле, что ему не хватает области видимости, хотя у меня никогда не было возможности его использовать. Точно так же LABjs может загружать и .wait()
действительно смягчает проблемы с зависимостями, но все равно не определяет область видимости)
Насколько я могу судить, кажется, что существует много решений для динамической и / или асинхронной загрузки javascript, но они, как правило, имеют те же проблемы с областью видимости, что и просто загрузка js из HTML. Больше всего на свете мне нужен способ загрузки javascript, который вообще не загрязняет глобальное пространство имен, но все же позволяет загружать и использовать библиотеки (так же, как это требуется для узла).
РЕДАКТИРОВАТЬ (МОЙ ОТВЕТ): С момента написания этого я широко использовал RequireJS (который теперь имеет гораздо более четкую документацию). RequireJS действительно был правильным выбором на мой взгляд. Я хотел бы уточнить, как система работает для людей, которые так же запутались, как и я:
Вы можете использовать require
в повседневной разработке. Модуль может быть чем угодно, возвращаемым функцией (обычно объектом или функцией) и имеет область видимости в качестве параметра. Вы также можете скомпилировать проект в один файл для развертывания, используя r.js
(на практике это почти всегда быстрее, даже если require
может загружать сценарии параллельно).
Основное отличие между RequireJS и стилем узла, например, в виде browserify (классный проект, предложенный tjameson), заключается в том, как спроектированы и необходимы модули:
- RequireJS использует AMD (определение модуля Async). В AMD
require
принимает список модулей (файлы javascript) для загрузки и функцию обратного вызова. Когда он загрузил каждый из модулей, он вызывает обратный вызов с каждым модулем в качестве параметра обратного вызова. Таким образом, он действительно асинхронный и поэтому хорошо подходит для Интернета.
- Узел использует CommonJS. В CommonJS
require
- это блокирующий вызов, который загружает модуль и возвращает его как объект. Это нормально работает для Node, поскольку файлы считываются из файловой системы, что достаточно быстро, но плохо работает в Интернете, поскольку синхронная загрузка файлов может занять гораздо больше времени.
На практике многие разработчики использовали Node (и, следовательно, CommonJS) еще до того, как увидели AMD. Кроме того, многие библиотеки / модули написаны для CommonJS (путем добавления объектов в объект exports
), а не для AMD (путем возврата модуля из функции define
). Таким образом, многие разработчики Node, ставшие веб-пользователями, хотят использовать библиотеки CommonJS в Интернете. Это возможно, поскольку загрузка из тега <script>
блокируется. Решения, такие как browserify, принимают модули CommonJS (Node) и упаковывают их, чтобы вы могли включать их в теги сценария.
Поэтому, если вы разрабатываете свой собственный многофайловый проект для Интернета, я настоятельно рекомендую RequireJS, поскольку это действительно модульная система для Интернета (хотя, если честно, я считаю AMD гораздо более естественной, чем CommonJS). В последнее время это различие стало менее важным, поскольку RequireJS теперь позволяет вам по существу использовать синтаксис CommonJS. Кроме того, RequireJS можно использовать для загрузки модулей AMD в Node (хотя я предпочитаю node-amd-loader ).