Таск раннер что это
Делаем удобный таск-раннер и публикуем его как npm-пакет
Рано или поздно при работе с тем или иным языком программирования возникает желание написать на нем свой вспомогательный инструмент для разработки. И впрямь, трудно представить современный мир программирования, а тем более мир javascript, на котором мне довелось писать последнее время, без огромного количества библиотек/фреймворков/консольных утилит.
Постановка задачи
Таким образом, нам нужно решить в коде следующие задачи:
Автор этой статьи много знает, потому что учился у менторов mkdev Выбрать ментора
Ну и файл с кодом, который непосредственно запустит тот или иной таск:
Скажу честно, последний, по большей части, я взял из проверенных временем исходников better-npm-run, добавив лишь callback после завершения дочернего процесса.
Выкладывание пакета в публичный доступ
Ну вот мы и подошли к финальной и возможно самой долгожданной части: выкладыванию нашего кода в публичный репозиторий npm. По сути тут все просто, но для начала подготовим наш package.json для публикации:
Вывод
Как видите, это совсем несложно написать что-то свое, что с легкостью может быть использовано другими. Весь код данной утилиты вместе с тестами вы можете найти у меня в репозитории.
P.S. Спасибо Кириллу за его сайт и книгу: в свое время они оказали колоссальное положительное влияние на меня как разработчика.
Мы рассказываем, как стать более лучшим разработчиком, как поддерживать и эффективно применять свои навыки. Информация о вакансиях и акциях эксклюзивно для более чем 8000 подписчиков. Присоединяйся!
Ускоряем npm-скрипты
Таск раннеры существенно упростили жизнь веб разработчиками автоматизируя рутинные действия связанные с запуском тестов, проверкой кода, объединением в один файл, транспайлингом и прочими не менее полезными делами. Опустим вопрос необходимости подобных инструментов, конечно, можно и без них, но они существенно упрощают жизнь и делают более качественным процесс разработки.
Все пользуются таск раннерами в той или иной мере: кто-то старинным грантом, кто-то постепенно уходящим с арены галпом и многими другими, а кто-то уже во всю использует npm-скрипты.
Последние мы сегодня разберем во всех деталях, а так же способы их ускорения и расширения возможностей
Причины использовать npm как таск раннер
Написанное ниже является субъективным опытом, и на истину последней инстанции не претендует, тем-не-менее является важными причинами дальнейшего повествования.
По мере появления перечисленных выше таск раннеров, они были мной испробованы в бою, и в каждом из них (конечно же) есть плюсы, и минусы. Рассмотрим их вкратце.
У гранта низкий порог вхождения, благодаря конфигам, которые в тот же момент являются его краеугольным камнем, заставляя генерировать их программно, из-за большого количества передаваемых полей. Галп решает эту проблему целиком, добавляя минимализм и скорость выполнения, благодаря стримам, что повышает порог вхождения, требуя от пользователей понимания того, как все работает изнутри.
И так, отойдя от гранта, разобравшись со стримами и написав лаконичный Gulpfile я успокоился и продолжил разработку текущего проекта. Для следующего приложения, я, конечно, снова написал Gulpfile. И для следующих. И для многих других.
После чего сам gulp, и его плагины начали обновляться, а потом и его зависимости, которые бывало нужно было обновлять самостоятельно. Конечно можно не использовать сервисы, следящие за обновлениями пакетов, устранением уязвимостей, исправлением ошибок и всем прочим, но это не самый хороший подход к разработке.
Таким образом мы подошли к главному недостатку большинства такс раннеров: их нужно обновлять, их зависимости нужно обновлять и зависимость зависимостей тоже. Для монолитных приложений это не представляет проблемы. Проблемы начинаются тогда, когда частей приложения много, и каждая из них является независимым модулем, а это ли не основная парадигма разработки на node.js?
Итак, вместо того, что бы обновлять: gulp, gulp-jshint и jshint, я лучше просто буду использовать jshint напрямую, с помощью интерфейса командной строки, который не часто меняется, значительно упрощая себе этим жизнь.
npm-скрипты
Когда я начал активно использовать npm-скрипты, я, как и многие разработчики, осознал неудобство и многословность такого подхода, к примеру, если нужно организовать проверку линтерами, код будет выглядеть таким образом:
Тогда скрипт, который запускает все проверки будет выглядит так:
Очень уж многословно, а тут всего-то 3 скрипта запускаются.
Удобные npm-скрипты
npm-run-all
Предыдущий пример получился очень многословным (гораздо более коротким чем в случае с грантом и галпом, но тем-не-менее) и сложночитаемым. npm-run-all существенно все упрощает. С его помощью, код делающий тоже самое будет выглядеть так:
И делать примерно то же самое: поочередно запускать скрипты.
npm-run-all очень не плохо себя показывает в плане удобства, но по принципу действия он не сильно уходить от npm run : каждая команда вызывается отдельно, что значительно замедляет весь процесс.
Быстрые npm-скрипты
Redrun
Что может redrun?
Взаимодействие
Установим tape для тестов, и запишем простейший тест, который проходит.
Теперь в секцию scripts файла package.json добавим несколько разделов:
После чего запустим тест с помощью npm :
А теперь то же самое, только с помощью redrun :
Даже на таком простом примере видно, что скорость выполнения почти в 3 раза выше.
Теперь попробуем тоже самое со скриптом npm watch:test :
Попробуем тоже-самое выполнить с помощью npm :
С помощью npm нам потребовалось 11 секунд, для того, что бы узнать, что nodemon не установлен.
Теперь все работает: запускается наблюдатель, который смотрит за изменениями в папках test и lib и перезапускает tape test.js — именно то, что нам нужно. При этом остается возможность использовать компактный синтаксис скриптов в package.json.
Процесс разработки
Redrun пишется по TDD, по этому вносить изменения: добавлять фичи, или фиксить баги — очень просто. Если читатель заметит не очевидное и не документированное расхождение в работе redrun по сравнению с аналогичными инструментами: создавайте ишью, присылайте пул реквесты — будем исправлять.
Зачем нужны таск менеджеры GULP и GRUNT?
Оценить 6 комментариев
Мне кажется тут не хватает образного примера:
Вот и сказочке конец, а кто слушал, тот и gulp.
Сейчас же, весь этот «девелоперский» антураж в виде фреймворков для фреймворков для запуска фреймворков с кучей json конфигов, с пафосным названием и флэт логотипом : )
Просто я реально не понимаю сути этих всех прелестных менеджеров!
Сказали ведь, автоматизация )
Я по началу тоже задавался этим вопросом.
Скажем так, если ты пишешь на Jade или другом шаблонизаторе + CSS препроцессор + CoffeeScript и проект разделен на множество файлов (модульность), то в таком случае это очень удобно, все это собирается буквально одной строчкой в консоле.
Плюс к этому добавь дополнительные плюшки в виде оптимизации изображений на лету, добавление актуальных префиксов и т.д.
А если еще и Bower(менеджер пакетов) прикрутить, то вообще лепота.
Использовать эти инструменты для какой-то одной или двух из этих задач конечно глупо.
Предполагается, что это избавит разработчика от множества рутинных действий, таких, как юнит-тесты, минификация \ объединение скриптов, а также от необходимости обновлять страницы, чтобы посмотреть, как изменилось действие скрипта. Не знаю, насколько это актуально для небольших проектов, но для крупных, полагаю, эффект будет очень заметен.
Ну поставите вы кучу говноплагинов в сублайм, а если вы работаете не один и другие разработчики используют другие редакторы/IDE? Ну, положим, вы всех убедили перейти на сублайм, теперь вам надо всем поставить эти плагины и всем их настроить.
А через три дня в команду взяли Васю, который пишет только на виме, что теперь делать?
А что делать с деплоем, как получить на проде склеенные скрипты и CSS из LESS? Cтавить на сервер сублайм? Так там даже иксов нет. Хранить в гите артефакты сборки? Плохая идея (каюсь, я пробовал).
Всем привет, друзья! Это обновленное и переработанное руководство Gulp 4, в котором мы детально разберем работу с Gulp, ознакомимся с новыми методами построения задач (тасков), вы узнаете, какими способами можно установить, настроить Gulp и как с его помощью автоматизировать и ускорить процесс веб-разработки. По традиции, мы будем знакомиться с возможностями инструмента на реальном примере и создадим удобное рабочее окружение для HTML верстки.
Для более углубленного понимания Gulp, в рамках подготовки данного урока, мною была полностью переведена документация Gulp, к которой мы будем возвращаться по мере обучения. Рекомендую ознакомиться с документацией, там вы найдете для себя много нового, полезного и интересного.
Полезные материалы урока:
С выходом Gulp 4 инструмент претерпел значительные изменения, по сравнению с Gulp 3, по которому я делал урок в свое время. Код стал максимально простым и лаконичным, значительно уменьшилось количество зависимостей пакетов, увеличилась скорость установки модулей и скорость работы в целом. Также у нас есть урок, в котором я рассказывал о том, как можно максимально быстро и без боли перевести любой проект, написанный с использование Gulp 3 на Gulp 4. Сегодня-же мы научимся писать задачи с использованием только актуальных и рекомендуемых разработчиками Gulp методами и API. Данный урок будет актуальным до тех пор, пока в закрепленном комментарии к видео на YouTube не появится информация о том, что вышел новый урок по данному инструменту. Данное правило применимо и для других уроков на канале. Чекните актуальность, а заодно, можете поставить лайк и что-нибудь написать или спросить, буду рад ответить на ваш вопрос.
Установка Gulp и настройка
Для начал необходимо установить окружение. Если вы пользователь macOS или Windows, вы можете загрузить Node.js версии LTS с сайта Nodejs.org или воспользоваться актуальным способом установки окружения, который я предлагаю для работы с использованием WSL.
После установки окружения можно приступать к работе. Откроем терминал в папке проекта: создадим папку «html» на вашем компьютере и откроем в ней терминал.
Если вы пользователь Windows, для того, чтобы открыть терминал bash или командную строку в нужной папке, просто зажмите клавишу Shift и нажать правую кнопку мыши.
Внимание! Лучше не создавать русскоязычные папки. Избегайте кириллицы в путях вашего проекта, папка вашего пользователя должна быть написана также латиницей для корректной работы.
Выполним инициализацию проекта командой npm init и укажем название нашего проекта myproject :
Если у вас нет желания заполнять остальные поля, можно оставить их пустыми, нажимая «Enter» или заполнить на свое усмотрение. По окончании заполнения полей, введите yes и нажмите «Enter».
Для начала установим Gulp локально в наш проект командой:
Теперь в файле package.json, в секции devDependencies появился gulp и информация о его текущей версии. После установки других пакетов таким-же образом, информация о них также будет отражена в «package.json».
Кроме того, в папке нашего проекта появилась папка «node_modules», которая теперь содержит все зависимости пакета «gulp».
Именно в эту папку будут автоматически установлены все модули и зависимости, которые мы будем использовать в нашем проекте. Папок с зависимостями может быть очень много, не смотря на то, что пока что мы установили только один пакет. Все дополнительные модули необходимы для корректной работы основных пакетов.
В папке проекта таже можно заметить файл «package-lock.json». Это служебный файл, на который можно не обращать внимание. Его, конечно, можно удалить, однако после повторной установки модулей, он появится вновь.
Для файлов нашего проекта я предлагаю создать папку «app/», в которой будут храниться все исходные файлы.
Давайте создадим самый главный файл проекта. Это, конечно-же, «gulpfile.js».
Работа с gulpfile.js
Внимание! Все куски кода с примерами будут объединены в один полноценный пример «gulpfile.js» со всеми комментариями в конце данного урока.
Для начала определим константы Gulp в «gulpfile.js»:
Именно с помощью require() мы подключаем модули из папки «node_modules» и присваиваем их переменной или, как в нашем случае, константам.
Подключим Browsersync в проект:
Далее напишем функцию, которая определит логику работы «Browsersync». В отличие от Gulp 3, в Gulp 4 логика работы в комбайне не является таском. Это просто функция, которую можно экспортировать в таск или добавить в набор экспорта.
Обратите внимание, что название функции не должно совпадать с названием переменной или константы, в которую мы подключаем пакет. Поэтмоу, в данном случае, название функции browsersync() будет содержать только строчные буквы.
При использовании какого-либо модуля, рекомендую всегда читать его документацию на официальном сайте или на сайта npmjs.org. Как правило, разницы большой нет, где смотреть инструкцию, однако лучше отдавать предпочтение оф. сайту, так как информация на сайте npmjs.org может обновляться не сразу или иметь не полные инструкции.
Для того, чтобы получить готовый к запуску таск, функцию или комбинацию функций необходимо экспортировать.
Допишем далее в gulpfile.js:
Запускаем новый таск командой:
После запуска мы увидим в браузере белую страницу с надписью «Cannot GET /». Это говорит о том, что в папке проекта «app/» нет индексного файла.
Если мы создадим в папке «app/» индексный файл «index.html», напишем в него что-нибудь и сохраним файл, то, после обновления страницы, мы сможем узреть в браузере результат нашего творчества.
Работа со скриптами
Создадим функцию scripts() до экспорта задач. Данная функция будет обрабатывать скрипты нашего проекта:
Для работы данной функции нам понадобятся модули «gulp-concat» и «gulp-uglify-es». Установим их в наш проект. Устанавливать несколько пакетов можно простым перечислением без каких-либо разделяющих символов одной командой:
И подключим данные модули к проекту в верхней части «gulpfile.js»:
Создадим в папке «app/» новую папку «js/» и в ней уже создадим новый файл «app.js». Для примера можно разместить следующий код в файле «app.js»:
Давайте разберемся, что происходит в функции scripts() нашего «gulpfile.js». Я буду указывать соответствующую строку кода из примера выше и объяснять, что мы делаем.
Строки 3 и 4: Перечисление нескольких файлов в качестве источника.
Далее экспортируем функцию scripts() в таск. В нижней части «gulpfile.js», где у нас размещен предыдущий экспорт, добавляем экспорт таска scripts :
Поначалу может показаться, что система экспорта функций в таски не совсем удобна, ведь раньше, в Gulp версии 3, мы сразу писали таски, которые уже были готовы к использованию без экспорта. Но здесь фишка в том, что именно с помощью exports можно комбинировать любым способом любые функции. Это намного круче, намного удобнее и работает все намного быстрее. По мере изучения данного урока вы в этом убедитесь.
Запустим gulp scripts и проверим в терминале, как работает наш таск:
Таск работает отлично. Если перейти в папку «app/js/», можно узреть вновь созданный минифицированный файл «app.min.js» со скриптами проекта. Открыв этот файл, мы увидим, что там находится скрипт библиотеки jQuery, а в конце строки наш пример кода из «app/js/app.js».
Добавим разметку-пример в файл «app/index.html» с подключенным скриптом, стилями и изображением:
Со стилями и изображениями поработаем чуть позже. Нужные ресурсы можно взять с GitHub, ссылка указана в начале статьи, в разделе полезных ресурсов урока.
Рекомендую держать файл «index.html» на виду, так как в дальнейшем мы к нему еще обратимся при работе со стилями и изображениями. Сейчас следует обратить внимание именно на строчку подключения скрипта:
.
Обратите внимание, что в путях до файлов скриптов, стилей и изображений мы не указываем папку «app/», так как эта папка является корнем для сервера и уже учтена в настройках Browsersync.
Для более глубокого понимания работы Globs рекомендую ознакомиться с соответствующим разделом документации Gulp.
Для того, чтобы наша функция startwatch() заработала и начала выполнять полезную работу, ее необходимо добавить в дефолтный экспорт. Перейдем в секцию экспортов (в gulpfile.js внизу, где мы размещаем экспорты) и добавим дефолтный таск, в котором и запустим вотчер:
Дефолтный таск exports.default позволяет запускать проект одной командой gulp в терминале.
Теперь можно запустить команду gulp в терминале. Если внести какие-либо изменения в файле «app/js/app.js», страница будет автоматически перезагружена.
Работа со стилями
Ориентируясь на предыдущий опыт, установим одной командой модули «gulp-sass», «sass», «gulp-less», «gulp-autoprefixer» и «gulp-clean-css»:
И подключим их в проект:
Создадим переменную preprocessor в самом начале «gulpfile.js»:
Давайте ознакомимся с полной функцией и будем разбираться, что здесь происходит:
Строка 5: Создание префиксов для лучшей совместимости со старыми браузерами. Здесь мы используем установленный и подключенный ранее модуль «gulp-autoprefixer».
Параметр overrideBrowserslist задается для определения глубины версий от текущей. В нашем случае, префиксы будут раздаваться старым браузерам последних 10-ти версий. Параметр grid: true отвечает за создание префиксов CSS Grid для браузеров Internet Explorer.
Экспортируем функцию styles() в задачу. Для этого добавим перед дефолтным экспортом exports.styles :
После выполнения в терминале команды gulp styles будет создан файл стилей проекта «app/css/app.min.css». Если мы поменяем значение переменной preprocessor на less и перезапустим gulp в терминале, то в качестве источника выступит файл «app/less/main.less» и файл будет обработан уже препроцессором Less.
Далее, как вы уже догадались, нам необходимо настроить слежение за изменениями в исходных файлах препроцессора. Для этого создадим еще один watch() для стилей:
Все, что нам остается сделать, это добавить функцию styles() в дефолтный экспорт:
Внимательный читатель заметит, что мы обработали стили, обработали JavaScript, но абсолютно оставили без внимания HTML файлы. Давайте добавим наблюдение за HTML файлами проекта в функцию startwatch() :
Работа с изображениями
Для того, чтобы работать с изображениями, нам необходим соответствующий модуль. Рекомендую использовать «compress-images». Это один из самых популярных модулей для работы с изображениями. Давайте установим «compress-images», а также вспомогательные модули:
Подключим их к нашему проекту. В результате секция с подключением необходимых модулей будет выглядеть следующим образом:
Назначение вспомогательного модуля «del» я объясню немного позже, а пока ознакомимся с новой функцией и разберемся, что здесь происходит. Добавим новую функцию images() после функции styles() :
Для того, чтобы новый таск заработал, функцию необходимо экспортировать. Добавим после exports.styles = styles; следующую строку:
Экспортируем для автономного использования в секции с экспортами в «gulpfile.js»:
Проверить работу таска довольно просто, введем команду в консоли:
Далее можно добавить мониторинг изображений в вотчер. В результате функция startwatch() будет иметь следующий вид:
Можно запустить проект командой gulp и проверить, как все работает. Ознакомьтесь с файлом «index.html», чтобы разобраться, как мы подключили в этот файл стили, изображения и скрипты.
Сборка проекта ( build )
Добавим новую функцию buildcopy() :
Обратите внимание, что мы выбираем здесь только минифицированные и готовые к продакшену файлы. Файлы нужно выбирать, исходя из задач и особенностей каждого отдельного проекта, это лишь простой и наглядный пример.
Данную функцию экспортировать не обязательно, так как она будет являться частью таска build и автономно использоваться не будет. Создадим таск build и выполним нужные функции последовательно друг за другом с помощью series() :
Здесь мы используем последовательное выполнение функций, так как нам нужен строгий порядок при сборке проекта и параллельно выполнять никакие задачи не требуется.
Соберем наш проект, выполнив в терминале:
Для очистки папки «dist/» можно создать дополнительную функцию cleandist() по аналогии с cleanimg() и добавить ее в таск build для предварительной очистки целевой папки:
Результат
В результате у нас получился такой замечательный «gulpfile.js», который мы создали на реальном примере простого окружения для верстки:
Премиум уроки от WebDesign Master
Создание сайта от А до Я. Комплексный курс
Создание современного интернет-магазина от А до Я
Описание современного JavaScript для динозавров
Это перевод статьи Питера Янга Modern JavaScript Explained For Dinosaurs. Она познакомит вас с инфраструктурой современной фронтэнд-разработки.
Наш курс JS: Настройка окружения выполняет схожую задачу, но чуть глубже, последовательно и без привязки только к фронтэнду. Этим темам также посвящена значительная часть первого проекта в JS Backend и JS Frontend. Там мы на деле устанавливаем и настраиваем среду для разработки, проверки, публикации, сборки и запуска своих приложений.
Изучать современный JavaScript — болезненно, если вы не знакомы с ним с самого его рождения. Экосистема разрастается и меняется с такой скоростью, что сложно разобраться с тем, какие проблемы пытаются решить разные инструменты. Я начал программировать в 1998 году, но к серьёзному изучению JavaScript приступил только в 2014. В то время я помню как анализировал Browserify и изумлённо смотрел на его слоган:
Browserify позволяет запрашивать (require) модули в браузере, объединяя все зависимости.
Можно сказать, я не понимал ни слова в этом предложении, и с трудом осознавал, насколько это может быть полезно мне, как разработчику.
Цель этой статьи — показать исторический контекст развития инструментов JavaScript до их уровня в 2017. Начнём с самых первых моментов и построим шаблон веб-сайта, как бы это сделали динозавры — без инструментов, чистый HTML и JavaScript. Затем мы будем пошагово вводить различные инструменты, чтобы на практике видеть, какие задачи они решают — поочерёдно. Благодаря историческому контексту у вас будет больше возможностей изучить и лучше адаптироваться к бесконечно меняющемуся JavaScript. Давайте начнём!
Использование JavaScript старомодным способом
Давайте начнём со старомодного веб-сайта, написанного на HTML и JavaScript, что включает загрузку и помещение ссылок на файлы вручную. Вот простой index.html файл, который ссылается на JavaScript файл:
Строчка ссылается на отдельный JavaScript-файл с названием index.js в той же директории:
Это всё, что вам нужно, чтобы сделать веб-сайт!
Продолжайте углублять свои знания На Хекслете есть блок «Треки», где собраны курсы для опытных разработчиков, которые хотят новых знаний про разработку.
Теперь давайте предположим, что вы хотите добавить библиотеку, которую написал кто-то другой, вроде moment.js (библиотеку, которая помогает превращать даты в понятные для чтения человеком). Например, вы можете использовать функцию moment в JavaScript вот так:
Но только при условии, что вы включите moment.js в код своего веб-сайта! На домашней странице moment.js вы найдёте такие инструкции:
И вот таким образом мы раньше делали веб-сайты с JavaScript-библиотеками! Положительный момент в том, что всё было достаточно легко понимать. Отрицательный — было муторно искать и загружать новые версии библиотек каждый раз, когда они обновлялись.
Использование пакетного менеджера JavaScript (npm)
Начиная примерно с 2010 появилось несколько конкурирующих пакетных менеджеров JavaScript для автоматизации процесса загрузки и обновления библиотек из центрального репозитория. Bower был, возможно, самым популярным в 2013, но в итоге, примерно в 2015 его настиг npm. (Стоит отметить, что с конца 2016 yarn привлёк много внимания, как альтернатива интерфейсу npm, но он всё ещё использует npm пакеты).
Заметьте, что npm был изначально пакетным менеджером, созданным специально для node.js — среды исполнения JavaScript, предназначенной для запуска на сервере, а не во фронтенде. Что делает его очень странным выбором для фронтенд-пакетного менеджера JavaScript библиотек, предназначенных запускаться в браузере.
Заметьте: Использование пакетного менеджера обычно требует работы с командной строкой, что в прошлом никогда не требовалось от фронтенд-разработки. Если вы никогда ей не пользовались, можете прочитать этот туториал, чтобы составить представление о том, как начать. Так или иначе, умение пользоваться командной строкой — важная часть современного JavaScript (и ещё она открывает двери в другие области разработки).
На Хекслете как раз есть бесплатный курс Bash: Основы командной строки, — прим. ред.
Давайте взглянем как использовать npm, чтобы установить пакет moment.js автоматически, вместо того, чтобы загружать его вручную. Если у вас установлен node.js, у вас уже есть и npm, а это значит, что вы можете через командную строку перейти к папке, в которой находится файл index.html и ввести:
Чтобы установить JavaScript-пакет moment.js, мы теперь можем следовать инструкциям npm на их домашней странице, введя в командную строку:
Читайте также Как устроен функциональный диалект Лиспа Clojure и почему использующие его программисты восхищаются им
Хорошие новости в том, что теперь мы можем использовать npm, чтобы загружать и обновлять пакеты с помощью командной строки. Плохие в том, что прямо сейчас мы обшариваем папку node_modules в поисках местоположения каждого пакета и вручную включаем их в HTML. Это достаточно неудобно, и следующее, что мы сделаем, это посмотрим как автоматизировать и этот процесс.
Использование модульного упаковщика JavaScript (webpack)
У большинства языков программирования есть способ импорта кода из одного файла в другой. JavaScript изначально не имел этой функции, потому что был создан только для работы в браузере, без доступа к файловой системе компьютера клиента (по соображениям безопасности). Поэтому очень долго организация кода JavaScript в нескольких файлах требовала загрузки каждого файла с глобальными переменными.
В 2009 году был запущен проект CommonJS, определяющий экосистему для JavaScript за пределами браузера. Большая часть CommonJS была спецификацией для модулей и она, наконец, позволила JavaScript делать импорт и экспорт между файлами, как в большинстве языков программирования, без использования глобальных переменных. Самая известная реализация модулей CommonJS — это node.js.
Как говорилось ранее, node.js — это среда выполнения JavaScript, предназначенная для запуска на сервере. Вот как выглядел более ранний пример с использованием модулей node.js. Вместо того, чтобы загружать все moment.min.js с помощью HTML script тега, вы можете загрузить его напрямую в файле JavaScript вот так:
Всё это подходит для node.js, но если вы попытаетесь использовать написанный выше код в браузере, вы получите сообщение об ошибке, в котором будет указано require not defined (не определено). Браузер не имеет доступа к файловой системе, это значит, что загрузка модулей таким способом очень проблематична — загрузка файлов должна выполняться динамически, синхронно (что замедляет исполнение), или асинхронно (что может вызвать проблемы с синхронизацией).
Тут вступает в действие упаковщик модулей. Упаковщик модулей JavaScript — это инструмент, который решает задачу с помощью этапа сборки (он имеет доступ к файловой системе) для создания конечно результата, совместимого с браузером (уже не нужен доступ к файловой системе). В этом случае нам нужен упаковщик модулей для поиска всех утверждений require (а это недопустимый синтаксис JavaScript для браузера) и замены их актуальным содержимым каждого требуемого файла. Конечный результат — один бандл (упакованный файл) JavaScript (без инструкций require)!
Самым популярным упаковщиком модулей был Browserify, он вышел в 2011 году и первым использовал стиль node.js для require во фронтенде (что, по сути, помогло npm стать самым используемым менеджером пакетов для фронтенда). Примерно в 2015 году более популярным стал упаковщик модулей webpack (его подпитывала популярность фронтенд-фреймворка React, который максимально пользовался различными функциями webpack).
Давайте посмотрим, как использовать webpack, чтобы заставить показанный выше пример с require(‘moment’) работать в браузере. Сначала нам нужно установить webpack в проект. Сам webpack — это npm-пакет, поэтому мы можем установить его из командной строки:
Это значит, что мы больше не будем использовать index.js в браузере, так как в нем содержатся недопустимые require утверждения. Вместо этого мы будем использовать вывод bundle.js в браузере, что должно будет отразиться в файле index.html :
Если вы обновите браузер, увидите, что всё работает, как работало раньше!
В целом, может казаться, что тут нет ничего особенного, но в этой рабочей последовательности есть несколько огромных плюсов. Мы больше не загружаем внешние скрипты через глобальные переменные. Любые новые библиотеки JavaScript будут добавляться через require в JavaScript, в отличие от добавления новых тегов
Hexlet Ltd. UMA Esplanadi, Pohjoisesplanadi 39, 00100 Helsinki, Finland VAT ID: FI26641607