Ось більш конкретний приклад.
Я працюю над проектом із 60 файлами. У нас є 2 різних режими його роботи.
Завантажте з'єднану версію, 1 великий файл. (Виробництво)
Завантажте всі 60 файлів (розробка)
Ми використовуємо завантажувач, тому у нас просто один сценарій на веб-сторінці
<script src="loader.js"></script>
Це за замовчуванням у режимі №1 (завантаження одного великого об'єднаного файлу). Для запуску в режимі №2 (окремі файли) встановлюємо деякий прапор. Це може бути що завгодно. Ключ у рядку запиту. У цьому прикладі ми просто робимо це
<script>useDebugVersion = true;</script>
<script src="loader.js"></script>
loader.js виглядає приблизно так
if (useDebugVersion) {
injectScript("app.js");
injectScript("somelib.js");
injectScript("someotherlib.js");
injectScript("anotherlib.js");
... repeat for 60 files ...
} else {
injectScript("large-concatinated.js");
}
Сценарій збірки - це просто .sh-файл, який виглядає приблизно так
cat > large-concantinated.js app.js somelib.js someotherlib.js anotherlib.js
тощо ...
Якщо буде доданий новий файл, ми, швидше за все, будемо використовувати режим №2, оскільки ми займаємося розробкою, ми повинні додати injectScript("somenewfile.js")
рядок до loader.js
Тоді пізніше для виробництва нам також потрібно додати somenewfile.js до нашого сценарію збирання. Крок ми часто забуваємо, а потім отримуємо повідомлення про помилки.
Перейшовши на AMD, нам не потрібно редагувати 2 файли. Проблема збереження loader.js та сценарію збірки синхронізується. Використовуючи r.js
або webpack
він може просто прочитати код для побудовиlarge-concantinated.js
Він також може вирішувати залежності, наприклад, у нас було завантажено 2 файли lib1.js та lib2.js
injectScript("lib1.js");
injectScript("lib2.js");
lib2 потребує lib1. У ньому є код, який робить щось подібне
lib1Api.installPlugin(...);
Але оскільки введені сценарії завантажуються асинхронно, немає гарантії, що вони завантажуватимуться у правильному порядку. Ці 2 сценарії не є сценаріями AMD, але, використовуючи requ.js, ми можемо сказати, що це їх залежність
require.config({
paths: {
lib1: './path/to/lib1',
lib2: './path/to/lib2',
},
shim: {
lib1: {
"exports": 'lib1Api',
},
lib2: {
"deps": ["lib1"],
},
}
});
Я наш модуль, який використовує lib1, ми це робимо
define(['lib1'], function(lib1Api) {
lib1Api.doSomething(...);
});
Тепер requ.js введе сценарії для нас, і він не введе lib2, поки не буде завантажений lib1, оскільки ми сказали, що lib2 залежить від lib1. Він також не запустить наш модуль, який використовує lib1, поки не завантажуються і lib2, і lib1.
Це робить розробку приємною (без кроку збирання, не турбуючись про порядок завантаження), і робить виробництво приємним (не потрібно оновлювати сценарій збірки для кожного доданого сценарію).
Як додатковий бонус, ми можемо використовувати плагін для веб-упаковки webpack для запуску бабеля над кодом для старих браузерів, і знову нам також не потрібно підтримувати цей сценарій складання.
Зауважте, що якби Chrome (наш вибір браузера) почав підтримувати import
реально, ми, ймовірно, переходимо до цього для розробки, але це насправді нічого не змінить. Ми ще можемо використовувати webpack для створення зв'язаного файлу, і ми можемо використовувати його для запуску бабеля над кодом для всіх браузерів.
Все це отримується за допомогою не використання тегів скриптів та використання AMD