Hello, World!¶
В этом разделе вы узнаете, как создать и запустить свою первую программу на Rust и WebAssembly: веб-страницу, оповещающую "Hello, World!".
Перед началом работы убедитесь, что вы выполнили инструкции setup instructions.
Клонирование шаблона проекта¶
Шаблон проекта поставляется предварительно сконфигурированным с разумными настройками по умолчанию, чтобы вы могли быстро собрать, интегрировать и упаковать свой код для Web.
Клонируйте шаблон проекта с помощью этой команды:
1 |
|
Вам будет предложено ввести название нового проекта. Мы будем использовать "wasm-game-of-life".
1 |
|
Что внутри¶
Заходите в новый проект wasm-game-of-life
1 |
|
и давайте посмотрим на его содержимое:
1 2 3 4 5 6 7 8 |
|
Давайте рассмотрим несколько таких файлов подробнее.
wasm-game-of-life/Cargo.toml
Файл Cargo.toml
определяет зависимости и метаданные для cargo
, менеджера пакетов и инструмента сборки Rust. Этот файл поставляется с предустановленной зависимостью wasm-bindgen
, несколькими дополнительными зависимостями, которые мы рассмотрим позже, и правильно инициализированным crate-type
для генерации библиотек .wasm
.
wasm-game-of-life/src/lib.rs
Файл src/lib.rs
является корнем Rust crate, который мы компилируем в WebAssembly. Он использует wasm-bindgen
для взаимодействия с JavaScript. Он импортирует JavaScript-функцию window.alert
и экспортирует Rust-функцию greet
, которая выдает приветствие.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
wasm-game-of-life/src/utils.rs
Модуль src/utils.rs
предоставляет общие утилиты для облегчения работы с Rust, скомпилированным в WebAssembly. Мы рассмотрим некоторые из этих утилит более подробно позже в учебнике, например, когда будем рассматривать отладку нашего wasm-кода, но пока мы можем игнорировать этот файл.
Сборка проекта¶
Мы используем wasm-pack
для организации следующих шагов сборки:
- Убедитесь, что у нас установлен Rust 1.30 или новее и цель
wasm32-unknown-unknown
черезrustup
, - Скомпилируйте наши исходные тексты Rust в бинарник WebAssembly
.wasm
с помощьюcargo
, - Используйте
wasm-bindgen
для генерации JavaScript API для использования нашей Rust-генерированной WebAssembly.
Чтобы сделать все это, запустите эту команду в каталоге проекта:
1 |
|
После завершения сборки мы можем найти ее артефакты в директории pkg
, и она должна иметь следующее содержимое:
1 2 3 4 5 6 |
|
Файл README.md
скопирован из основного проекта, но все остальные - совершенно новые.
wasm-game-of-life/pkg/wasm_game_of_life_bg.wasm
Файл .wasm
- это двоичный файл WebAssembly, который генерируется компилятором Rust из наших исходных текстов Rust. Он содержит скомпилированные в wasm версии всех наших функций и данных Rust. Например, в нем есть экспортируемая функция "greet".
wasm-game-of-life/pkg/wasm_game_of_life.js
Файл .js
генерируется wasm-bindgen
и содержит JavaScript-клеи для импорта DOM и JavaScript-функций в Rust и раскрытия красивого API для функций WebAssembly в JavaScript. Например, есть функция JavaScript greet
, которая оборачивает функцию greet
, экспортированную из модуля WebAssembly. Сейчас этот клей не делает многого, но когда мы начнем передавать более интересные значения туда и обратно между wasm и JavaScript, он поможет переправить эти значения через границу.
1 2 3 4 5 6 7 |
|
wasm-game-of-life/pkg/wasm_game_of_life.d.ts
Файл .d.ts
содержит объявления типов TypeScript для JavaScript-клея. Если вы используете TypeScript, вы можете проверять типы ваших вызовов функций WebAssembly, а ваша IDE может предоставить автозавершение и предложения! Если вы не используете TypeScript, можете смело игнорировать этот файл.
1 |
|
wasm-game-of-life/pkg/package.json
Файл package.json
содержит метаданные о сгенерированном пакете JavaScript и WebAssembly. Он используется npm и JavaScript bundlers для определения зависимостей между пакетами, имен пакетов, версий и множества других вещей. Он помогает нам интегрироваться с инструментами JavaScript и позволяет опубликовать наш пакет в npm.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Вставка в веб-страницу¶
Чтобы взять наш пакет wasm-game-of-life
и использовать его в веб-странице, мы используем шаблон проекта JavaScript create-wasm-app
.
Выполните эту команду в директории wasm-game-of-life
:
1 |
|
Вот что содержит наш новый подкаталог wasm-game-of-life/www
:
1 2 3 4 5 6 7 8 9 |
|
Давайте еще раз внимательно рассмотрим некоторые из этих файлов.
wasm-game-of-life/www/package.json
Этот package.json
поставляется с предустановленными зависимостями webpack
и webpack-dev-server
, а также зависимостью от hello-wasm-pack
, которая представляет собой версию начального пакета wasm-pack-template
, опубликованного на npm.
wasm-game-of-life/www/webpack.config.js
Этот файл настраивает webpack и его локальный сервер разработки. Он поставляется уже настроенным, и вам не придется вносить в него какие-либо изменения, чтобы заставить webpack и его локальный сервер разработки работать.
wasm-game-of-life/www/index.html
Это корневой HTML-файл для веб-страницы. Он не делает ничего особенного, кроме загрузки bootstrap.js
, который является очень тонкой оберткой вокруг index.js
.
1 2 3 4 5 6 7 8 9 10 |
|
wasm-game-of-life/www/index.js
Сайт index.js
- это основная точка входа для JavaScript нашей веб-страницы. Он импортирует пакет npm hello-wasm-pack
, который содержит скомпилированный WebAssembly и JavaScript-клея по умолчанию wasm-pack-template
, а затем вызывает функцию hello-wasm-pack
greet
.
1 2 3 |
|
Установите зависимости¶
Сначала убедитесь, что локальный сервер разработки и его зависимости установлены, запустив npm install
в подкаталоге wasm-game-of-life/www
:
1 |
|
Эту команду нужно выполнить только один раз, и она установит пакет JavaScript webpack
и его сервер разработки.
Обратите внимание, что
webpack
не является обязательным для работы с Rust и WebAssembly, это просто бандлер и сервер разработки, который мы выбрали для удобства. Parcel и Rollup также должны поддерживать импорт WebAssembly как модулей ECMAScript. Вы также можете использовать Rust и WebAssembly без бандлера, если хотите!
Использование нашего локального пакета wasm-game-of-life
в www
¶
Вместо того чтобы использовать пакет hello-wasm-pack
из npm, мы хотим использовать наш локальный пакет wasm-game-of-life
. Это позволит нам постепенно развивать нашу программу Game of Life.
Откройте wasm-game-of-life/www/package.json
и рядом с "devDependencies"
добавьте поле "dependencies"
, включая "wasm-game-of-life": "file:../pkg"
:
1 2 3 4 5 6 7 8 9 |
|
Затем измените wasm-game-of-life/www/index.js
, чтобы импортировать wasm-game-of-life
вместо пакета hello-wasm-pack
:
1 2 3 |
|
Поскольку мы объявили новую зависимость, нам нужно ее установить:
1 |
|
Наша веб-страница теперь готова к местному обслуживанию!
Обслуживание локально¶
Далее откройте новый терминал для сервера разработки. Запуск сервера в новом терминале позволяет нам оставить его работать в фоновом режиме и не мешает нам выполнять другие команды в это время. В новом терминале выполните эту команду из директории wasm-game-of-life/www
:
1 |
|
Перейдите в веб-браузере по адресу http://localhost:8080/, и вас должно встретить сообщение с предупреждением:
Каждый раз, когда вы вносите изменения и хотите, чтобы они отразились на http://localhost:8080/, просто повторно выполните команду wasm-pack build
в директории wasm-game-of-life
.
Упражнения¶
Измените функцию greet
в wasm-game-of-life/src/lib.rs
, чтобы она принимала параметр name: &str
, который настраивает сообщение с предупреждением, и передайте свое имя в функцию greet
из каталога wasm-game-of-life/www/index.js
. Пересоберите бинарный файл .wasm
с помощью wasm-pack build
, затем обновите http://localhost:8080/ в веб-браузере, и вы увидите настроенное приветствие!
Answer
New version of the greet
function in wasm-game-of-life/src/lib.rs
:
1 2 3 4 |
|
New invocation of greet
in wasm-game-of-life/www/index.js
:
1 |
|
Источник — https://rustwasm.github.io/docs/book/game-of-life/hello-world.html