Современные реалии таковы, что не каждый бизнес может себе позволить сайт, особенно стартующий бизнес. Поэтому выгодно воспользоваться конструктором сайтов, например filandor.com . Запуск сайта через несколько минут.
На платформе разработчиков Cloudflare мы понимаем, что создание любого приложения — это уникальный опыт для каждого разработчика. Мы знаем, что в экосистеме разработчиков есть множество инструментов на выбор, и как у разработчика у вас есть предпочтения и потребности. Мы не считаем, что есть «правильные» или «неправильные» инструменты для использования в разработке, и хотим обеспечить хороший опыт разработчика независимо от вашего выбора. Мы верим в встречу с вами там, где вы находитесь.
Когда в ноябре прошлого года функция Pages была переведена в общедоступный режим, мы знали, что это ключ, открывающий множество вариантов использования, а именно приложения с полным стеком! Тем не менее, мы по-прежнему чувствовали, что можем сделать больше, чтобы предоставить вам гибкость для создания того, что вы хотите и как вы хотите.
Вот почему сегодня мы открываем двери разработчикам, которые хотят создавать свои серверные приложения с помощью чего-то другого, кроме JavaScript. Мы рады объявить о поддержке WebAssembly для проектов Pages Functions!
Веб-сборка (или Васм) — это низкоуровневый язык, похожий на ассемблер, который может работать почти с родной производительностью. Он предоставляет такие языки программирования, как C/C++, C# или Rust, с целью компиляции, что позволяет им работать вместе с JavaScript. Первоначально разработанная для работы в Интернете (хотя и не исключительно), WebAssembly открывает захватывающие возможности для запуска приложений на веб-платформе, как на клиенте, так и на сервере, которые до сих пор не могли этого сделать.
Поскольку Pages Functions — это Workers «под капотом», а Workers уже некоторое время поддерживает модуль Wasm, вполне естественно, что Pages предоставляет аналогичный опыт и нашим пользователям. Хотя не все варианты использования подходят для Wasm, их много. Наша цель с добавлением поддержки Wasm — обеспечить эти варианты использования и расширить границы того, что могут создавать функции.
Использование WebAssembly в функциях Pages
WebAssembly в Pages Functions работает очень похоже на то, как это работает сегодня в Workers — мы читаем wasm
файлов в виде модулей WebAssembly, готовых для импорта и использования непосредственно из ваших функций. Короче, вот так:
// functions/api/distance-between.js
import wasmModule from "../../pkg/distance.wasm";
export async function onRequest({ request }) {
const moduleInstance = await WebAssembly.instantiate(wasmModule);
const distance = await moduleInstance.exports.distance_between();
return new Response(distance);
}
Давайте кратко распакуем приведенный выше фрагмент кода, чтобы выделить некоторые важные для понимания вещи.
import wasmModule from "../../pkg/distance.wasm";
Pages не делает никаких предположений относительно того, как двоичный файл .wasm
файлы, которые вы хотите импортировать, были скомпилированы. В нашем примере выше, distance.wasm
может быть файлом, который вы скомпилировали самостоятельно из написанного вами кода, или файлом, предоставленным в дистрибутиве сторонней библиотеки. Единственное, что волнует Pages, это то, что distance.wasm
представляет собой скомпилированный двоичный файл модуля Wasm.
Результатом этого импорта является WebAssembly.Module
объект, который вы затем можете создать:
const moduleInstance = await WebAssembly.instantiate(wasmModule);
Однажды WebAssembly.Instance
объект создан, вы можете начать использовать любые функции вашего модуля Wasm exports
внутри вашего кода функций:
const distance = await moduleInstance.exports.distance_between();
Больше модулей, больше удовольствия!
Помимо модулей Wasm, эта работа открывает поддержку двух других типов модулей, которые вы можете импортировать в свой код функций: текст и бинарный. Это не стандартизированные модули, но они могут быть очень удобны, если вам нужно импортировать необработанные текстовые BLOB-объекты (например, HTML-файлы) в качестве string
:
// functions/my-function.js
import html from "404.html";
export async function onRequest() {
return new Response(html,{
headers: { "Content-Type": "text/html" }
});
}
или большие двоичные объекты необработанных данных (например, изображения) в качестве ArrayBuffer
.
// functions/my-function.js
import image from "../hearts.png.bin";
export async function onRequest() {
return new Response(image,{
headers: { "Content-Type": "image/png" }
});
}
Расстояние между нами на поверхности Земли
Давайте посмотрим на живой пример, чтобы увидеть все это в действии! Мы создали небольшое демонстрационное приложение, которое проведет вас через пример функций с WebAssembly от начала до конца. Вы можете ознакомиться с кодом нашего демо-приложения, доступным на GitHub.
Приложение вычисляет расстояние в километрах на поверхности Земли между вашим текущим местоположением (на основе геокоординат входящего запроса) и любой другой точкой земного шара каждый раз, когда вы нажимаете на поверхность земного шара.

Код, выполняющий фактическое высокопроизводительное вычисление расстояния, написан на Rust и представляет собой небольшую адаптацию примера, приведенного в кулинарной книге Rust:
fn distance_between(from_latitude_degrees: f64, from_longitude_degrees: f64, to_latitude_degrees: f64, to_longitude_degrees: f64) -> f64 {
let earth_radius_kilometer = 6371.0_f64;
let from_latitude = from_latitude_degrees.to_radians();
let to_latitude = to_latitude_degrees.to_radians();
let delta_latitude = (from_latitude_degrees - to_latitude_degrees).to_radians();
let delta_longitude = (from_longitude_degrees - to_longitude_degrees).to_radians();
let central_angle_inner = (delta_latitude / 2.0).sin().powi(2)
+ from_latitude.cos() * to_latitude.cos() * (delta_longitude / 2.0).sin().powi(2);
let central_angle = 2.0 * central_angle_inner.sqrt().asin();
let distance = earth_radius_kilometer * central_angle;
return distance;
}
У нас есть экспериментальная игровая площадка Rust, доступная здесь, если вы хотите поиграть, в частности, с этим фрагментом кода.
Чтобы использовать distance_between()
Rust в Pages Functions, мы сначала компилируем код в WebAssembly, используя wasm-pack
:
##
# generate the `pkg` folder which will contain the wasm binary
##
wasm-pack build
Затем мы импортируем сгенерированный .wasm
Артефакт внутри нашего distance-between.js
Функции страниц. Теперь каждый раз, когда вы нажимаете на поверхность земного шара, запрос на /api/distance-between
производится, что приведет к distance_between()
функция для выполнения. После вычисления значение расстояния возвращается нашей функцией обратно клиенту, который продолжает отображать значение для пользователя.

Мы хотим отметить, что это приложение можно было бы полностью создать на JavaScript, однако мы в равной степени хотели показать, насколько просто его создать на Rust. Решение использовать Rust было мотивировано несколькими факторами. Во-первых, экосистема инструментов для создания WebAssembly, созданного на Rust, и работы с ним достаточно зрелая, хорошо документированная и с ней легко начать работу. Во-вторых, документы Rust — это фантастический ресурс, если вы новичок в Rust или в Rust с WebAssembly! Если вы ищете пошаговое руководство по созданию и настройке проекта Rust и WebAssembly, мы настоятельно рекомендуем ознакомиться с официальной книгой Rust по WebAssembly.
Мы надеемся, что это послужит вам надежной отправной точкой в изучении возможностей Wasm on Pages Functions и вдохновит вас на создание собственных мощных приложений. Перейдите к нашим документам, чтобы начать сегодня!