Не вебпаком единым

    Представляем лог доклада с 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 собирает бандл?



    ДоксВижн
    45.18
    Company
    Share post

    Comments 22

      0
      del
        +1

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

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

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

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

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

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

              +2

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

                +1

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

                  0

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

                  +2

                  Вообще я сначала хотел написать, что единственный недостаток 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 прописывать. Так что нет, спасибо.

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

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


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

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


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

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

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

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

                        0

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

                          0

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

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

                      я имею ввиду что-то именно технологически важное, т.е. не в духе «там надо настраивать а тут из коробки», а, скажем «дебаг TypeScript исходников в браузерном дебаггере»
                        0

                        Использовать commonjs- и es6-модули.

                          0
                          поправьте меня пожалуйста если я не прав, но вроде как systemjs тоже не может es6-модули загружать в браузер без трансплита?
                            0

                            systemjs основан на https://www.npmjs.com/package/es6-module-loader, эта либа умеет загружать модули без транспиляции (т.е. babel и не нужны, если из es6 вы юзаете только модули).

                      Only users with full accounts can post comments. Log in, please.