Статьи

Сборка библиотеки с помощью RequireJS

RequireJS — загрузчик модулей AMD для браузеров, который может загружать ваш скрипт и CSS-файлы асинхронно. Вам больше не нужно иметь дело с порядком файлов сценариев внутри отдельного файла (например, index.html). Вместо этого вы просто заключаете свой код в определения модулей, а RequireJS позаботится о зависимостях, делая ваш код более структурированным и хорошо организованным. У этого также есть инструмент оптимизатора, который удаляет и объединяет файлы для производственного использования.

Официальный сайт предоставляет обширную документацию по его API, и есть много примеров репозиториев, которые могут вам помочь. Но у него много настроек, и поначалу сложно начать с RequireJS.

В этой статье мы узнаем, как использовать RequireJS, создав библиотеку с использованием модулей AMD, оптимизировав ее и экспортировав в виде отдельного модуля с использованием оптимизатора RequireJS. Позже мы будем использовать RequireJS для создания приложения и использования нашей библиотеки.

Этот учебник предполагает некоторое знакомство с RequireJS. Если вы ищете учебник, ознакомьтесь: Понимание RequireJS для эффективной загрузки модуля JavaScript .

Установка RequireJS

RequireJS доступен через Bower:

bower install requirejs --save

или вы можете получить файлы на github .

Есть также основанный на Grunt генератор Yeoman для проектов RequireJS.

Определение модуля AMD

Мы обернем наш код внутри define()

Файл: mylib.js

 define(['jquery'], function($) {
    // $ is jquery now.

    return 'mylib';
});

Вот и все. Обратите внимание, что define()['jquery'] Это список зависимостей для этого модуля. Все модули внутри массива будут загружены до этого модуля. Когда этот модуль выполняется, аргументы являются соответствующими модулями в массиве зависимостей.

Таким образом, в этом случае сначала будет загружен jQuery, а затем передан в функцию в качестве параметра $ Наконец наш модуль возвращает строку. Возвращаемое значение — это то, что передается параметру функции, когда требуется этот модуль.

Требование других модулей

Давайте посмотрим, как это работает, определив второй модуль и потребовав наш первый модуль mylib.js

Файл: main.js

 define(['jquery', 'mylib'], function($, mylib) {
    // $ is jquery as usual
    // mylib is the string `mylib` because that's the return value
    // from the first module

    return {
        version: '0.0.1, jQuery version: ' + $.fn.jquery,
        mylibString: mylib
    }
});

Внутри массива зависимостей вы можете требовать столько зависимостей, сколько захотите, и все модули будут доступны через параметры функции в том же порядке. Во втором модуле нам потребовались модули jquerymylib Пользователь этой библиотеки будет использовать этот объект в качестве вашей библиотеки.

Настройка оптимизатора RequireJS: r.js

Вам может быть интересно, как RequireJS узнает, какой файл загружать, только взглянув на строку в массиве зависимостей? В нашем случае мы предоставили jquerymylib mylibmylib.js.js

Как насчет jquery Вот где используется конфиг RequireJS. Вы можете обеспечить расширенную настройку через конфигурацию RequireJS. Есть два способа предоставить этот конфиг, так как мы используем оптимизатор RequireJS, я покажу вам путь r.js. r.js — оптимизатор RequireJS.

Мы предоставим r.js конфиг, и он оптимизирует все модули в одном файле. Предоставленная нами конфигурация заставит r.js собирать модули как отдельную глобальную библиотеку, которую можно использовать как модуль AMD или как глобальный экспорт в браузере.

r.js может быть запущен через командную строку или как Node-модуль. Существует также задача Grunt grunt-requirejs

При этом давайте посмотрим, как выглядит наша конфигурация:

Файл: tools/build.js

 {
  "baseUrl": "../lib",
  "paths": {
    "mylib": "../main"
  },
  "include": ["../tools/almond", "main"],
  "exclude": ["jquery"],
  "out": "../dist/mylib.js"
  "wrap": {
    "startFile": "wrap.start",
    "endFile": "wrap.end"
  }
}

Конфигурационный файл — это действительно мясо RequireJS. Как только вы поймете, как работают эти параметры, вы можете использовать RequireJS как профессионал.

Вы можете делать разные вещи и настраивать ваш проект с помощью файла конфигурации. Чтобы узнать больше о конфигурации и RequireJS в целом, я рекомендую обратиться к документации и вики . Существует также пример файла конфигурации , который демонстрирует, как использовать систему сборки, поэтому не забудьте также сослаться на него.

Наконец мы запускаем оптимизатор. Как я уже говорил, вы можете запустить его через командную строку или Node, а также задачу Grunt. Обратитесь к r.js README, чтобы узнать, как запустить оптимизатор в разных средах.

 node tools/r.js -o tools/build.js

Это сгенерирует файл сборки в dist/mylib.js

build.js

Далее, давайте посмотрим, что на самом деле означают параметры.

baseUrl — корневой путь для всех поисков модулей.

paths — сопоставления путей для имен модулей, относящихся к baseUrl.

В нашем примере «mylib» отображается на «../main», то есть относительно baseUrl
Обратите внимание, что мы baseUrlpaths.js Здесь вы указываете, как модули отображаются на файлы, такие как jquerymylib

include — модули, которые мы хотим включить в процесс оптимизации. Зависимости, которые требуются включенными модулями, включены неявно. В нашем случае mainmylibjquery Мы также включаем almond

exclude — модули, которые мы хотим исключить из процесса оптимизации. В нашем случае мы исключаем jquery Потребители встроенной библиотеки предоставят библиотеку jQuery. Мы увидим это, когда будем использовать нашу библиотеку позже.

out — имя оптимизированного выходного файла.

wrap — заключает в сборочный пакет начальный и конечный текст, указанный в wrap Оптимизированный выходной файл выглядит следующим образом: wrap.startwrap.end wrap.startwrap.end

миндальный

Встроенная библиотека не включает require.js в файл, а использует миндаль. almond — это небольшая реализация AMD API, которая заменит require.js.

Упаковка нашей библиотеки

В конфиге r.js мы обернули нашу библиотеку wrap.startwrap.end Мы также включили миндаль в нашу библиотеку, это сделает нашу библиотеку автономной, чтобы ее можно было использовать без RequireJS через глобальные переменные браузера или как модуль AMD через requirejs.

File: wrap.start

 (function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD.
    define(['jquery'], factory);
  } else {
    // Browser globals.
    root.mylib = factory(root.$);
  }
}(this, function($) {

Наши включенные модули mainmylibalmondwrap.startwrap.end

File: wrap.end

 // Register in the values from the outer closure for common dependencies
  // as local almond modules
  define('jquery', function() {
    return $;
  });

  // Use almond's special top level synchronous require to trigger factory
  // functions, get the final module, and export it as the public api.
  return require('mylib');
}));

Если потребитель использует загрузчик AMD, то встроенный файл будет запрашивать «jquery» в качестве зависимостей AMD. Если потребитель использует глобальные переменные браузера, библиотека возьмет переменную $

Использование библиотеки с RequireJS

Мы закончили с нашей библиотекой, теперь давайте на самом деле используем ее, создавая приложение requirejs.

Файл: app.js

 define(['jquery', 'mylib'], function($, mylib) {
  // $ is jquery
  // mylib is mylib that is:
  // {
  //   version: 'version 0.0.1 jQuery version: xxx',
  //   mylib: 'mylib'
  // }
});

Ничего особенного, это еще один модуль, требующий jQuery и mylib. Когда модуль определен с помощью define Это означает, что наше приложение запускается не только с определения этого модуля. Теперь давайте посмотрим, как настроить RequireJS и выполнить этот модуль, который является нашим приложением.

Настройка RequireJS для браузера

Мы настроим RequireJS и запустим наш модуль приложения в одном файле. Хотя есть разные способы сделать это.

Файл: common.js

 requirejs.config({
  baseUrl: '../lib',
  paths: {
    'jquery': 'jquery/dist/jquery.min',
    'underscore': 'underscore/dist/underscore',
    'backbone': 'backbone/backbone',
    'mylib': 'mylib/dist/mylib',
    'app': '../app'
  },
  shim: {
    'jquery': {
      exports: '$'
    },
    'backbone': {
      deps: ['jquery', 'underscore'],
      exports: 'Backbone',
    },
    'underscore': {
      exports: '_'
    }
  }
});

require(['app/app'], function(App) {
  // app module is available here
  // you can start your application now
  // this is immediately called because
  // we used `require` instead of `define`
  // to define this module.
});

baseUrlpaths Дополнительное значение конфигурации здесь:

shim : Конфигурирует зависимости и экспорт для традиционных скриптов «globals браузера», которые не используют define() Например, Backbone — это не модуль AMD, а глобальный браузер, который экспортирует Backboneexports В нашем примере модуль также зависит от jQuery и Underscore , поэтому мы указываем это с помощью deps Сценарии в массиве depsexports

Обратите внимание, что вы также можете использовать r.js в этом проекте приложения, что потребует отдельной настройки. Но не смущайтесь этим. Я не буду вдаваться в подробности о том, как это сделать, но это похоже на то, что мы сделали для нашей библиотеки. Смотрите пример конфигурации сборки для дальнейшего использования.

требуют против определения

Позже мы используем require Иногда definerequire definerequire Часто в качестве основного модуля ввода у вас будет один requiredefine

Загрузка скриптов

Обычно вы включаете все ваши файлы сценариев в ваш index.html Теперь, когда мы используем RequireJS, нам нужно только включить RequireJS и указать нашу базу data-main Существуют разные способы настройки параметров конфигурации или отделения основного модуля, используемого в index.html Вы можете найти больше информации об этом здесь .

 <script data-main="scripts/common" src="scripts/lib/require/require.js"></script>

Вывод

В этой статье мы создали библиотеку и приложение, которое использует эту библиотеку с RequireJS. Мы узнали, как настроить оптимизатор r.js и как настроить RequireJS в браузере. Наконец, мы узнали, как использовать RequireJS для определения и использования модулей AMD. Это сделало наш код хорошо структурированным и организованным.

Я использовал этот пример репозитория libglobal в этом уроке для первой половины (настройка оптимизатора), а вторая половина не так сложна, так что вы должны быть хороши, чтобы развернуть свою собственную сейчас.

Официальный веб-сайт RequireJS является основной документацией, но обязательно ознакомьтесь с примерами репозиториев на github, а также примерами проектов в этом репо, которые демонстрируют использование приложения RequireJS.