Начните работу с WebAssembly — используя всего 14 строк JavaScript

1656654017 nachnite rabotu s webassembly — ispolzuya vsego 14 strok javascript

Дэниел Симмонс

1*sHlMI2kxKBlm76U2Gmt2Cw

WebAssembly – это совершенно новая веб-технология с огромным потенциалом. Это повлияет на разработку веб-приложений в будущем.

Но иногда я чувствую, что это просто не хочет быть понятным… почти каким-то странным пассивно-агрессивным способом.

Когда я смотрю на документацию и кучу уже имеющихся учебных пособий, я не могу не чувствовать себя фермером, который молился о дожде и утонул в наводнении. Технически я получил то, что хотел… только не так, как я надеялся. «Хочешь дождя? О, я тебе дам дождь

Это потому, что WebAssembly делает возможным так много новых вещей и может быть реализовано многими разными способами. Но он настолько изменился на пути к своему официальному релизу MVP в феврале, что когда вы впервые начинаете о нем узнавать, легко утонуть в море деталей.

Продолжая метафору дождя, эта статья является моей попыткой представить легкий дождь поступления в WebAssembly. Не концепции или гайки и болты, а фактическое внедрение.

Я проведу вас через шаги, чтобы создать и реализовать очень простой проект, устраняя сложность, где это возможно. После того, как вы реализуете это один раз, хотя и просто, многие из этих идей высшего уровня гораздо легче понять.

Давайте разберем это

Все станет гораздо понятнее, если мы отступим назад и посмотрим на список шагов, связанных с внедрением WebAssembly в проект.

Когда вы только начинаете работу, легко взглянуть на WebAssembly и увидеть огромный ряд параметров и процессов. Разбивка на отдельные шаги поможет нам получить четкое представление о происходящем:

  1. написать: Напишите что-нибудь (или используйте существующий проект) на C, C++ или Rust
  2. Скомпилировать: Скомпилируйте его в WebAssembly (что даст вам двоичный файл .wasm)
  3. Включать: Введите файл .wasm в проект
  4. Экземпляр: Напишите группу асинхронных JavaScript, которые скомпилируют двоичный файл .wasm и создадут его во что-нибудь такое, с чем JS может хорошо работать.

И почти все. Конечно, существуют разные перестановки этого процесса, но это суть.

В общем, это не так уж сложно. Однако это может становятся чрезвычайно сложными, поскольку большинство из этих шагов допускают разные степени сложности. Во всяком случае, я буду ошибаться на стороне простоты.

Для нашего проекта мы напишем простую функцию на C++ (не беспокойтесь, если вы не знакомы с C++, это будет чрезвычайно простой). Функция вернет квадрат заданного числа.

Затем мы скомпилируем его в .wasm с помощью онлайн-инструмента (вам не нужно будет загружать или использовать никакие утилиты командной строки). Далее мы создадим его с помощью 14 строчек JS.

Когда мы закончим, вы сможете вызвать функцию, написанную на C++, как если бы это была функция JS и вы будете поражены!

Огромное количество открывающих это возможностей просто поражает.

Напишите

Начнём с кода C++. Помните, что мы не будем использовать локальную среду разработчика для написания или компиляции этого.

Вместо этого мы будем использовать онлайн-инструмент под названием WebAssembly Explorer. Это что-то типа CodePen для WebAssembly, и оно позволяет скомпилировать ваш код C или C++ прямо в браузере и загрузить файл .wasm в одном месте.

Открыв WebAssembly Explorer, введите этот код C++ в крайнем левом окне:

int squarer(int num) {  return num * num;}

Как я уже сказал, здесь мы используем очень простой пример. Даже если вы никогда раньше не смотрели на C или C++, возможно, не так уж трудно понять, что происходит.

Скомпилировать

Затем нажмите кнопку «компилировать» на красной панели над кодом C++. Вот что вы увидите:

1*KAAS0TC2K5c2xkBiaWNNjg

Средний столбец показывает удобную для чтения версию двоичного файла .wasm, который вы только что создали. Это называется WAT или текстовый формат WebAssembly.

Справа – результирующий код сборки. Очень здорово.

Я не буду вдаваться в подробности ни одного из них, но вам нужно знать хотя бы немного о файле WAT, чтобы выполнять следующие шаги.

WAT существует потому, что нам, людям, обычно сложно понять прямой двоичный код. По сути это уровень абстракции, который помогает вам понять код WebAssembly и взаимодействовать с ним.

В нашем случае мы хотим понять, как наша WebAssembly относится к функции, которую мы только что создали. Это потому, что нам понадобится использовать то же имя в нашем файле JS позже, чтобы ссылаться на него.

Любые функции, которые вы пишете в своем коде C++, будут доступны в WebAssembly как нечто, называемое «экспорт». Мы поговорим об этом чуть позже, но все, что вам нужно знать, это то, что экспорт — это то, с чем вы сможете взаимодействовать и использовать.

Посмотрите на файл WAT и найдите слово export. Вы увидите это дважды: один раз рядом со словом memory и снова рядом со словом _Z7squareri. Нам не нужно знать о memory пока, но мы точно заинтересованы _Z7squareri.

Мы использовали название функции squarer в нашем C++, но теперь это как-то стало _z7squareri. Это точно может сбить с толку в первый раз, когда вы это увидите.

Насколько я могу судить, префикс «_Z7» и суффикс «i» являются маркерами отладки, введенными компилятором C++. Однако это не слишком важно глубоко понимать. Вам просто нужно знать, что это произойдет, потому что вам нужно использовать именно это имя в файле JS, чтобы вызвать свою функцию C++.

Включать

Теперь просто нажмите кнопку «скачать» в верхней части фиолетового раздела WAT. Вы получите бинарный файл .wasm. Переименуйте его squarer.wasm. Затем создайте новый каталог и поместите свой squarer.wasm файл там вместе с двумя другими файлами:

  • index.html (шаблонный)
  • scripts.js (пока пуст)

Создание экземпляра

Теперь о сложной части. Или, по крайней мере, часть, которая вызвала у меня много путаницы, когда я впервые начал просматривать документацию.

Хотя впоследствии вы сможете включить модули .wasm, как обычный старый модуль ES6 (с помощью <script type="module»> ), на данный момент вам нужно настроить его «вручную». Это делается с помощью нескольких асинхронных вызовов API WebAssembly. Существует три шага:

  • Переместите свой бинарный файл .wasm в файл буфер массива*
  • Скомпилируйте байты в a WebAssembly модуль*
  • Создать экземпляр* модуль WebAssembly

Если все это имеет смысл для вас, вы можете перейти к следующей главе. Но если вы немного почесали затылок и хотите получить более подробное объяснение, продолжайте читать.

*Буфер массива

Буфер – это место временного хранения данных при их перемещении. Как правило, это полезно, когда данные принимаются и обрабатываются с разной скоростью.

Например, когда видео буферизуется, данные поступают со скоростью ниже видеопроигрывателя может их воспроизвести. Одна из вещей, которые производит наш буфер массива, это постановка в очередь наших двоичных данных, чтобы их было легче скомпилировать.

Но здесь происходит еще что-то очень важное. В JavaScript буфер массива – это типизированный массив, который используется специально для хранения двоичных данных.

Тот факт, что он явно типизирован, означает, что механизм JS может интерпретировать буфер массива гораздо быстрее, чем обычный массив, поскольку он уже знает тип данных, и ему не нужно проходить процесс его определения.

*Модуль WebAssembly

После того, как вы поместили все двоичные данные в буфер массива, вы можете скомпилировать их в модуль. Модуль WebAssembly сам по себе инертен. Это просто скомпилированный двоичный файл, который ждет, пока с ним что-то будет сделано.

Вы можете думать о модуле почти как о рецепте торта. Рецепт – это просто формат для хранения информации о том, как приготовить торт. Если вы действительно хотите торт, вам нужно создать экземпляр торта, описанного в рецепте (instantiate the cake).

Делайте это, следуя инструкциям, изложенным в рецепте. Кроме того, вы можете отправить рецепт кому-то другому («сервисному работнику») или вы можете сохранить его и использовать позже («кэшировать» его). И то и другое гораздо удобнее делать по рецепту, чем с помощью настоящего торта.

*Создание экземпляра

Последнее, что вам нужно сделать, это создать экземпляр вашего модуля WebAssembly, который оживит и сделает его фактически пригодным для использования.

Экземпляр предоставляет вам доступ к экспорту модуля (помните это из нашего файла WAT?). Это объект, содержащий:

  • Память (не имеет отношения к нам, но вы можете прочесть об этом здесь)
  • Любые функции, присутствовавшие в вашем коде C++. Вот как вы будете использовать функцию C++, которую вы написали.

Завершите и запустите!

Вот код, который выполняет все шаги, которые мы только что рассмотрели (это входит в ваш scripts.js файл):

The loadWebAssembly() функция получает ваш файл .wasm, а затем выполняет описанные выше действия. Затем он возвращает новый экземпляр вашего модуля WebAssembly.

Наша функция C++ (помните, что она называется удивительным названием, которое мы упоминали ранее: _z7squareri ) находится в собственности экспорта нашего экземпляра. Вы можете видеть, что его присваивают глобальной переменной squarer в строке 12. Теперь мы можем использовать squarer() как обычную функцию JavaScript!

Как только вы поместите это в свой scripts.js файл и нажмите «Сохранить», вы можете скачать его на локальном хосте и вы увидите сообщение «Компиляция завершена…» на консоли.

Теперь вызовите свою функцию и передайте аргумент из консоли. Попробуйте нечто подобное squarer(9) . Жмите возвращение, и вы увидите 81 . Это работает! Вы вызываете функцию, написанную на языке C++!

1*nMZGPLafGLLuEombmJ4LPg

Это фантастически

Вы можете представить себе все, что это делает возможным.

Во-первых, JavaScript больше не является единственным вариантом для «делания вещей» в браузере. Это совершенно огромно.

Кроме того, есть улучшение производительности, поскольку WebAssembly, в отличие от JS, работает почти с родной скоростью.

И тогда есть весь устаревший код, который теперь находится в вашем распоряжении. C и C++ существуют уже давно, и за это время многие гениальные люди создали на них удивительные проекты с открытым кодом. Проекты, которые можно теперь интегрировать в веб-сайты или программы.

Отсюда можно написать более сложный код на C, C++ или Rust или даже адаптировать существующий проект и «wasm-it» в веб-проект.

Однако одна оговорка заключается в том, что если вы хотите создать функции, принимающие аргументы или возвращающие значения, не являющиеся числами, тогда все начинает становиться несколько сложнее. Именно тогда вам нужно будет узнать немного больше об атрибуте памяти экспорта экземпляра .wasm.

Этот проект доступен на GitHub, если вы хотите просто клонировать рабочую копию в дополнение к продолжению статьи.

Добавить комментарий

Ваш адрес email не будет опубликован.