Представляем лог доклада с OrelJS о настройке удобной среды разработки с использованием SystemJS. У сборки на основе Webpack полно недостатков, в докладе представляется альтернативный подход на основе SytemJS и JSPM.



Задачи среды разработки


Основная проблема организации среды разработки в том, что у продакшн-сборки и сборки во время разработки разные требования. Для продакшн-сборки список может быть таким:


  • Компиляция TypeScript, SASS
  • Пост-процессинг
  • Tree-shaking
  • Сборка бандла
  • Минификация
  • Загрузка в браузер

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


Что я понимаю под удобством разработки:


  1. Скорость отображения правок в браузере. Поменяли в исходниках строчку кода — хотим быстро увидеть, как это работает в браузере. Не во всех средах это происходит быстро.
  2. Удобная отладка. Хочется так: открыли браузер, открыли консоль Dev Tools, легко поставили break point, сопоставили исходники, которые видим в браузере, с тем, что мы редактировали, — и все это прозрачно, удобно и не тормозит.
  3. Контроль над процессом, промежуточными этапами компиляции и сборки. Допустим, компилируем TypeScript в JavaScript — и надо проверить, что получилось на выходе.
  4. Управление зависимостями. Оно складывается из двух вещей: управление зависимостями с внешними библиотеками, чтобы было удобно делать подключение одной командой, и управление зависимостями внутри проекта.

   Что не так с Webpack


Сейчас хэдлайнером в среде разработки является Webpack. На мой взгляд, у него не все хорошо в плане удобства разработки.


  1. Чтобы увидеть свои правки в браузере — надо собрать бандл. Строчку кода написали – вебпак собирает бандл; ещё символ сохранили – опять собирает. Плюс ещё проблема – он начинает сборку при изменении файла в файловой системе. Напечатали символ, нажали «Ctrl + S» – собирается бандл. Ещё символ и «Ctrl + S», он снова запускает сборку. Итого 2 бандла собираются одновременно.
  2. С точки зрения удобства отладки, Webpack – это бандлер, и все, что он умеет, – это собирать бандлы. Чтобы в браузере что-то отлаживать, нужно использовать source map или копаться в огромном куске кода. Проблема с source map в том, что они а) иногда тормозят б) не точно соответствуют TypeScript-исходникам. Если вы пробовали отлаживать async/await конструкции (точнее то, во что они компилируются TypeScript-компилятором) через source map, то вы понимаете, о чем я. Это практически невозможно.
  3. Контроль над процессом — отсутствует чуть больше, чем полностью. Вебпак – чёрный ящик. Настроили конфиг, вебпак заработал, собрал. Всё. Посмотреть, во что скомпилировался TypeScript или SASS мы не можем.
  4. Управление зависимостями – тут все хорошо. Даже лучше, чем то, что я предлагаю.

   Альтернативная среда разработки на 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.


Таким образом, во время разработки работает следующая схема:


Схема среды разработки

Преимущества этого подхода:


  1. Скорость отображения в браузере – мгновенная. Время компиляции одного файла стремится к нулю. Никаких бандлов во время разработки.
  2. Удобная отладка, потому что все файлы загружаются в браузер по одному. Открыли исходник, разбираемся в нём, и можем чётко провести соответствие тому коду, который мы писали в IDE. Если мы используем source map, мы можем отлаживать TypeScript-код в браузере, если не устраивают source maps — можно отлаживать непосредственно в самом скомпилированном JavaScript. Это намного удобнее, потому что TypeScript обычно генерирует простой и понятный JavaScript. В нем легко разобраться, и он очень похож на оригинал.
  3. Контроль над процессом – полный. Результат любого промежуточного шага сборки всегда доступен для изучения.
  4. Управление зависимостями полностью берет на себя JSPM.

Для Angular этот подход тоже применим, разве что там это несколько сложнее. Про возможный рабочий вариант настройки я рассказывал в этой статье.


При сборке продакшн схема примерно такая:


Продакшн сборка: используем gulp для сборки стилей и JSPM для формирования бандла

То есть, используем JSPM и Gulp, ничего сложного.


Так что, Вы все еще ждете пока Webpack собирает бандл?



Комментарии (18)


  1. Zenitchik
    24.01.2018 12:47

    del


  1. Veikedo
    24.01.2018 13:19

    Поддержка async/await в браузерах уже давненько нативная, поэтому при разработке не имеет смысла их транспайлить в es5 => нет проблем с отладкой


  1. AxisPod
    24.01.2018 13:38

    Чтобы увидеть свои правки в браузере — надо собрать бандл.
    Ну да, hot reload вот взяли прям так и отменили во всей вселенной.
    Посмотреть, во что скомпилировался TypeScript или SASS мы не можем.
    И кто это запретил? Вот почему-то опыта у меня не густо, я сразу задался этим вопросом и вопрос отпал. При это вы сами же и ответили на этот вопрос в виде source map.
    Для SaSS – WebCompiler, который компилирует SASS в CSS при нажатии сохранении. Отредактировали строчку кода, нажали Ctrl+S — и мгновенно компилируется один единственный файл.
    Ну конечно, куда ведь удобнее ковыряться в одном файле вместо просмотра соответствующего source map. Конечно же удобно по всему проекту удобно имена классов задавать в 50 символом, дабы случайно не переюзать имя для других целей.

    Дальше хватит писать, но подобные моменты есть и далее. Так что очень спорное предложение, просто проигнорировав альтернативы данному подходу, да и минусы в целом.


    1. PFight77 Автор
      24.01.2018 14:35

      Вы пробовали отлаживать TypeScript по source map? Вот попробуйте.


      1. DAiMor
        24.01.2018 15:24

        А что не так с отладкой TypeScript в браузере? В DevTools На вкладке Sources нахожу свой ts файл, ставлю брейкпойнт ловлю, дебажу на TypeScript коде. Мне даже не нужно смотреть во что он скомпилировался, а зачем вам это надо? Все ошибки которые у меня обычно возникают, возникают не от того как он скомпилировался. Да и если хочется посмотреть скомпилированное просто запустите сборку, кто вам это запрещает.


        1. Zenitchik
          24.01.2018 15:28

          Во всех браузерах?


          1. DAiMor
            24.01.2018 15:31

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


            1. Zenitchik
              24.01.2018 16:39

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


        1. PFight77 Автор
          24.01.2018 17:30

          Видимо зависит от проекта.


  1. alex6636
    24.01.2018 23:42

    Ого, опять новый инструмент в мире JS, как-то даже не верится!


  1. dfuse
    25.01.2018 00:37

    Новый? Да ему уже дофига лет… вон, видео из 2015 года https://www.youtube.com/watch?v=NpMnRifyGyw


    1. alex6636
      25.01.2018 10:18

      Новый лично для меня. Почти каждый день узнаю о чём-то новом в JS, тысячи их


  1. 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 прописывать. Так что нет, спасибо.


    1. PFight77 Автор
      25.01.2018 13:05

      А в SystemJS как это возможно? Там вообще всё в памяти.

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


      IDE-зависимая сборка

      Ну разумеется отдельная галп-таска для компиляции. Плагины IDE только во время разработки.


      изменения я увижу автоматически, когда они будут готовы

      Всегда интересовало, как Вы определяете, что изменения уже применились? Допустим, если они визуально не заметны.


      1. k12th
        25.01.2018 13:14

        Всегда интересовало, как Вы определяете, что изменения уже применились? Допустим, если они визуально не заметны.

        В консоли видно — она ведь все равно всегда открыта при разработке.
        Честно скажу, hot-reload не панацея, он не со всем справляется и иногда все-таки приходится делать F5, но это обычно раз или два в неделю. Но вообще он здорово ускоряет разработку хотя бы за счет отсутствия потери потока и фокуса разработчика. Очень советую попробовать, хотя понимаю, что это не ваша специальность.


        1. PFight77 Автор
          25.01.2018 23:08

          Hotreload возможен и для SystemJS, и гугл показывает кучу реализаций, включая стандартную реализацию в JSPM. Я просто правда очень скептически отношусь к этой теме, может напрасно.


          1. k12th
            25.01.2018 23:26

            Попробуйте, если фреймворк поддерживает. Это правда удобно, особенно когда разрабатываемый компонент закопан где-то в интерфейсе и нужно несколько кликов, чтобы его увидеть.


  1. Antiznak
    25.01.2018 13:06

    Никогда такого не было и вот опять. Ожидаю статью из серии «как правильно использовать webpack, systemJS и gulp в рамках одного проекта».