Rust - это быстрый, надежный и экономичный, с точки зрения памяти, язык программирования. Его признавали одним из самых любимых языков программирования шесть лет подряд (на основании опросов).

Созданный Mozilla, он теперь используется в FacebookAppleAmazonMicrosoft и Google для системной инфраструктуры, шифрования, виртуализации и низкоуровневого программирования.

Почему Rust сейчас используется для замены таких частей веб-экосистемы JavaScript, как минификация (Terser), транспиляция (Babel), форматирование (Prettier), комплектация (webpack), линтинг (ESLint) и другие?

Что такое Rust?

Rust помогает разработчикам писать быстрое программное обеспечение с эффективным использованием памяти. Это современная замена таким языкам, как C++ или C, с упором на безопасность кода и лаконичный синтаксис.

Rust сильно отличается от JavaScriptJavaScript пытается найти неиспользуемые переменные или объекты и автоматически удаляет их из памяти. Это называется сборкой мусора . Язык отвлекает разработчика от размышлений о ручном управлении памятью.

С помощью Rust разработчики имеют больший контроль над распределением памяти, но это не так болезненно, как C++.

Rust использует относительно уникальный подход к управлению памятью, который включает в себя идею “владения памятью”. В принципе, Rust отслеживает, кто может читать и записывать в память. Он знает, когда программа использует память, и немедленно освобождает память, как только она больше не нужна. Он применяет правила памяти во время компиляции, что делает практически невозможным наличие ошибок в памяти во время выполнения. Вам не нужно вручную отслеживать объем памяти. Компилятор позаботится об этом. – Discord

Принятие (отрицание и гнев уже позади)

Помимо компаний, упомянутых выше, Rust также используется для популярных библиотек с открытым исходным кодом, таких как:

Rust умножал силы для нашей команды, и ставка на Rust была одним из лучших решений, которые мы приняли. Больше, чем производительность, его эргономика и ориентация на правильность помогли нам укротить сложность синхронизации. Мы можем закодировать сложные инварианты о нашей системе в системе типов и попросить компилятор проверить их для нас. – Dropbox

От JavaScript к Rust

JavaScript - наиболее широко используемый язык программирования, работающий на каждом устройстве с веб-браузером. За последние десять лет вокруг JavaScript была построена огромная экосистема:

  • Webpack: разработчики хотели объединить несколько файлов JavaScript в один.

  • Babel: разработчики хотели написать современный JavaScript, поддерживая старые браузеры.

  • Terser: разработчики хотели создать файлы как можно меньшего размера.

  • Prettier: разработчики хотели, чтобы самоуверенный форматер кода просто работал.

  • ESLint: разработчики хотели найти проблемы со своим кодом перед развертыванием.

Написаны миллионы строк кода и исправлено еще больше ошибок, чтобы создать основу для современных веб-приложений. Все эти инструменты написаны на JavaScript или TypeScript. Это сработало хорошо, но мы достигли максимальной оптимизации с помощью JS. Это вдохновило на создание нового класса инструментов, предназначенных для значительного повышения производительности веб-разработки.

SWC

SWC , создан в 2017 году, представляет собой расширяемую платформу на основе Rust для следующего поколения быстрых инструментов разработки. Он используется такими инструментами, как Next.js, Parcel и Deno, а также такими компаниями, как Vercel, ByteDance, Tencent, Shopify и другими.

SWC можно использовать для компиляции, минификации, сборки в бандлы и т.д. - в нем заложены возможности для расширения. Это то, что вы можете использовать для трансформаций кода (встроенных или кастомных). Выполнение этих трансформаций происходит с помощью инструментов более высокого уровня, таких как Next.js.

Deno

Deno, создан в 2018 году, представляет собой простую, современную и безопасную среду выполнения для JavaScript и TypeScript, использующую V8 и построенную на Rust. Это попытка заменить Node.js, предпринятая создателями Node.js. Хотя он был создан в 2018 году, он не достиг версии 1.0 до мая 2020 года.

Линтер, модуль форматирования кода и генератор документации Deno созданы с использованием SWC.

esbuild

esbuild , создан в январе 2020 года, представляет собой сборщик и минификатор JavaScript в 10-100 раз быстрее, чем существующие инструменты, написанные на Go.

Я пытаюсь создать инструмент сборки, который A) хорошо работает для заданных вариантов использования (сборка JavaScript, TypeScript и, возможно, CSS) и B) меняет ожидания сообщества относительно того, что означает быть быстрым для инструмента сборки JavaScript. На мой взгляд, наши текущие инструменты работают слишком медленно. - Эван, создатель esbuild Источник

Создание инструментов разработчика для JavaScript с использованием языков системного программирования, таких как Go и Rust, было довольно узкой нишей, пока не был выпущен esbuild. На мой взгляд, esbuild вызвала широкий интерес к попыткам сделать инструменты разработчика более быстрыми. Эван решил использовать Go:

Реализация на Rust, вероятно, могла бы работать с такой же скоростью. Но на высоком уровне с Go было гораздо удобнее работать. Это мой side project, и мне должно быть приятно работать над ним. - Эван, создатель esbuild Источник

Некоторые утверждают, что Rust может работать лучше, но оба могут достичь первоначальной цели Эвана - повлиять на сообщество:

Даже с простой базовой оптимизацией Rust смог превзойти версию Go с глубчайшей ручной оптимизацией. Это неоспоримое свидетельство того, насколько легко писать эффективные программы на Rust по сравнению с тем глубоким погружением, которое мы сделали с Go. - Discord

Rome

Rome , создан в августе 2020 года, представляет собой линтер, компилятор, сборщик, средство запуска тестов и многое другое для JavaScript, TypeScript, HTML, JSON, Markdown и CSS. Он нацелен на замену и унификацию всей цепочки инструментов фронтенд-разработки. Создатель Себастьян , который также создал Babel.

Зачем тогда все переписывать?

Внесение необходимых изменений в Babel, чтобы сделать его надежной базой для других инструментов, потребовало бы изменений абсолютно всего. Архитектура привязана к первоначальным дизайн-решениям, которые я сделал в 2014 году, когда изучал парсеры, AST и компиляторы. - Себастьян Источник

В настоящее время Rome написан на TypeScript и работает на Node.js. Но сейчас они работают над переписыванием на Rust с использованием парсера RSLint и собственной системой обхода для AST трансформаций.

NAPI

Интеграция Rust с Node.js лучше, чем с другими низкоуровневыми языками.

napi-rs позволяет создавать предварительно скомпилированные модули Node.js с помощью Rust. Он обеспечивает решение из коробки для кросс-компиляции и публикации нативных бинарников в npm, без необходимости использования node-gypили postinstallскиптов.

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

Rust + WebAssembly

WebAssembly  (WASM)  - это портируемый низкоуровневый язык, в который может компилироваться Rust. Он работает в браузере, совместим с JavaScript и поддерживается всеми современными браузерами.

WASM определенно намного быстрее чем JS, но не на уровне нативного кода. В наших тестах Parcel работает в 10-20 раз медленнее при компиляции в WASM, чем с собственными двоичными файлами. - Девон Говетт

Хотя WASM еще не является идеальным решением, он может помочь разработчикам создавать чрезвычайно быстрые веб-интерфейсы. Команда Rust стремится к качественной и современной реализации WASM. Для разработчиков это означает, что у вас может быть преимущество в производительности Rust (по сравнению с Go) при компиляции для веба (с использованием WASM).

Некоторые ранние фреймворки в этой области:

Эти веб-фреймворки на основе Rust, которые компилируются в WASM, они не пытаются заменить JavaScript, но работают вместе с ним. Пока мы не достигли этого, интересно наблюдать, как Rust наступает на пятки вебу с обеих сторон: ускорение существующих инструментов JavaScript и перспективные идеи для компиляции в WASM .

Куда ни поди всюду Rust.

Почему бы не Заржаветь? (Rust в переводе - ржавчина)

У Rust крутая кривая обучения. Это более низкий уровень абстракции, чем тот, к которому привыкло большинство веб-разработчиков.

Когда вы работаете с собственным кодом (через Rust, Go, Zig или другие низкоуровневые языки), алгоритмы и структуры данных становятся более важными, чем выбор языка. Это не серебряная пуля.

Rust заставляет задуматься о размерах вашего кода, что имеет огромное значение для системного программирования. Это заставляет задуматься о том, как память распределяется или копируется. Это заставляет задуматься о реальных, но маловероятных краевых случаях и убедиться, что они решены. Это помогает вам писать код, который невероятно эффективен во всех возможных отношениях. - Том Макрайт Источник

Более того, использование Rust в веб-сообществе все еще остается нишевым. Он не достиг критического уровня принятия. Несмотря на то, что изучение инструментов Rust для JavaScript будет препятствием для входа, интересно, что разработчики предпочли бы иметь более быстрый инструмент, в который труднее внести свой вкладПобеждает быстрое программное обеспечение .

В настоящее время сложно найти библиотеку или фреймворк на Rust для ваших любимых сервисов (таких как работа с аутентификацией, базами данных, платежными системами и т.д.). Я действительно думаю, что как только Rust и WASM будут приняты критически, проблема исчезнет сама собой. Но не сейчас. Нам нужны существующие инструменты JavaScript, которые помогут нам преодолеть разрыв и постепенно внедрять улучшения производительности.

Будущее инструментов для JavaScript

Я верю, что Rust - это будущее инструментов JavaScript. Next.js 12 начал наш переход, чтобы полностью заменить Babel (транспиляция) и Terser (минификация) на SWC и Rust. Почему?

  • Расширяемость: SWC можно использовать внутри Next.js, без необходимости форкать библиотеку или обходить ограничения проектирования.

  • Производительность: нам удалось добиться ~ 3-кратного ускорения Fast Refresh и ~ 5-кратного ускорения сборки в Next.js путем перехода на SWC, при этом не все возможнсти для оптимизации еще исчерпаны.

  • WebAssembly: поддержка WASM в Rust необходима для поддержки всех возможных платформ и повсеместной разработки Next.js.

  • Сообщество: Сообщество и экосистема Rust потрясающие и только растут.

SWC внедряется не только в Next.js:

Parcel использует SWC как библиотеку. Раньше мы использовали синтаксический анализатор Babel и кастомные трансформации, написанные на JS. Теперь мы используем синтаксический анализатор SWC и настраиваемые преобразования в Rust . Это включает в себя полную реализацию сборки, сбор зависимостей и многое другое. По своим масштабам он похож на то, как Deno построил на основе SWC. - Девон Говетт

Для Rust это только начало - несколько важных моментов еще не решены:

  • Плагины: написание плагинов на Rust не слишком доступно для многих разработчиков JavaScript. В то же время использование системы плагинов в JavaScript может свести на нет прирост производительности. Окончательного решения пока нет. В идеале будущее сочетает в себе как JavaScript, так и Rust. Если вы хотите написать плагин с помощью JavaScript, это возможно, если вы заплатите за скорость. Требуется больше производительности? Используйте API плагина Rust.

  • Объединение: Одна интересная область разработки - swcpackэто замена SWC для Webpack. Он все еще находится в стадии разработки, но может быть очень многообещающим.

  • WebAssembly: как упоминалось выше, перспектива написания Rust и компиляции в WASM заманчива, но еще предстоит поработать.

Тем не менее, я уверен, что Rust продолжит оказывать серьезное влияние на экосистему JavaScript в следующие 1-2 года и в будущем. Представьте себе мир, в котором все инструменты сборки, используемые в Next.js, написаны на Rust, что обеспечивает оптимальную производительность. Затем Next.js можно было бы распространять как статический двоичный файл, который вы загружали из NPM.

Это мир, в котором я хочу жить (и развиваться).

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


  1. YChebotaev
    24.11.2021 10:58
    +12

    Экосистема js такая развитая, потому что в ней все знают js и пишут на нем. Любой может написать плагин к популярному инструменту типа вебпака или Бабеля. А на расте плагины смогут писать единицы

    Например, сейчас next 12 перешёл на swc, но мы не можем обновиться потому что у нас подключены плагины которые не реализованы для swc. И поделать с этим ничего нельзя - Раст в команде никто не знает

    Так что мейнстримом такой подход точно не будет

    Ну и ещё не только на расте пишут но и на го. Го не сильно медленнее, но в разы проще. Если уж и писать тулинг на чем-то нативном, то на нем

    Компиляция в wa даёт всего-то 20% плюс к производительности, игра не стоит свеч. Это имеет смысл когда нужно переиспользовать нативную библиотеку, или скрыть сорцы от посторонних глаз. Но тоже не мейнстрим


    1. Gordon01
      24.11.2021 11:23
      +1

      Раст — это просто очередной язык, в котором некоторые вещи сделаны не так, потому что в остальных языках очень долгое время абсолютной нормой считалось компилировать и запускать (падая в рантайме) очевидно ошибочный код. В остальном — это просто еще один язык с си-подобным синтаксисом. За месяц литкода любой разраб будет на нем писать.

      В го можно читать из переменных, которые не были инициализированны. Длинна неинициализированного массива — 0. Даже в TS такой дичи нет.

      Го не сильно медленнее, но в разы проще.

      До тех пор, пока в коде не появились неявные ошибки.


      1. Stronix
        24.11.2021 12:36
        +2

        В го можно читать из переменных, которые не были инициализированны.

        А вы хотя бы букварь читали? https://go.dev/tour/basics/12

        Длинна неинициализированного массива — 0.

        Это как? >An array's length is part of its type


        1. falconandy
          24.11.2021 12:57

          Длинна неинициализированного массива — 0.

          Под массивом наверно имеется в виду slice.
          Из того же букваря go.dev/tour/moretypes/12:
          The zero value of a slice is nil.
          A nil slice has a length and capacity of 0 and has no underlying array.


        1. Gordon01
          24.11.2021 14:43
          -1

          А вы хотя бы букварь читали? https://go.dev/tour/basics/12

          А вы? Там написано что неинициализированные переменные неявно "инициализируются" каким-то рандомным значением, которое разработчики почему-то посчитали подходящим.

          Это не инициализация, это присваивание переменным рандомного значения, которое ничем не лучше мусора, который си читает из неинициализированной памяти.

          Это как? >An array's length is part of its type

          Ниже вам уже написали, но если хотите, можете продолжать блистать знаниями терминологии.

          A nil slice has a length and capacity of 0 and has no underlying array.


          1. falconandy
            24.11.2021 15:47
            +3

            Где там написано про «какое-то рандомное значение»? Значение вполне определенное и зависит от типа переменной — ноль, false, пустая строка, nil.


            1. Gordon01
              24.11.2021 16:00
              -9

              ноль, false, пустая строка, nil.

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

              Очевидно, они ошиблись.


              1. SadOcean
                25.11.2021 11:21
                +3

                То, что вы считаете их неудачными - это одно.

                Но они не рандомные - они весьма конкретные и каждый раз одинаковые.


        1. alexesDev
          29.11.2021 12:11

          Он про такой кейс. ИМХО есть и есть, язык простой, пару особенностей запомнить не так сложно, но на любителя да.

          var data []int; fmt.Println(len(data)) // -> 0

          Массив может быть nil (выше ситуация), а может быть нулевой длины. Особой разницы нет в повседневной работе, кроме случаев JSON серелизации, тк nil будет null, а не []


    1. sheknitrtch
      24.11.2021 11:36
      +8

      Я наблюдал подобную ситуацию при появлении Scala и Kotlin. Матёрые Java программисты с опытом 10+ лет посмеивались над новыми языками, ведь всё тоже самое можно сделать на Java. Но вот уже вышла Scala 3 и нашла своё приминение в Kafka, Spark, BigData, а Kotlin постепенно захватывает Android разработку.

      В современно ИТ нет одного языка, который объединит все остальные. Наоборот каждый пишет на том, что удобнее. Я думаю найдутся любители Rust во фронтэнде, и от этого никому не будет хуже.


      1. YChebotaev
        24.11.2021 14:56
        -3

        Во фронтенде было несколько таких попыток: CoffeScript, Dart, теперь вот TypeScript. Кроме TypeScript-а никто не прижился, но даже с учетом всей его популярности, он все равно не лидер пока.
        Вот, приложил сравнение количества PR-ов на GH по котлину vs джаве, джава vs скала и TS vs JS.


        1. Gordon01
          24.11.2021 18:12
          +5

          Всегда меня так веселят оголотелые староверы любители того-самого правильно.

          Но потом, через 5-10 лет почему-то пишут "ой, что-то на Делфи и Паскале вакансий не найти", "ой, что-то ПХПшникам платят меньше чем доставщикам пиццы"


          1. YChebotaev
            25.11.2021 02:02
            -1

            Может, в будущем что-то и изменится но пока что JS помирать не собирается


            1. muturgan
              25.11.2021 09:23

              А медианная зарплата в этих вакансиях одинаковая?


              1. YChebotaev
                25.11.2021 23:17

                За год тайпскриптеры получают на 10% больше на рынке США.

                Но какое это имеет отношение к обсуждаемой теме?


                1. muturgan
                  26.11.2021 10:11
                  +1

                  Я к тому что нужно смотреть не только на количество, но и на "качество" вакансий.

                  Хотя возможно я не особо разобрался в сути вашего сообщения, и мой комментарий и неуместен. Вы же только говорите что спрос на js программистов есть, а это именно так.


            1. Gordon01
              25.11.2021 11:18
              +1

              Когда наступит будущее и все изменится уже поздно будет пить боржоми


              1. KanuTaH
                25.11.2021 14:27
                +1

                Из всего пестрого многообразия "стильных-модных-молодежных" язычков в мейнстрим пробиваются единицы. Вот выше вспомнили про Scala и Kotlin (которым в общем-то тоже ещё далеко до мейнстрима, это нишевые языки), а про тот же Groovy не упомянули - забыли наверное, да? :) (неудивительно). Просто не всем нравится тратить свое время на переписывание coreutils и прочих велосипедов на очередном маргинальном языке из списка "other programming languages" у TIOBE, а выучить "очередной язык с си-подобным синтаксисом" в случае необходимости проблемой не является. А вот возникнет ли эта необходимость - это отдельный вопрос.


                1. Chamie
                  25.11.2021 16:40
                  +3

                  Вот выше вспомнили про Scala и Kotlin (которым в общем-то тоже ещё далеко до мейнстрима, это нишевые языки)
                  Kotlin же аж основной рекомендованный Гуглом язык для разработки под Андроид. Или мейнстрим — это когда он популярнее Джавы будет во всех сферах, включая легаси?


    1. justboris
      25.11.2021 15:19
      +2

      Подобное уже случалось во фронтенде. Была библиотека libsass, написанная на C++. Однако из-за неудобного стека, новые фичи добавлялись катастрофически медленно. В результате, libsass всё, закрылся.

      Возможно библиотекам на Rust повезет больше, потому что язык более дружелюбный, но время покажет


  1. korsetlr473
    24.11.2021 15:45
    -5

    бред какойто TS будет в вебасамбли , зачем еще одна прослойка , явно автор курил чтото или сам запутался ....


  1. Chamie
    24.11.2021 20:17

    быстрее, чем JS, но не совсем по скорости
    Быстрее, но не по скорости? Это как, вообще? В оригинале
    WASM is definitely a lot faster than JS, but not quite native speed.
    Т.е., быстрее JS, но не на уровне нативного кода.


    1. Avelot Автор
      24.11.2021 22:59
      +1

      Спасибо, поправлю


    1. JSmitty
      24.11.2021 23:57
      -1

      В оригинале тоже очевидно враньё - некоторые тесты показывают единицы процентов на одинаковых алгоритмах, отдельные - деградацию wasm относительно JS. Да, счётные задачки типа расчёта фракталов - хорошо дробятся в wasm. Ну, может SIMD теперь еще ощутимо подпихнёт в некоторых кейсах. Но вот прям заявлять "a lot faster" - кмк перебор.


  1. cy-ernado
    25.11.2021 11:10
    +3

    Основная причина, почему Vercel выбрала Rust, а не Go (и написала эту статью) — им удалось купить мейнтейнеров SWC и получить полный контроль над проектом.

    Аналог на Go (esbuild) не уступает по скорости и функциональности, а где-то даже превосходит решение на Rust. Единственная проблема — его пишет технический директор Figma, поэтому купить его затруднительно, а это противоречит бизнес-модели Vercel.


    1. justboris
      25.11.2021 15:14
      +1

      esbuild и swc - это не аналоги, один инструмент другой не заменяет. esbuild – это бандлер (вроде webpack), а swc – транспайлер (вроде babel)


      1. cy-ernado
        25.11.2021 15:42
        +1

        Ну да, esbuild не только транспайлер, но и бандлер. Поэтому я и написал, что "где-то даже превосходит".


        1. justboris
          25.11.2021 15:48
          +4

          Возможности транспайлера в esbuild настолько ограниченные, что я бы их всерьез рассматривать бы и не стал.

          Более того, сам Эван так и говорит – хотите нормальный транспайлер, берите swc


  1. eshimischi
    29.11.2021 05:27
    +1

    Rust вряд ли сменит JS, мне он видится больше языком для wasm, написания утилит для сборки, оптимизации и прочих прикладных задач для node.js/deno. За пару лет собрал несколько интересных проектов. "Убийца" Electron - Tauri и вот буквально вчера попал на проект PostCSS-RS.