Статьи

Модульный JavaScript: руководство для начинающих по SystemJS & jspm

Эта статья была рецензирована Адрианом Санду и Марком Брауном . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

За последние несколько лет популярность языка программирования JavaScript возросла. Он стал популярным языком для разработки как многофункциональных веб-приложений, так и гибридных мобильных приложений. И так как проекты JavaScript становятся все более сложными, разработчики сталкиваются с новыми требованиями языка. Одним из них является модульность.

Насколько я вижу, есть два аспекта, в которых должна быть достигнута модульность:

  • Модули, которые мы автор
  • Внешние модули, которые устанавливаются как зависимости

ES6 привносит стандартный синтаксис модуля в JavaScript и спецификацию загрузчика . Это хороший шаг вперед, однако на момент написания этой статьи не было браузеров, которые могли бы изначально загружать модули ES6 . Это означает, что если вы хотите использовать модули сегодня, вам нужно использовать пакетный модуль.

Обзор текущего ландшафта см .: Понимание модулей JavaScript: объединение и перенос

Более того, у нас нет менеджера пакетов, который позволяет нам загружать пакет и включать его в наше приложение. Менеджеры пакетов (такие как Bower и npm) помогают нам загружать внешние интерфейсы, не посещая веб-сайт проекта, но это далеко не так.

В этой статье мы увидим, как jspm и SystemJS могут быть использованы для преодоления этих проблем.

Что такое jspm и SystemJS?

Менеджер пакетов JavaScript (также известный как jspm) — менеджер пакетов, работающий поверх универсального загрузчика модулей SystemJS. Это не совсем новый менеджер пакетов с собственным набором правил, скорее он работает поверх существующих источников пакетов. Из коробки работает с GitHub и npm. Поскольку большинство пакетов на базе Bower основаны на GitHub, мы можем установить эти пакеты также с помощью jspm. Он имеет реестр, в котором перечислены большинство часто используемых интерфейсных пакетов для упрощения установки. Как и npm, его можно использовать для различения пакетов в качестве пакетов разработки и производства во время установки.

SystemJS — это загрузчик модулей, который может импортировать модули во время выполнения в любом из популярных сегодня форматов (CommonJS, UMD, AMD, ES6). Он построен поверх полифилов-загрузчиков модулей ES6 и достаточно умен, чтобы определять используемый формат и обрабатывать его соответствующим образом. SystemJS также может переносить код ES6 (с Babel или Traceur ) или другие языки, такие как TypeScript и CoffeeScript, используя плагины. Вы настраиваете эти вещи в System.config({ ... }) перед импортом вашего модуля.

jspm использует SystemJS для управления пакетами и их зависимостями, поэтому нам не нужно беспокоиться о том, чтобы расположить пакеты в правильном порядке для их загрузки.

Теперь, когда мы знаем, что такое jspm и SystemJS, давайте посмотрим, как их использовать.

Настройка нашей среды

Если вы этого еще не сделали, вам необходимо установить Node.js. Особенно простой способ сделать это — использовать менеджер версий (например, nvm), который подробно описан в этом кратком совете . Установив Node, вы можете установить jspm глобально, запустив в командной строке следующее:

 npm install -g jspm 

Теперь мы можем использовать интерфейс командной строки jspm . Давайте настроим проект:

 mkdir new-project && cd new-project npm init -y npm install jspm --save-dev 

Это создает каталог с именем new-project , инициализирует проект npm и устанавливает jspm локально. Это рекомендуемый способ работы , так как он блокирует версию jspm для проекта и гарантирует, что обновление до глобальной jspm не изменит поведение вашего приложения.

Еще одним преимуществом этого подхода является то, что если ваш проект развертывается с помощью непрерывной интеграции, вы можете настроить процесс сборки на использование локального пакета jspm вместо того, чтобы устанавливать глобально jspm на сервере.

Вы можете использовать jspm -v для подтверждения локальной версии.

 $ jspm -v 0.16.34 Running against local jspm install. 

Чтобы использовать jspm в проекте, выполните следующую команду:

 jspm init 

Вам будет предложено ввести несколько параметров, нажмите Enter, чтобы принять значения по умолчанию, или введите другое значение, чтобы изменить их. На следующем снимке экрана показан случай, когда команда выполняется с настройками по умолчанию:

Выполнение команды jspm init в терминале

Структура и конфигурация каталогов

Это создаст файл с именем config.js в корне проекта, а также папку с именем jspm_packages . Если вы загляните внутрь папки jspm_packages то увидите:

  • github
  • npm
  • Основные файлы для загрузчика модуля SystemJS

Причина, по которой jspm создает каталоги github и npm заключается в том, что он поддерживает эти реестры, просто добавляя псевдонимы запрошенного пакета npm или GitHub. Кроме того, каталог github содержит плагин SystemJS для загрузки файлов JSON из GitHub, а каталог npm содержит пакеты, связанные с Babel, которые нам понадобятся для переноса нашего кода ES6.

Файл config.js в основном предназначен для SystemJS. Если вы откроете его, вы увидите, что в нем заданы параметры конфигурации для путей пакетов из разных источников, параметры для Babel и карты имен для пакетов, чтобы упростить их обращение к ним. Этот файл обновляется автоматически и обновляется при установке нового пакета с использованием jspm.

Команда также обновляет файл package.json и добавляет раздел для jspm. Пакеты Babel, установленные с помощью команды init , добавляются в раздел devDependencies проекта.

 "jspm": { "devDependencies": { "babel": "npm:babel-core@^5.8.24", "babel-runtime": "npm:babel-runtime@^5.8.24", "core-js": "npm:core-js@^1.1.4" } } 

Любой новый пакет, установленный с помощью команды jspm с параметром —save или без --save будет добавлен в раздел dependencies и станет производственной зависимостью. Установка с параметром --save-dev делает зависимость зависимостью от времени разработки и сохраняет ее в разделе devDependencies .

Наконец, jspm добавляет запись в раздел config.js файла config.js для каждого пакета, установленного с помощью команды jspm . Сопоставленное имя можно использовать для загрузки библиотеки в любой файл JavaScript на протяжении всего проекта. Любые зависимости пакетов также добавляются в раздел карты. Ниже приведен фрагмент из раздела config.js файла config.js который показывает, как сопоставляются пакеты jquery и jquery-ui и как определяется зависимость:

 "jquery": "npm:jquery@2.2.0", "jquery-ui": "github:components/jqueryui@1.11.4", "github:components/jqueryui@1.11.4": { "jquery": "npm:jquery@2.2.0" } 

Интересно, что вы также можете автоматически генерировать эти сопоставления при установке модуля:

 jspm install jq=jquery 

Это позволит вам написать следующее в вашем приложении:

 var $ = require('jq'); 

jspm и SystemJS в действии

Чтобы сопровождать эту статью, я сделал простой пример поиска в Википедии. Вы можете найти репозиторий GitHub здесь . Он настроен с использованием параметров по умолчанию команды jspm init и, следовательно, использует Babel в качестве транспортера ES6. Он также использует библиотеки jQuery и Bootstrap, которые устанавливаются с помощью jspm. Поскольку для начальной загрузки требуется jQuery, jspm создает отображение в файле config.js для загрузки jQuery перед загрузкой начальной загрузки:

 "github:twbs/bootstrap@3.3.6": { "jquery": "github:components/jquery@2.2.0" } 

Как следует из названия репо, он запрашивает API поиска в Википедии и отображает данные, полученные в представлении. Он использует $.ajax() jQuery для вызова API, отображает результаты на странице и имеет ссылку, чтобы показать фрагмент статьи в модальном всплывающем окне. Пример содержит три файла JavaScript в папке scripts :

  • search.js : этот файл использует модуль стиля AMD. Он загружает jQuery как зависимость и делает Ajax-вызов в поисковом API Википедии. Модуль возвращает функцию, которую любой другой модуль-потребитель может вызвать с параметром.
  • summaryModal.js : Этот файл использует модуль стиля ES6. Он загружает библиотеку JavaScript Bootstrap. Затем он экспортирует функцию, которая принимает часть экранированного HTML и удаляет текст HTML перед отображением в модальном всплывающем окне.
  • display.js : этот файл использует модуль стиля CommonJS. Он загружает jQuery и оба вышеуказанных файла как зависимости. Он вызывает метод, предоставляемый search.js для получения результатов, а затем отображает эти данные в HTML-таблице в пользовательском интерфейсе. Кроме того, он использует метод, представленный summaryModal.js чтобы показать модальное нажатие кнопки ссылки в таблице.

Как уже упоминалось, SystemJS понимает все системы модулей в JavaScript. Мы можем загрузить все три вышеупомянутых файла, используя SystemJS.

Чтобы запустить эти сценарии, нам нужно загрузить system.js и config.js на HTML-странице. После этого мы загрузим файл display.js с помощью загрузчика модуля SystemJS. Поскольку этот файл ссылается на другие файлы в репозитории, и эти файлы загружают необходимые библиотеки, нам не нужно загружать другие файлы.

 <script src="jspm_packages/system.js"></script> <script src="config.js"></script> <script> System.import("scripts/display.js"); </script> 
SystemJS переносит файл ES6 на лету с помощью Babel и запускает его в браузере. Вот (немного упрощенная) демонстрация того, как это выглядит:

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

Пакетирование

Мы можем создать пакет для всего приложения, используя следующую команду:

 jspm bundle scripts/display.js build.js 

Эта команда выполняет следующие действия:

  • Объединяет все файлы и библиотеки в один файл с именем build.js
  • Преобразует системы модулей, используемые файлами, в модули стиля SystemJS.
  • Создает исходный файл карты, который загружается во время отладки.

Теперь нам нужно загрузить файл build.js файл index.html . Вот обновленный набор ссылок:

 <script src="jspm_packages/system.js"></script> <script src="config.js"></script> <script src="build.js"></script> <script> System.import("scripts/display.js"); </script> 

Обратите внимание, что мы не удалили оператор импорта для загрузки модуля display.js . Этот оператор больше не загружает файл, вместо этого он загружает модуль SystemJS, который уже доступен в файле build.js .

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

Вывод

Комбинация jspm и SystemJS обеспечивает унифицированный способ установки и загрузки зависимостей. Этот инструмент не только облегчает работу с зависимостями, но и открывает двери для использования будущей модульной системы в современных браузерах. Как я продемонстрировал, jspm прост в настройке и использовании — две причины, которые способствуют его растущей популярности.

Вы используете JSPM в своих проектах? Почему? Почему нет? Позвольте мне знать в комментариях ниже.