Чи існують бібліотеки для 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 ).