Vue + WebAssembly

Недавно я экспериментировал с использованием веб-сборки в моем проекте Vue и мне нравилось программировать на Rust, но я обнаружил, что, хотя инструменты для компиляции модуля WebAssembly приятны и просты, использование его в вашем веб-приложении требует немного возни.

В следующей статье мы надеемся обрисовать, как я интегрировал свои функции веб-сборки в каждый компонент моего проекта Webpack, созданного с помощью Vue-cli.

Интеграция с Webpack

Моя основная проблема с текущей реализацией Web Assembly - это довольно громоздкий способ загрузки вашего модуля Web Assembly в ваше приложение.

fetch('simple.wasm').then(response =>
  response.arrayBuffer()
).then(bytes =>
  WebAssembly.instantiate(bytes, importObject)
).then(results => {
  results.instance.exports.exported_func();
});

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

// build/webpack.base.conf.js
module: {
  rules: [
    ...
    {
      test: /\.wasm$/,
      loaders: ['wasm-loader']
    }
  ]
}

После настройки загрузчика вы можете импортировать файл .wasm , как и любой другой модуль JS. Экспорт по умолчанию из загрузчика - это функция, возвращающая собственный Promise, обещание разрешается в WebAssembly.Instance.

import artihmeticModule from './assets/wasm/artihmetic.wasm';
const arithmetic = artihmeticModule().then(({ instance }) => {
  return instance.exports
});

Использование WA с Vue

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

import artihmeticModule from './assets/wasm/artihmetic.wasm';
import fibinachiModule from './assets/wasm/fibinachi.wasm';
const extractModule = async (module) => {
  const { instance } = await module();
  return instance.exports;
};
const arithmetic = extractModule(artihmeticModule);
const fibinachi = extractModule(fibinachiModule);

Чтобы сделать функции веб-сборки доступными во всех ваших компонентах Vue, вы можете добавить что-то подобное в прототип Vue.

Vue.prototype.$wasm = {
  arithmetic: extractModule(artihmeticModule), 
  fibinachi: extractModule(fibinachiModule),
};

Теперь вы можете вызывать любую импортированную функцию веб-сборки в вашем компоненте Vue, используя следующий синтаксис…

this.$wasm.arithmetic.add(1, 2) // 3

Плагин

Я создал плагин для Vue, чтобы обернуть описанный выше процесс, что делает регистрацию модулей WebAssembly такой же простой, как…

// main.js
import Vue from 'vue'
import VueWasm from 'vue-wasm';
import arithmeticModule from './assets/wasm/arithmetic.wasm';

VueWasm(Vue, { modules: { arithmetic: arithmeticModule } });

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

this.$wasm.arithmetic.add(1, 2) // 3

Резюме

Я вижу огромный потенциал веб-сборки, и я также вижу (не такое уж далекое) будущее, в котором веб-разработчики не обязательно будут создавать свои собственные модули на основе Rust, но будут использовать сторонние служебные библиотеки веб-сборки, аналогичные тому, как мы используем на основе JS. библиотеки сегодня, как Lodash.

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