Ваши первые шаги в будущем разработки, повышение производительности, сильные типы и многое другое в 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 включена.

Теперь мы хотим сделать две вещи:

  1. скомпилировать код rust в wasm
  2. импортируйте 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.

Спасибо за чтение!