Зачем в ноде есть WASI и какие возможности он нам дает?nodejs-17

Что такое WASI

WASI (WebAssembly System Interface) - это стандартизированный системный интерфейс для WebAssembly, который позволяет WASM-модулям взаимодействовать с операционной системой безопасным и переносимым способом.

В Node.js WASI появился начиная с версии 13.3.0 как экспериментальная возможность, а с версии 14 стал стабильным.

Зачем WASI нужен в Node.js

1. Безопасное выполнение ненадежного кода

  • Изоляция WASM-модулей от основной системы
  • Контролируемый доступ к системным ресурсам
  • Песочница по умолчанию

2. Кросс-платформенная совместимость

  • Единый интерфейс для разных ОС
  • Переносимость WASM-модулей между сервером и браузером

3. Производительность

  • Близкая к нативной скорость выполнения
  • Предсказуемая производительность

Основные возможности WASI в Node.js

1. Работа с файловой системой

const fs = require('fs');
const { WASI } = require('wasi');

const wasi = new WASI({
  preopens: {
    '/sandbox': '/some/real/path'
  }
});

const instance = new WebAssembly.Instance(wasmModule, {
  wasi_snapshot_preview1: wasi.wasiImport
});

2. Доступ к аргументам командной строки

const wasi = new WASI({
  args: process.argv,
  env: process.env
});

3. Работа со стандартными потоками

  • stdin/stdout/stderr доступны внутри WASM-модуля
  • Можно перенаправлять потоки

4. Системные часы и таймеры

  • Доступ к монотоным и реальным часам
  • Точное время выполнения

Практические применения в Node.js

  1. Плагины с изоляцией - безопасное выполнение пользовательских скриптов
  2. Критичные к производительности участки - вычисления в WASM
  3. Перенос существующих С/C++ библиотек - без переписывания на JS
  4. Универсальные модули - один код для сервера и браузера

Пример использования С библиотеки:

const { WASI } = require('wasi');
const { readFileSync } = require('fs');

const wasm = readFileSync('./optimized-lib.wasm');
const wasi = new WASI({ args: process.argv });

(async () => {
  const { instance } = await WebAssembly.instantiate(wasm, {
    wasi_snapshot_preview1: wasi.wasiImport
  });

  const result = instance.exports.compute(42);
  console.log(result);
})();

Ограничения WASI

  1. Нет доступа к Node.js API (только через мосты)
  2. Ограниченный набор системных вызовов
  3. Требуется явное разрешение ресурсов

Резюмируем

  1. Безопасность - песочница для ненадежного кода
  2. Переносимость - единый интерфейс для всех платформ
  3. Производительность - выполнение на уровне близком к нативному
  4. Интеграция с системой - контролируемый доступ к ОС
  5. Экосистема - возможность использовать существующие С/C++ библиотеки

WASI открывает в Node.js новые возможности для безопасного и эффективного выполнения кода, особенно в сценариях где важны изоляция и производительность.