Передача Wasm-модуля в веб-проект
Мы прошли путь от договора статистики до Rust-функции, браузерной обвязки, Worker и запасной реализации. Теперь рассмотрим передачу «Меры» в другой веб-проект. Для этого нужны согласованные файлы, версия API, ограничения входа и ясное описание того, что действительно проверено.
Серия пока существует локально как черновик. Учебная программа не компилировалась, зависимости не устанавливались, браузерные сценарии и измерения не выполнялись. Архив содержит исходники, которые можно изучать и готовить к отдельной технической приёмке. Нельзя называть его проверенным производственным пакетом только потому, что оглавление уже доступно на локальном сайте.
Версия внешнего договора
Добавим маленький экспорт в src/lib.rs. Он помогает адаптеру отличить поддерживаемый формат результата от случайно подставленного бинарника:
#[wasm_bindgen]
pub fn contract_version() -> u32 {
1
}
В загрузчике после инициализации сравним module.contract_version() с единицей. Если версия отличается, остановим подготовку движка с понятной причиной. Смысл полей и границы гистограммы являются частью договора, даже если число элементов массива осталось прежним.
Версия исходного пакета Cargo и версия внешнего API не обязаны совпадать. Исправление внутреннего алгоритма без изменения результата может повысить версию пакета, сохранив договор 1. Изменение определения строки или порядка чисел требует обсуждения совместимости. Такое разделение облегчает сопровождение приложения.
JavaScript-движок тоже должен следовать договору 1. Его наличие не делает несовместимый Wasm безопасным автоматически: в обычном режиме можно выбрать fallback при отказе подготовки, но причина должна остаться доступной. Для технической проверки нужен принудительный выбор, чтобы запасной путь не скрыл проблему.
Исходный архив и готовый артефакт
Исходный набор включает Rust, Cargo-конфигурацию, браузерные модули и README. После разрешённой сборки дополнительно появится каталог web/pkg со связанной обвязкой и бинарником. Каталог target не требуется посетителю. Установленный CLI тоже не загружается в браузер.
| Часть | Для разработчика | Для браузерного выпуска |
|---|---|---|
src/lib.rs |
Исходник вычисления | Нет |
| Cargo-файлы | Воспроизводимость сборки | Нет |
web/pkg/*.js и *.wasm |
Сгенерированная граница | Да |
web/worker.mjs |
Протокол потока | Да |
web/fallback.mjs |
Запасной алгоритм | Да |
| Измерительные записи | Техническая приёмка | Обычно нет |
В готовом артефакте все пути должны соответствовать расположению приложения. Перенос главной HTML-страницы в подкаталог может изменить относительные ссылки. Использование new URL(..., import.meta.url) привязывает Worker к модулю, но не исправляет произвольно переименованный пакет Wasm.
Не смешивайте JavaScript из одного выпуска с бинарником из другого. Кэширование ресурсов нужно согласовать с их версиями: изменённый файл под старым долго кэшируемым именем может не обновиться у посетителя. Один из вариантов — имена с хешем и коротко кэшируемая входная страница; конкретную реализацию выбирают средствами сборки сайта.
Выдача ресурсов и ограничения среды
На хостинге Wasm должен выдавать ожидаемый тип application/wasm, а JavaScript — корректный тип модуля. Публичная HTML-страница и файл бинарника имеют разные требования выдачи. Ответ 200 со страницей ошибки вместо бинарника не является успешной загрузкой модуля.
Если сайт использует Content Security Policy, загрузка модулей, Worker и компиляция Wasm должны соответствовать его правилам. Не отключайте всю политику ради одной ошибки. Нужно разобрать реальную причину и разрешить только необходимые возможности. Наш проект не задаёт универсальные производственные заголовки и не утверждает, что они проверены на Beget.
У обычного Worker отдельная память, но он находится в браузерном приложении того же пользователя. Мы не применяем shared memory и не обещаем параллельную обработку одного файла несколькими Rust-потоками. Если появятся такие требования, понадобится новый договор среды и измерений.
Ограничения входа являются частью продукта
Лимит восемь MiB отображается в подписи формы, проверяется до чтения файла и повторно внутри движка. UTF-8 декодируется строго, BOM сохраняется, строки разделяются по LF. Эти условия нужно перенести вместе с модулем, а не оставить в старом учебном интерфейсе.
Приложение не обрабатывает произвольный CSV с кавычками и многострочными полями. Оно считает технические строки текста. Если пользователь загрузил CSV, статистика строк не равна числу табличных записей при любом формате. Для настоящего CSV-парсера потребуется отдельная грамматика, примеры и обработка ошибок.
Статистика не заменяет проверку смысла файла. Количество непустых строк не доказывает качество статьи или отсутствие вредной разметки. Модуль получает текст как данные и не исполняет его. Такая граница позволяет использовать анализатор рядом с редакционным интерфейсом, не смешивая его с рендерером Markdown.
Передача следующему разработчику
README должен сообщать точные версии, команды будущей сборки и известное отсутствие выполненной проверки. Разработчик получает контрольные входы с ожидаемыми значениями, список режимов движка и условия отмены Worker. После технического запуска эти сведения можно дополнить фактическим отчётом, сохранив исходную версию кода.
Уничтожение Worker отменяет текущую вычислительную операцию, но не обязано отменить уже начатое чтение файла в основном потоке. Поэтому клиент проверяет актуальность намерения после каждого ожидания. При уходе со страницы полезно завершить поток и отклонить ожидающие Promise, чтобы не оставлять скрытые ресурсы.
Перед настоящим выпуском отдельно подтвердите результат на характерных текстах, получение ресурсов по HTTP, выбор fallback и поведение отмены. Это задачи будущей приёмки, а не действия, выполненные в ходе написания. Внешний сайт ProfessorWeb и его старые URL не изменялись учебным примером.
Расширение после передачи
Новая функция не обязана менять весь пакет. Можно сохранить договор статистики и добавить отдельный экспорт для другой задачи с собственным входом и ограничениями. Однако общая инициализация, сообщения Worker и размер ресурса продолжат влиять на приложение. Перед расширением полезно проверить, действительно ли функция нужна в том же виджете или должна загружаться отдельно при первом обращении пользователя.
«Мера» показывает осмысленное включение другого языка в веб-приложение: сначала договор, затем граница типов и ресурсов, затем интерфейс и измерение. Такой подход позволяет принять решение о Wasm на основании конкретной задачи, сохранив понятный JavaScript-путь и возможность расширять приложение дальше.