Rust - это быстрый, надежный и экономичный, с точки зрения памяти, язык программирования. Его признавали одним из самых любимых языков программирования шесть лет подряд (на основании опросов).
Созданный Mozilla, он теперь используется в Facebook, Apple, Amazon, Microsoft и Google для системной инфраструктуры, шифрования, виртуализации и низкоуровневого программирования.
Почему Rust сейчас используется для замены таких частей веб-экосистемы JavaScript, как минификация (Terser), транспиляция (Babel), форматирование (Prettier), комплектация (webpack), линтинг (ESLint) и другие?
Что такое Rust?
Rust помогает разработчикам писать быстрое программное обеспечение с эффективным использованием памяти. Это современная замена таким языкам, как C++ или C, с упором на безопасность кода и лаконичный синтаксис.
Rust сильно отличается от JavaScript. JavaScript пытается найти неиспользуемые переменные или объекты и автоматически удаляет их из памяти. Это называется сборкой мусора . Язык отвлекает разработчика от размышлений о ручном управлении памятью.
С помощью Rust разработчики имеют больший контроль над распределением памяти, но это не так болезненно, как C++.
Rust использует относительно уникальный подход к управлению памятью, который включает в себя идею “владения памятью”. В принципе, Rust отслеживает, кто может читать и записывать в память. Он знает, когда программа использует память, и немедленно освобождает память, как только она больше не нужна. Он применяет правила памяти во время компиляции, что делает практически невозможным наличие ошибок в памяти во время выполнения. Вам не нужно вручную отслеживать объем памяти. Компилятор позаботится об этом. – Discord
Принятие (отрицание и гнев уже позади)
Помимо компаний, упомянутых выше, Rust также используется для популярных библиотек с открытым исходным кодом, таких как:
Firecracker (AWS)
Bottlerocket (AWS)
Quiche (Cloudflare)
Neqo (Mozilla)
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).
Некоторые ранние фреймворки в этой области:
Yew
Percy
Seed
Sycamore
Stork
Эти веб-фреймворки на основе 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:
Deno’s литер, модуль форматирования кода и генератор документации, Deno созданы с использованием SWC.
dprint , созданный на основе SWC, является в 30 раз более быстрой заменой для Prettier.
Parcel улучшил общую производительность сборки до 10 раз с помощью SWC.
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.
Это мир, в котором я хочу жить (и развиваться).