Анонсируем Dart Sass +22


В течение нескольких последних месяцев мы тихо работали надо новым проектом. Сегодня я готова анонсировать Dart Sass всему миру. Это абсолютно новая реализация Sass, созданная, чтобы быть быстрой и легкой в установке и разработке. Она еще не завершена — я веду работу по приведению её в соответствие со спецификацией Sass — так что сегодня я просто публикую версию 1.0.0-alpha.1. Но она достаточно надежна, чтобы можно было скачать, поиграться с ней и начать сообщать баги.



Вы можете скачать архив с со страницы релиза — просто распакуйте его, добавьте директорию в path, и запустите dart-sass. Dart также компилируется в JavaScript, так что если у вас установлен npm, то вы можете установить JS-версию запустив npm install -g dart-sass. И если вы сами уже являетесь пользователем Dart, то можете его установить через pub global dart-sass.


Зачем переписывать Sass?


В течение последних нескольких лет было две основные реализации Sass. Ruby Sass был первым, написанным в основном мной при существенной поддержке Криса. Он был высокоуровневым и легким для разработки, и являлся тем местом, где мы обкатывали и выпускали новые возможности. Затем появился LibSass — реализация на C++, изначально созданная Аароном и Хэмптоном, а в настоящее время поддерживается Марселем и Майклом. Это низкоуровневая версия, что делает ее быстрой и легкой в установке и встраивании в другие языки. В частности, байндинг к Node.js является очень популярным способом использования Sass в мире JavaScript.


Достоинства каждой версии дополняют слабости другой. Там где LibSass быстра и переносима, Ruby Sass медленный и сложный к установке не-Ruby пользователями. Зато Ruby Sass проще в разработке, в то время как в LibSass добавлять новые возможности намного сложнее из-за низкоуровнего языка. Хотя взаимодополняющие отношения могут быть здоровыми, но это так же значит, что ни одно из решений не такое хорошее, каким должно бы быть. Это мы обнаружили, когда в мае Марсель официально покинул команду LibSass. (Примечание автора: Я говорю "официально", потому что он все еще принимает участие в проекте по мере возможности, но не в том объеме как официальный разработчик).


Лишенные усилий двух человек, мы были не уверены, что LibSass сможет поддерживать темп, так что Крис и я захотели внести изменения в используемый язык. В течение долгого времени было понятно, что Ruby Sass намного медленнее при обработке больших таблиц стилей. Нам нужна была новая реализация, которая могла бы быстро генерировать CSS и быстро добавлять новую функциональность.


Почему Dart?


Мы рассмотрели несколько возможных языков и остановились на Dart по нескольким причинам. Во-первых, он действительно быстрый – Dart-VM в основном сильно быстрее чем JavaScript VM и предварительные бенчмарки показывают, что для больших файлов Dart Sass в 5-10 раз быстрее Ruby Sass и только в 1,5 раза медленнее LibSass. (Примечание автора: Я не эксперт в бенчмарках, и в тестах были подобраны (ad hoc — пер.) нерепрезентативные исходные файлы. Если кто-нибудь заинтересован в работе над более научными измерениями, дайте мне знать). С опаской предположу, что это будет в 1,5-2 раза быстрее специализированной JS-реализации, но не могу сказать уверенно. Кроме того, производительность Dart улучшается со временем.


В то время как с Dart легко работать — намного легче, чем с C++, и в некоторой степени легче чем с Ruby для такого большого проекта. Конечно, не так много людей знакомы с ним, как с JavaScript, но работа над реализацией языка не подразумевает множества внешних участников в любом случае. Я буду делать большую часть работы над новой реализацией, и Dart это язык с которым я лично чувствую себя комфортно в данный момент (в то время, когда я не работаю над Sass, я в команде Dart). Использование Dart дает мне прибавку в скорости.


В отличие от Ruby или JavaScript, Dart статически типизирован, так что тип каждого значения может быть выведен без необходимости запускать сам код. Также, в отличие от C++, он со сборкой мусора, то есть нам не нужно беспокоиться о приборке за собой. Это делает его легким для написания, правок и поддержки. Может быть, даже более важно то, что он легко транслируется в другие языки программирования, что позволит LibSass получать новые возможности быстрее.


Последняя причина выбора Dart, это то, чем немногие языки могут похвастаться: совместимость с JavaScript. Dart может быть скомпилирован в JavaScript, который может напрямую использоваться в Node.js и даже возможно в браузере. Большая часть экосистемы Sass построена на node-sass, и мы намерены сделать JS-версию Dart Sass как можно более совместимой по API c node-sass, чтобы можно было легко перекинуть на новую версию существующие инструменты и системы сборки.


Единственный недостаток здесь – это провал по скорости: Dart Sass примерно вдвое медленнее при запуске на V8 по сравнению с Dart VM. Однако, он все еще дает уверенный прирост в 3-4 раза по сравнению с Ruby Sass. В итоге, мы также надеемся, что сможем предоставить пользователям JS-версии путь миграции на Dart VM настолько легкий, насколько возможно.


Что же случится с Остальными Реализациями?


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


Больше гибкости выльется в более быстрые релизы LibSass, которые поставят на первый план возможности, которые пользователи хотят сильнее всего. Строгая совместимость значила, что важные нововведения, такие, как, например, поддержка пользовательских CSS-свойств не могут быть выпущены до тех пор, пока не будут обработаны все маленькие и хитрые граничные случаи, которые были в соответствующей версии Ruby Sass, например, объединение :root. Мы все еще стараемся достигать максимальной совместимости, насколько возможно, но мы не будем позволять стоять ей на пути у скорости.


Ruby Sass в конечном итоге уйдет совсем, если не появится новый разработчик для него. Мы не хотим делать переход внезапным, рискуя расколоть экосистему: я и Крис собираемся поддерживать его в течение одного года, что включает поддержку функциональности на том же уровне, что будет добавляться в Dart Sass. Если кто-то заинтересован в участии как разработчик после этого периода, мы будем рады познакомить его с кодом в течение наступающего года. А если никто не выступит, то Ruby Sass будет официально признан устаревшим и неподдерживаемым.


Я хочу подчеркнуть, что мы не совершаем решение прекратить разработку Ruby Sass просто так. Это большое и не простое для меня изменение, я непрерывно работала над ним почти 10 лет, и мне сложно позволить уйти этой истории. Но мы с Крисом тщательно это обсудили и склонились к тому, что это правильный ход. Мы посвятили так много времени Sass, что это больше не имеет смысла тратить это время на реализацию, медленную настолько, что это неприемлемо для наших крупнейших пользователей.


Что дальше


Перед тем как мы выпустим первую стабильную версию Dart Sass, есть несколько больших вещей в нашем списке:


  • Полная совместимость со спецификацией Sass. Здесь все еще есть моменты, где Dart Sass ведет себя неправильно, особенно в отношении @extend. Я не ожидаю никакой особой несовместимости, которую будет трудно решить, спецификация Sass довольно исчерпывающая, так что это лишь дело уменьшения количества непройденных тестов до нуля.


  • Достаточно близкая совместимость с render() из node-sass. Этот API является основной точкой входа в LibSass в мире JavaScript. Именно так системы сборки запускают Sass, пользователи определяют свои собственные Sass-функции и Eyeglass передает свои модули в Sass. Мы хотим поддержать API с достаточной мере, чтобы существующая экосистема работала с Dart Sass.


  • Совместимость Dart и Ruby Sass. Здесь есть несколько случаев, где Dart-функциональность намеренно отличается от Ruby, в частности, там где поведение Ruby расценивается как баг. Мы должны добавить предупреждения об этом в Ruby Sass или, если мы сможем это сделать с минимальными правками, внести новое поведение и в Ruby.

Здесь еще несколько пунктов, которые мы хотели бы сделать в конечном счете, как например поддержка Sass в браузере и предоставление node-sass-совместимой обертки для Sass на Dart VM, но это не блокирует начальный релиз.


В дальнейшем будущем


На несколько следующих месяцев я вижу много работы по становлению Dart Sass стабильнее и совместимее, а также добавление возможностей Sass 3.5 в LibSass. Я думаю, что скорее всего в начале 2017 мы увидим стабильный релиз Dart Sass и версию LibSass 3.5. В это время мы определимся с нашим взглядом на крупную функциональность и начнем работать над Sass 4.0 и его совершенно новой системой модулей.


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



Комментарии (32):

  1. Vilyx
    /#9889568

    На Dart получается писать неплохие консольные программы, то, что раньше делал на Python сейчас делаю на Dart. Не удивлён, что кто-то пишет что-то столь серьёзное как Dart SASS.

    • Alexeyco
      /#9889818

      У меня примерно то же самое с go. Я как-то жил-жил себе крайний год, а потом внезапно осознал, что битбакет-проект для репозиториев «а ты можешь мне написать, чтобы XXX из командной строки?» уже раздулся до 18 штук. Но тут, я думаю, дело вкуса. Что-то о Dart говорят все больше и больше. Надо будет углубиться.

      Кстати, тогда вопрос. С появлением новых ES у Dart вообще есть будущее? Только, пожалуйста, объективно, а не с позиции «я пишу на Dart, поэтому есть».

      • Vilyx
        /#9890508

        Как серверный язык — не знаю, а вот как клиентский вполне, но при условиях. Если разработчики языка используют возможности, которые им даст появление WebAssembly, то получится язык, который свободно обращается с данными на странице и с такой же лёгкостью обрабатывает тяжелые данные. Если говорить про появление ES, то он слабо повлияет на Dart, уже сейчас есть TS, который идеально подходит для любителей JS и всех его странностей. Dart выбирают те, кто пришёл из десктопных языков Java, C# и хочет получить знакомый синтаксис и поведение. Если верить опросу, проведённому в группе Dart, то 50% нынешних разработчиков пришли из Java и 20% из JS.

  2. k12th
    /#9889578 / -6

    В чем смысл sass при наличии less, stylus и postcss — никогда не понимал. «Ура, мы додревнее легаси, которое не умеет медиа-запросы в миксинах»? И да, libsass под виндой — боль.

    • franzose
      /#9889628 / +3

      Windows для разработки — в принципе боль. А по поводу SASS, то он мощнее LESS и Stylus.

      • bustEXZ
        /#9889718 / +1

        Простите. Разбирая ранее разницу между Less и Sass, я выбрал первый. Чем по вашему мнению SASS «мощнее». Может я что-то пропустил?

        • franzose
          /#9889724

          Ну, например, в SASS полноценные циклы и операторы if-else. Собственные функции можно определять непосредственно в коде SASS. Есть карты (map), они удобны для объединения параметров вместо использования нескольких переменных.

          • Vladimir37
            /#9890068

            Это не оверкилл? Стили всё же должны оставаться просто стилями, а не превращаться в ещё один язык программирования.

            • franzose
              /#9890634

              Насчет простоты соглашусь, сам стараюсь держать стили простыми. Но иногда попадаются задачки типа генерации классов или стилей в зависимости от каких-то условий. Вот тогда всякие if-else в помощь)

            • dom1n1k
              /#9891244 / +1

              Условия и циклы нужны.
              Порядка 90-95% стилей спокойно пишется и без них, но вот в оставшиеся 5-10% обходиться без них неудобно.
              Я сам начинал с LESS-а — это очень хороший шаг в сравнении с нативным CSS, и все-таки неполноценность его ощущается.

      • k12th
        /#9889992 / +1

        С первой частью согласен (но рабы на галерах кровавого энтерпрайза не имеют выбора), а со второй — не очень. Циклы — это мило, но на практике за 10 лет вебдева они мне пригодились только один раз, и я спокойно их сделал в less. А вот неполная поддержка синтаксиса CSS в 2016 году — это уже нехорошо как-то.

        • franzose
          /#9890638

          (но рабы на галерах кровавого энтерпрайза не имеют выбора)

          Я бы не стал всех разработчиков на C#, F# и проч. грести под одну гребёнку.


          А вот неполная поддержка синтаксиса CSS в 2016 году

          Тут могу чего-то не знать. В чем она выражается?

          • k12th
            /#9891142

            При чем тут C# и F#? Я в жизни на втором ни строчки не написал, но на работе у всех винда без права выбора.


            Тут могу чего-то не знать. В чем она выражается?

            Попробуйте сделать миксин с media-query внутри.

            • franzose
              /#9891934

              на работе у всех винда без права выбора.

              А, вы об этом. Ну, немножко печально. У нас Linux/Mac/Win, кому как удобно.


              Попробуйте сделать миксин с media-query внутри.

              Хм, а в LESS так можно?

              • k12th
                /#9891940 / +1

                Я потому и сказал «кровавый энтерпрайз»:)


                В LESS можно. Я согласен, кейс не очень частый… примерно как потребность в циклах и if-ах;)

            • franzose
              /#9891936

              Просто никогда такого не требовалось)

            • Flying
              /#9892856

              А с этим есть проблемы? Вот пример в Susy, постоянно этим пользуюсь

              • k12th
                /#9892864

                У нас были. Версия sass была свежая на тот момент.

                • Flying
                  /#9892888

                  Возможно, но сейчас это точно работает, у меня на этом довольно много кода завязано

    • justboris
      /#9890074

      Ура, мы додревнее легаси
      Именно в этом и смысл поста. Они переехали на Dart, чтобы быстрее развиваться и выглядеть современно.

      Ваш вопрос можно перефразировать: в чем смысл less, stylus и postcss при наличии sass?

      • k12th
        /#9890284

        Именно в этом смысл поста.

        Ага, переписать с одного экзотического языка на другой, еще более экзотический. Отличная идея!


        в чем смысл less, stylus и postcss при наличии sass?

        Я вам расскажу: в том, чтобы не тащить на фронтенд ruby, dart, C и прочее. Less почти сразу переписали с того же руби на js именно по этой причине. stylus сразу писали на js. Ну у postcss своя атмосфера парадигма.
        Все, что не написано на джс, из фронтендерского тулбокса рано ило поздно выпадет, как всякие странные сборщики/минификаторы на php, python, .net и т.д. Если бы не emscripten (а еще синдром утенка), libsass бы не спас sass из Леты.

        • bromzh
          /#9890662 / +1

          Я вот sass не пользуюсь именно по причине его сборки. Как минимум раз в месяц возникали проблемы с libsass на билд-сервере. Ладно там phantomjs требует сишных либ и node-gyp, но зачем они препроцессору стилей?

        • franzose
          /#9890666

          Всё, что мне нравится в LESS по сравнению с SASS — это data-uri.

        • justboris
          /#9890674

          В посте как раз и написано, что команда понимает необходимость поставки пакета на чистом JavaScript, поэтому выбрали Dart, который транслируется в JS.

          • k12th
            /#9891134

            Это такой же «чистый js» как libsass собранный emscripten. Формально — JS, а на деле требуется ставить отдельный тулчейн и знать посторонний язык.

            • bromzh
              /#9891166

              Ну всё же они теперь могут сделать npm-модуль и туда поместить js-бандл без зависимостей от внешних сишных либ. Хотя бы так.


              А js сгенерированный из dart всё же лучше js сгенерированного из C

            • justboris
              /#9891186 / +1

              Читайте статью. Там все объясняется.


              1) Нет. Emscripten это слишком низкуровневый интерпретатор. Dart изначально строился с заделом на удобную трансляцию в JS. Поэтому генерируемый им JavaScipt будет проще и оптимальнее, чем чересчур абстрактный LibSass+Emscripten


              2) Для использования тулчейн ставить не надо. npm install dart-sass и готово. Для разработки конечно же придется, но удобство для контрибьюторов не так важно для основных разработчиков, как их собственное.

  3. 3aicheg
    /#9889590 / -4

    А Дарт Сасс круче Дарта Вейдера?

  4. Laney1
    /#9890230

    мне кажется, разработчики SASS занимаются не тем чем надо. Напишите грамматику в любом формате, например ABNF. Загоните ее в yacc или куда угодно. Получите на выходе парсер на нужном вам языке программирования.

    Вместо этого они тратят кучу сил и времени, делая парсеры вручную

    • Dreyk
      /#9890592

      и каждый следующий парсер все равно надо подгонять под ruby-sass, потому что каждый раз проблемы: libsass до сих пор лажает с упомянутыми @extend

    • justboris
      /#9890658

      Напишите issue разработчкикам, расскажите как надо, а то они глупые, не знают как разрабатывать.


      Судя по исходному коду, парсер там не самая большая часть. Намного больше занимает собственно процес трансформации SASS -> CSS