Ваши первые шаги в будущем разработки, повышение производительности, сильные типы и многое другое в JS
Еще до своего запуска WASM стал важной технологией в сообществе разработчиков. Некоторые разработчики могут предпочесть избегать этого и продолжать использовать JavaScript и TypeScript, что является абсолютно допустимой настройкой для большинства случаев использования. Однако WebAssembly привнес непревзойденную производительность и безопасность типов в мир внешнего интерфейса (и не только).
WebAssembly (или WASM) — это двоичный язык, который эффективно преобразуется в машинный код браузером, который выполняет его намного эффективнее, чем JavaScript. WASM позволяет таким языкам, как C, Rust и Zig, выполнять свой код в браузере (очевидно, в песочнице).
WebAssembly не только для браузера. На самом деле, Stellar, например, создает собственную среду смарт-контрактов для выполнения WASM в сети. Это означает, что веб-сборка станет важным игроком в различных отраслях.
Скорость была движущим фактором при создании WASM, и хакеры внедрили вредоносный код JavaScript на уязвимые веб-сайты, чтобы загрузить код, написанный на wasm, и выполнять тяжелые вычисления для майнинга криптовалюты непосредственно с процессора посетителя веб-сайта, доказывая, что производительность WebAssembly находится на совершенно другом уровне по сравнению с к JavaScript.
Как бы мне ни хотелось поговорить о потенциальных угрозах безопасности, которые wasm привносит в игру, тем более, что я был заинтересован и участвовал в некоторых исследованиях веб-безопасности, которые заслуживают отдельной статьи, и эта не такова.
Сегодня мы рассмотрим основы работы с Rust, чтобы собрать WASM и выполнить его из любого кода JavaScript (без использования сборщиков).
Эта статья предназначена либо для тех, кто знаком с основами Rust и хочет увидеть, насколько мощным он может быть даже в браузере, либо для любознательных JS-разработчиков, желающих потенциально изменить свой набор инструментов и изучить основы WASM.
Настраивать
Вам понадобится стандартная установка Rust, которая, я полагаю, у вас уже есть на вашей машине, если вы уже работали с этим языком.
Кроме того, я рекомендую установить cargo-generate, чтобы получить базовую настройку rustwasm в вашем каталоге всего за пару нажатий клавиш:
cargo install cargo-generate
Вы также захотите установить wasm-pack для сборки (и не только) WebAssembly из Rust. Вот команда:
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
Теперь у вас есть все необходимое для начала, так что давайте создадим наш проект:
cargo generate --git https://github.com/rustwasm/wasm-pack-template
Это попросит вас ввести имя проекта. Выбирайте то, что считаете более подходящим. Для этого поста я решил использовать «тестирование».
Импортируйте свою первую функцию Rust в JS
Вы заметите, что структура нашего проекта похожа на большинство грузовых проектов. Файл src/lib.rs
(корневой файл нашего проекта) — это тот, который мы скомпилируем в WASM. Затем у нас есть наш известный файл Cargo.toml
для управления зависимостями, настройками, метаданными и так далее.
Откройте lib.rs
и давайте посмотрим на его текущий код.
Это простой начальный шаблон, который использует wasm-bindingen
для импорта функции оповещения JavaScript, а затем определяет (общедоступную) функцию greet
, которая будет вызываться JS в будущем. Мы можем игнорировать строки, которые устанавливают распределитель elfin как глобальный, если функция wee_alloc
включена.
Теперь мы хотим сделать две вещи:
- скомпилировать код rust в wasm
- импортируйте wasm и вызовите функцию
greet
со страницыindex.html
.
Сборка WASM из кода Rust
Поскольку многие разработчики предпочитают использовать разные сборщики, я решил не использовать сборщик для этой статьи, чтобы читатель мог продолжить с помощью простого HTML-файла. Для этого мы будем использовать флаг --target web
при построении WASM с wasm-pack
.
В каталоге ящика выполните следующее:
wasm-pack build --target web
Это создаст несколько файлов в папке ./pkg
. В этих файлах есть двоичный файл wasm (projectname_bg.wasm
) и файл js (projectname.js
), предоставляющий удобный API для загрузки функций WASM в JavaScript.
Запуск функции приветствия
В корне вашего проекта создайте файл index.html
и импортируйте файл ./pkg/projectname.js
. Это позволит вам запустить wasm API и вызвать функцию greet()
. HTML-файл должен выглядеть так:
Если вы теперь обслуживаете файл index.html
(я использую Snowpack, поэтому snowpack dev
находится в корневом каталоге), вы увидите всплывающее предупреждение, вызванное функцией greet()
:
Изменение DOM
Этот раздел предполагает, что вы прочитали предыдущий раздел.
Вышеупомянутый раздел предоставляет почти все, что вам нужно для загрузки Rust в браузере. Вам также может быть интересно, как изменить DOM прямо из Rust. В этом абзаце я быстро покажу вам, как это сделать.
Для этого добавьте зависимость web-sys в ваш файл Cargo.toml
:
[dependencies.web-sys] version = "0.3.4" features = [ 'Document', 'Element', 'HtmlElement', 'Node', 'Window', ]
Теперь нам нужно добавить функцию, которая использует web-sys
для вызова окна браузера, чтобы затем получить доступ к DOM и добавить, например, заголовок в тело.
Наш lib.rs
с новой функцией будет выглядеть так:
Если вы сейчас пересоберете крейт (wasm-pack build --target web
), вы сможете импортировать функцию add_heading
из файла index.html
:
Отправьте HTML еще раз, и вы увидите заголовок.
Эта статья станет началом серии, учитывая количество тем, связанных с WASM, особенно когда речь идет об оптимизации приложений, взаимодействующих с WebAssembly, чтобы они лучше соответствовали линейной модели памяти wasm.
Я надеюсь, что этот пост помог вам начать работу с Rust и WASM, или, по крайней мере, вам стало интересно попробовать эту технологию. В конечном счете, я думаю, обещаний, которые дает WebAssembly, было достаточно, чтобы привлечь мое внимание и, вероятно, привлечет и ваше. Говоря о wasm, он также позволил писать рабочие процессы Cloudflare на Rust, обеспечивая один из самых быстрых бессерверных приложений.
Оставайтесь с нами, так как я планирую написать об этом учитывая мой интерес к работникам Cloudflare.
Спасибо за чтение!