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
