Представляем лог доклада с OrelJS о настройке удобной среды разработки с использованием SystemJS. У сборки на основе Webpack полно недостатков, в докладе представляется альтернативный подход на основе SytemJS и JSPM.
Задачи среды разработки
Основная проблема организации среды разработки в том, что у продакшн-сборки и сборки во время разработки разные требования. Для продакшн-сборки список может быть таким:
- Компиляция TypeScript, SASS
- Пост-процессинг
- Tree-shaking
- Сборка бандла
- Минификация
- Загрузка в браузер
Однако, во время разработки нужен только первый и последний пункты. Нам совершенно не нужно, и, более того, вредно собирать и оптимизировать бандл. Но что нам действительно нужно и важно — это удобство разработки.
Что я понимаю под удобством разработки:
- Скорость отображения правок в браузере. Поменяли в исходниках строчку кода — хотим быстро увидеть, как это работает в браузере. Не во всех средах это происходит быстро.
- Удобная отладка. Хочется так: открыли браузер, открыли консоль Dev Tools, легко поставили break point, сопоставили исходники, которые видим в браузере, с тем, что мы редактировали, — и все это прозрачно, удобно и не тормозит.
- Контроль над процессом, промежуточными этапами компиляции и сборки. Допустим, компилируем TypeScript в JavaScript — и надо проверить, что получилось на выходе.
- Управление зависимостями. Оно складывается из двух вещей: управление зависимостями с внешними библиотеками, чтобы было удобно делать подключение одной командой, и управление зависимостями внутри проекта.
Что не так с Webpack
Сейчас хэдлайнером в среде разработки является Webpack. На мой взгляд, у него не все хорошо в плане удобства разработки.
- Чтобы увидеть свои правки в браузере — надо собрать бандл. Строчку кода написали – вебпак собирает бандл; ещё символ сохранили – опять собирает. Плюс ещё проблема – он начинает сборку при изменении файла в файловой системе. Напечатали символ, нажали «Ctrl + S» – собирается бандл. Ещё символ и «Ctrl + S», он снова запускает сборку. Итого 2 бандла собираются одновременно.
- С точки зрения удобства отладки, Webpack – это бандлер, и все, что он умеет, – это собирать бандлы. Чтобы в браузере что-то отлаживать, нужно использовать source map или копаться в огромном куске кода. Проблема с source map в том, что они а) иногда тормозят б) не точно соответствуют TypeScript-исходникам. Если вы пробовали отлаживать async/await конструкции (точнее то, во что они компилируются TypeScript-компилятором) через source map, то вы понимаете, о чем я. Это практически невозможно.
- Контроль над процессом — отсутствует чуть больше, чем полностью. Вебпак – чёрный ящик. Настроили конфиг, вебпак заработал, собрал. Всё. Посмотреть, во что скомпилировался TypeScript или SASS мы не можем.
- Управление зависимостями – тут все хорошо. Даже лучше, чем то, что я предлагаю.
Альтернативная среда разработки на SystemJS и JSPM
Когда я понял, что меня эта ситуация не устраивает, я начал искать альтернативы. Мы используем Visual Studio в разработке, а для него есть классные плагины.
- Для SaSS – WebCompiler, который компилирует SASS в CSS при нажатии сохранении. Отредактировали строчку кода, нажали Ctrl+S — и мгновенно компилируется один единственный файл. На страницу его можно добавить через style-тэг при помощи gulp (это делается однажды, при добавлении/удалении файлов).
- Нативно поддерживается работа с TypeScript. Есть опция компилировать при сохранении – то же самое, обрабатывается один единственный файл и также мгновенно. Правда, потом студия компилирует все остальное (на случай, если файлы зависят друг от друга), но нам ждать уже не обязательно, т.к. наши правки применены. При помощи SystemJS и JSPM наш код загружается в браузер.
SystemJS – это библиотека, загрузчик модулей. Она позволяет загружать модули любых видов (ES6, CommonJS, AMD, UMD, System) в браузер. Представим, что у нас есть три модуля в трех файлах.
Мы импортируем главный модуль, а SystemJS, анализируя зависимости, уже подгружает по цепочке все остальное. Очень удобная схема во время разработки.
В паре с SystemJS идёт JSPM, который избавляет нас от необходимости разбираться с конфигурацией SystemJS. Он все настраивает, умеет собирать бандл для продакшена, и даже из коробки поддерживает Rollup.
Таким образом, во время разработки работает следующая схема:
Преимущества этого подхода:
- Скорость отображения в браузере – мгновенная. Время компиляции одного файла стремится к нулю. Никаких бандлов во время разработки.
- Удобная отладка, потому что все файлы загружаются в браузер по одному. Открыли исходник, разбираемся в нём, и можем чётко провести соответствие тому коду, который мы писали в IDE. Если мы используем source map, мы можем отлаживать TypeScript-код в браузере, если не устраивают source maps — можно отлаживать непосредственно в самом скомпилированном JavaScript. Это намного удобнее, потому что TypeScript обычно генерирует простой и понятный JavaScript. В нем легко разобраться, и он очень похож на оригинал.
- Контроль над процессом – полный. Результат любого промежуточного шага сборки всегда доступен для изучения.
- Управление зависимостями полностью берет на себя JSPM.
Для Angular этот подход тоже применим, разве что там это несколько сложнее. Про возможный рабочий вариант настройки я рассказывал в этой статье.
При сборке продакшн схема примерно такая:
То есть, используем JSPM и Gulp, ничего сложного.
Так что, Вы все еще ждете пока Webpack собирает бандл?
Комментарии (18)
Veikedo
24.01.2018 13:19Поддержка async/await в браузерах уже давненько нативная, поэтому при разработке не имеет смысла их транспайлить в es5 => нет проблем с отладкой
AxisPod
24.01.2018 13:38Чтобы увидеть свои правки в браузере — надо собрать бандл.
Ну да, hot reload вот взяли прям так и отменили во всей вселенной.
Посмотреть, во что скомпилировался TypeScript или SASS мы не можем.
И кто это запретил? Вот почему-то опыта у меня не густо, я сразу задался этим вопросом и вопрос отпал. При это вы сами же и ответили на этот вопрос в виде source map.
Для SaSS – WebCompiler, который компилирует SASS в CSS при нажатии сохранении. Отредактировали строчку кода, нажали Ctrl+S — и мгновенно компилируется один единственный файл.
Ну конечно, куда ведь удобнее ковыряться в одном файле вместо просмотра соответствующего source map. Конечно же удобно по всему проекту удобно имена классов задавать в 50 символом, дабы случайно не переюзать имя для других целей.
Дальше хватит писать, но подобные моменты есть и далее. Так что очень спорное предложение, просто проигнорировав альтернативы данному подходу, да и минусы в целом.PFight77 Автор
24.01.2018 14:35Вы пробовали отлаживать TypeScript по source map? Вот попробуйте.
DAiMor
24.01.2018 15:24А что не так с отладкой TypeScript в браузере? В DevTools На вкладке Sources нахожу свой ts файл, ставлю брейкпойнт ловлю, дебажу на TypeScript коде. Мне даже не нужно смотреть во что он скомпилировался, а зачем вам это надо? Все ошибки которые у меня обычно возникают, возникают не от того как он скомпилировался. Да и если хочется посмотреть скомпилированное просто запустите сборку, кто вам это запрещает.
Zenitchik
24.01.2018 15:28Во всех браузерах?
DAiMor
24.01.2018 15:31Chrome. Я разработку веду с Chrome. Правда у меня канарейка. В остальных браузерах, не проверял, но не уверен, что возможны прям сильные проблемы такие которые нельзя будет оттестировать в Chrome с учетом итоговой компиляции под все браузеры.
Zenitchik
24.01.2018 16:39В принципе, согласен. В других браузерах можно и после сборки посмотреть.
После того, как я дебажил минифицированный код в IE7, следующие версии оного не особо пугают…
dfuse
25.01.2018 00:37Новый? Да ему уже дофига лет… вон, видео из 2015 года https://www.youtube.com/watch?v=NpMnRifyGyw
alex6636
25.01.2018 10:18Новый лично для меня. Почти каждый день узнаю о чём-то новом в JS, тысячи их
k12th
25.01.2018 12:35Вообще я сначала хотел написать, что единственный недостаток Webpack по сравнению с SystemJS — наркоманские конфиги, но потом вспомнил конфиг systemjs (в который еще гадит (простите, по другому назвать не получится) JSPM своей инфой) и передумал.
Поменяли в исходниках строчку кода — хотим быстро увидеть, как это работает в браузере.
C SystemJS вам нужно переключиться на вкладку браузера, нажать F5, дождаться, пока он загрузит и скомпилирует исходники. C Webpack достаточно переключиться на вкладку браузера, live/hot-reload гарантирует, что изменения я увижу автоматически, когда они будут готовы.
Напечатали символ, нажали «Ctrl + S» – собирается бандл. Ещё символ и «Ctrl + S», он снова запускает сборку. Итого 2 бандла собираются одновременно.
Нет, в вебпаке есть троттлинг. И я никогда не видел, чтобы два бандла собирались одновременно (хотя, наверное, этого можно достичь).
Вебпак – чёрный ящик. Настроили конфиг, вебпак заработал, собрал.
Системжс – чёрный ящик. Настроили конфиг, системжс заработал, собрал.
Посмотреть, во что скомпилировался TypeScript или SASS мы не можем.
А в SystemJS как это возможно? Там вообще всё в памяти.
Если очень уж надо — собираем без минификации (закомментить одну строку в конфиге) и смотрим.
Для SaSS – WebCompiler, который компилирует SASS в CSS при нажатии сохранении.
Есть опция компилировать при сохранении – то же самое, обрабатывается один единственный файл и также мгновенно."А за такое можно и канделябром-с..." IDE-зависимая сборка — всегда плохая идея. На дженкинсе студии с плагинами Ctrl+S нету:)
Скорость отображения в браузере – мгновенная. Время компиляции одного файла стремится к нулю.
Webpack не самый быстрый парень по сю сторону джаваскрипта, это правда. Например, новичок ParcelJS, если верить бенчмаркам, куда шустрее. Но это касается только холодного старта, инкрементальные ребилды в процессе разработки занимают столько же, сколько Alt+Tab на браузер и переключение внимания человека. Проблема с полной пересборкой TS решается использованием awesome-ts-loader.
Кстати, rollup сам из коробки или c минимальными плагинами умеет в watch с live-reload. systemjs/jspm тут лишние.
JSPM, который избавляет нас от необходимости разбираться с конфигурацией
Во-первых, два менеджера пакетов в одном проекте (а еще какой-нибудь nuget/pip/composer/gem) это грустно. Во-вторых, последний раз когда я это дело пробовал, время от времени всплывали какие-то мутные проблемы с теми или иными пакетами из npm — то не ставится, то вручную надо shim прописывать. Так что нет, спасибо.
PFight77 Автор
25.01.2018 13:05А в SystemJS как это возможно? Там вообще всё в памяти.
Вы имеете ввиду загрузчик TypeScript для SystemJS, который компилирует на лету. В моем варианте компиляция происходит отдельно от SystemJS, она работает уже с готовым JS.
IDE-зависимая сборка
Ну разумеется отдельная галп-таска для компиляции. Плагины IDE только во время разработки.
изменения я увижу автоматически, когда они будут готовы
Всегда интересовало, как Вы определяете, что изменения уже применились? Допустим, если они визуально не заметны.
k12th
25.01.2018 13:14Всегда интересовало, как Вы определяете, что изменения уже применились? Допустим, если они визуально не заметны.
В консоли видно — она ведь все равно всегда открыта при разработке.
Честно скажу, hot-reload не панацея, он не со всем справляется и иногда все-таки приходится делать F5, но это обычно раз или два в неделю. Но вообще он здорово ускоряет разработку хотя бы за счет отсутствия потери потока и фокуса разработчика. Очень советую попробовать, хотя понимаю, что это не ваша специальность.PFight77 Автор
25.01.2018 23:08Hotreload возможен и для SystemJS, и гугл показывает кучу реализаций, включая стандартную реализацию в JSPM. Я просто правда очень скептически отношусь к этой теме, может напрасно.
k12th
25.01.2018 23:26Попробуйте, если фреймворк поддерживает. Это правда удобно, особенно когда разрабатываемый компонент закопан где-то в интерфейсе и нужно несколько кликов, чтобы его увидеть.
Antiznak
25.01.2018 13:06Никогда такого не было и вот опять. Ожидаю статью из серии «как правильно использовать webpack, systemJS и gulp в рамках одного проекта».
Zenitchik
del