Чи існують бібліотеки для JavaScript у браузері, що забезпечують таку ж гнучкість / модульність / простоту використання, що і Node require
?
Щоб надати докладніше: причина require
настільки вагома, що вона:
- Дозволяє динамічно завантажувати код з інших місць (що, на мій погляд, стилістично краще, ніж зв’язування всього вашого коду в HTML)
- Він забезпечує послідовний інтерфейс для побудови модулів
- Модулям легко залежати від інших модулів (щоб я міг написати, наприклад, API, який вимагає jQuery, щоб я міг використовувати
jQuery.ajax()
- Завантажений javascript масштабується , це означає, що я міг завантажувати
var dsp = require("dsp.js");
і мав би доступdsp.FFT
, що не заважало б моєму локальномуvar FFT
Я ще не знайшов бібліотеки, яка б це ефективно робила. Рішення, якими я схильний користуватися, є:
coffeescript-concat - досить просто вимагати інших js, але вам потрібно його скомпілювати, а це означає, що він менш придатний для швидкої розробки (наприклад, побудова API в тесті)
RequireJS - Він популярний, простий і вирішує 1-3, але відсутність обсягу дійсно порушує дію (я вважаю, що head.js схожий тим, що йому бракує масштабу, хоча у мене ніколи не було жодної нагоди використовувати його. Подібним чином LABjs може завантажувати та усунути
.wait()
проблеми залежності, але все одно не робить масштабування)
Наскільки я можу зрозуміти, здається, існує багато рішень для динамічного та / або асинхронного завантаження javascript, але вони, як правило, мають такі ж проблеми з обсягом, як просто завантаження js з HTML. Більше за все інше, я хотів би завантажити javascript, який взагалі не забруднює глобальний простір імен, але все ж дозволяє завантажувати та використовувати бібліотеки (як це вимагає вузол).
ОНОВЛЕННЯ 2020: Модулі тепер є стандартними для ES6, а станом на середину 2020 року підтримуються більшістю браузерів . Модулі підтримують як синхронне, так і асинхронне (з використанням Promise) завантаження. Поточна моя рекомендація полягає в тому, що в більшості нових проектів слід використовувати модулі ES6 та використовувати транслятор, щоб повернутися до одного файлу JS для застарілих браузерів.
Як загальний принцип, пропускна здатність сьогодні також набагато ширша, ніж коли я спочатку задавав це питання. Отже, на практиці ви можете обґрунтовано вибрати завжди використовувати транспілер з модулями ES6 і зосередити свої зусилля на ефективності коду, а не на мережі.
ПОПЕРЕДНЕ РЕДАКТУВАННЯ (або якщо вам не подобаються модулі ES6): З моменту написання цього тексту я широко використовував RequireJS (який тепер має набагато чіткішу документацію). На мою думку, RequireJS справді був правильним вибором. Я хотів би пояснити, як система працює для людей, які так само розгублені, як і я:
Ви можете використовувати require
в повсякденному розвитку. Модулем може бути будь-що, що повертається функцією (як правило, об’єктом або функцією) і визначається як параметр. Ви також можете скомпілювати свій проект в один файл для розгортання r.js
(на практиці це майже завжди швидше, хоча require
паралельно можна завантажувати сценарії).
Основна відмінність між RequireJS та стилем node вимагає, як browserify (класний проект, запропонований tjameson), - це спосіб розробки та необхідності модулів:
- RequireJS використовує AMD (Визначення асинхронного модуля). В AMD
require
бере список модулів (файли javascript) для завантаження та функцію зворотного виклику. Коли він завантажує кожен з модулів, він викликає зворотний виклик з кожним модулем як параметр зворотного виклику. Таким чином, це справді асинхронно і, отже, добре підходить для Інтернету. - Вузол використовує CommonJS. У CommonJS
require
- це виклик блокування, який завантажує модуль і повертає його як об'єкт. Це чудово працює для Node, оскільки файли зчитуються з файлової системи, що досить швидко, але погано працює в Інтернеті, оскільки синхронне завантаження файлів може зайняти набагато більше часу.
На практиці багато розробників використовували Node (а отже і CommonJS) ще до того, як побачити AMD. Крім того, багато бібліотек / модулів написано для CommonJS (шляхом додавання речей до exports
об'єкта), а не для AMD (поверненням модуля з define
функції). Тому багато розробників веб-вузлів хочуть використовувати бібліотеки CommonJS в Інтернеті. Це можливо, оскільки завантаження з <script>
тегу блокує. Такі рішення, як browserify, беруть модулі CommonJS (Node) і обгортають їх, щоб ви могли включати їх за допомогою тегів сценаріїв.
Тому, якщо ви розробляєте власний багатофайловий проект для Інтернету, я настійно рекомендую RequireJS, оскільки це справді модульна система для Інтернету (хоча при чесному розкритті я вважаю AMD набагато природнішим, ніж CommonJS). Останнім часом розрізнення стає менш важливим, оскільки RequireJS тепер дозволяє по суті використовувати синтаксис CommonJS. Крім того, RequireJS можна використовувати для завантаження модулів AMD у Node (хоча я віддаю перевагу node-amd-loader ).