Подпишитесь, чтобы получать уведомления о новых публикациях:

Невероятно быстрая разработка с помощью фреймворков на стороне клиента и сервера и Cloudflare

2024-04-05

6 мин. чтения
Другие языки, на которых доступна эта публикация: English, 繁體中文, 日本語, 한국어, Português, Español и 简体中文.
Blazing fast development with full-stack frameworks and Cloudflare

Здравствуйте, веб-разработчики! В прошлом году мы выпустили ряд улучшений, которые значительно упростили развертывание веб-приложений на Cloudflare, и в результате этого мы наблюдаем значительный рост Astro, Next.js, Nuxt, Qwik, Remix, SolidStart, SvelteKit и других веб- приложений, размещенных на Cloudflare. Сегодня мы объявляем о значительных улучшениях в нашей интеграции с этими веб-фреймворками, которые упрощают разработку сложных приложений, использующих нашу базу данных SQL D1, хранилище объектов R2, модели искусственного интеллекта и другие мощные функции платформы для разработчиков Cloudflare.

В прошлом, если вы хотели разработать приложение на основе веб-фреймворка с помощью D1 и запускать его локально, вам приходилось создавать рабочую сборку вашего приложения, а затем запускать его локально с помощью `wrangler Pages dev`. Хотя это работало, каждая итерация вашего кода занимала секунды или десятки секунд для больших приложений. Итерация с использованием производственных сборок просто слишком медленная, нарушает ваш поток и не позволяет воспользоваться всеми преимуществами DX-оптимизаций, в которые авторы фреймворка вложили много кропотливого труда. Сегодня ситуация меняется!

Наша цель — обеспечить наиболее естественную интеграцию с веб-фреймворками, при этом разработчикам не нужно обучаться и внедрять значительные изменения в рабочие процессы или пользовательские API при развертывании своего приложение в Cloudflare. Независимо от того, являетесь ли вы разработчиком Next.js, Nuxt или предпочитаете другой фреймворк, теперь вы можете продолжать использовать знакомый вам невероятно быстрый рабочий процесс локальной разработки и отправлять свое приложение на Cloudflare.

Все веб-фреймворки на стороне клиента и сервера поставляются с локальным сервером разработки (dev-сервером), который специально настраивается для фреймворка и часто обеспечивает превосходные возможности разработки, за одним лишь исключением: они нативно не поддерживают некоторые важные функции платформы разработки Cloudflare, особенно наши решения для хранения.

Поэтому до недавнего времени вам приходилось делать трудный выбор. Вы можете использовать dev-сервер конкретного фреймворка для разработки своего приложения, но при этом отказаться от доступа ко многим функциям Cloudflare. В качестве альтернативы вы можете воспользоваться всеми преимуществами платформы Cloudflare, включая различные ресурсы, такие как D1 или R2, но вам придется отказаться от использования инструментов разработчика для конкретной платформы. В этом случае ваш цикл итерации замедлится, и вам потребуются секунды, а не миллисекунды, чтобы увидеть результаты изменений вашего кода в браузере. Но теперь это не так! Давайте посмотрим.

Будем создавать приложение

Давайте создадим новое приложение, используя C3 — наш create-cloudflare CLI. Мы могли бы использовать любой клиент npm по нашему выбору (pnpm anyone?!?), но для простоты в этой публикации мы будем придерживаться клиента npm по умолчанию. Чтобы начать, просто запустите:

$ npm create cloudflare@latest

Введите имя для своего приложение или используйте случайно сгенерированное. Затем выберите категорию “Website or web app” (Веб-сайт или веб приложение) и выберите фреймворк на стороне клиента и сервера по вашему выбору. Мы поддерживаем многие из них: Astro, Next.js, Nuxt, Qwik, Remix, SolidStart и SvelteKit.

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

Создав шаблон для нашего приложения, давайте реализуем отображение в нем списка продуктов, хранящихся в базе данных, всего за несколько шагов. Сначала мы добавим конфигурацию нашей базы данных в наш файл конфигурации wrangler.toml:

[[d1_databases]]
binding = "DB"
database_name = "blog-products-db"
database_id = "XXXXXXXXXXXXXXXX"

Да, все верно! Теперь вы можете настраивать связанные ресурсы с помощью файла wrangler.toml даже для приложений на стороне клиента и сервера, развернутых на Pages. Более подробно об улучшениях конфигурации Pages мы расскажем в отдельном объявлении.

Теперь давайте создадим простой файл schema.sql, представляющий схему нашей базы данных:

CREATE TABLE products(product_id INTEGER PRIMARY KEY, name TEXT, price INTEGER);
INSERT INTO products (product_id, name, price) VALUES (1, 'Apple', 250), (2, 'Banana', 100), (3, 'Cherry', 375);

И инициализируем нашу базу данных:

$ npx wrangler d1 execute blog-products-db --local --file schema.sql

Обратите внимание, что мы использовали флаг -local выполнения wrangler d1, чтобы применить изменения к нашей локальной базе данных D1. Это база данных, к которой будет подключаться наш dev-сервер.

Затем, если вы используете TypeScript, сообщите TypeScript о вашей базе данных, выполнив команду:

$ npm run build-cf-types

Эта команда предварительно настроена для всех приложений на стороне клиента и сервера, созданных через C3, и выполняет типы wrangler для обновления интерфейса среды Cloudflare, содержащего все настроенные привязки.

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

$ npm run dev

Этот ярлык запустит сервер разработки вашего фреймворка, независимо от того, работает ли он на next dev, nitro или vite.

Теперь, чтобы получить доступ к нашей базе данных и перечислить продукты, мы уже можем использовать подход, специфичный для фреймворка. Например, в приложении Next.js, использующем маршрутизатор приложений, мы можем обновить app/api/hello/route.ts следующим образом:

const db = getRequestContext().env.DB;
 const productsResults = await db.prepare('SELECT * FROM products').all();
 return Response.json(productsResults.results);

Или в приложении Nuxt мы можем создать файл server/api/hello.ts и заполнить его следующим:

export default defineEventHandler(async ({ context }) => {
   const db = context.cloudflare.env.DB;
   const productsResults = await db.prepare('SELECT * FROM products').all();
   return productsResults.results;
 });

Предполагая, что сервер разработки фреймворка работает на порту 3000, вы можете протестировать новый маршрут API в любом фреймворке, перейдя по адресу http://localhost:3000/api/hello. Для простоты в этих примерах мы выбрали маршруты API, но то же самое относится и к любым маршрутам, генерирующим пользовательский интерфейс.

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

Теперь, когда вы знаете, как получить доступ к ресурсам Cloudflare в выбранном вами фреймворке, все остальное, что вы знаете о своем фреймворке, остается прежним. Теперь вы можете разрабатывать свое приложение локально, используя сервер разработки, оптимизированный для вашей платформы, который часто включает поддержку горячей замены модулей (HMR [hot module replacemet]), пользовательские инструменты разработки, расширенную поддержка отладки и многое другое, при этом по-прежнему используя преимущества API и функций, специфичных для Cloudflare. Беспроигрышный вариант!

Что на самом деле изменилось, чтобы позволить включить эти рабочие процессы разработки?

Чтобы уменьшить задержку разработки и сохранить пользовательский опыт, специфичный для фреймворка, нам нужно было обеспечить веб-фреймворкам и их dev-серверам возможность интегрироваться с wrangler и miniflare бесшовным, почти незаметным образом.

Miniflare является ключевым компонентом в этой головоломке. Это наш локальный симулятор для ресурсов, специфичных для Cloudflare, который работает на базе workerd, нашей среды выполнения JavaScript (JS). Опираясь на worker, мы гарантируем, что API JavaScript Cloudflare работают локально таким образом, который точно имитирует нашу рабочую среду. Проблема заключается в том, что dev-серверы фреймворка уже используют Node.js для запуска приложения, поэтому добавление еще одной среды выполнения JS ломает многие предположения о том, как были спроектированы эти dev-серверы.

Однако наша команда предложила интересный подход к преодолению разрыва между этими двумя средами выполнения JS. Мы называем это API getPlatformProxy(), который теперь является частью wrangler и сверхэффективно работает на основе magic proxy miniflare. Этот API предоставляет объект proxy JS, который ведет себя так же, как обычный объект env Workers, содержащий все связанные ресурсы. Объект proxy позволяет коду из Node.js прозрачно вызывать код JavaScript, работающий в workerd, а также получать доступ к API среды выполнения Cloudflare.

Благодаря такому мосту между средами выполнения Node.js и workerd ваше приложение теперь может получать доступ к симуляторам Cloudflare для D1, R2, KV и других решений хранения напрямую, работая на dev-сервере на базе Node.js. Или вы даже можете написать скрипт Node.js, чтобы сделать то же самое:

 import {getPlatformProxy} from 'wrangler';


 const {env} = getPlatformProxy();
 console.dir(env);
 const db = env.DB;


 // Now let’s execute a DB query that runs in a local D1 db
 // powered by miniflare/workerd and access the result from Node.js
 const productsResults = await db.prepare('SELECT * FROM products').all();
 console.log(productsResults.results);

Поскольку доступен API getPlatformProxy(), оставшаяся работа сводилась к обновлению всех адаптеров фреймворка, плагинов, а в некоторых случаях и самих фреймворков, чтобы они могли использовать этот API. Мы благодарны за поддержку, которую мы получили от команд разработки фреймворков на этом пути, особенно Алексу из Astro, pi0 из Nuxt, Педро из Remix, Райану из Solid, Бену и Ричу из Svelte, а также нашему участнику проекта next-on-pages , Джеймсу Андерсону.

Будущие улучшения рабочих процессов разработки с помощью Vite

Хотя API getPlatformProxy() является хорошим решением для многих сценариев, мы можем добиться большего. Если бы мы могли запускать все приложение в нашей среде выполнения JS, а не в Node.js, мы могли бы еще более точно имитировать производственную среду и уменьшить трения разработчиков и производственные неожиданности.

В идеальном мире мы хотели бы, чтобы вы разрабатывали в той же среде выполнения, которую вы развертываете в рабочей среде, и это может быть достигнуто только путем интеграции workerd непосредственно в dev-серверы всех фреймворков, что немаловажно, учитывая количество фреймворков и различий между ними.

Однако нам немного повезло. Когда мы приступили к этой работе, мы быстро поняли, что Vite, популярный dev-сервер, используемый многими фреймворками на стороне клиента и сервера, получает все более широкое распространение. Фактически, Remix совсем недавно перешел на Vite и подтвердил популярность Vite как общей основы для сегодняшней веб-разработки.

Если бы Vite обеспечивал первоклассную поддержка запуска приложения на стороне клиента и сервера в альтернативной среде выполнения JavaScript, мы могли бы позволить любому, кто использует Vite, разрабатывать свои приложения локально с полным доступом к платформе разработчиков Cloudflare. Больше никаких пользовательских интеграций и обходных путей для конкретных фреймворков — все функции фреймворка на стороне клиента и сервера, Vite и Cloudflare доступны для всех разработчиков.

Звучит слишком хорошо, чтобы быть правдой? Возможно. Мы очень рады работать с командой Vite над предложением по средам Vite, которое может обеспечить именно такую функциональность. Это предложение все еще находится в разработке, поэтому следите за обновлениями.

Что вы будете разрабатывать сегодня?

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

$ npm create cloudflare@latest

Мы защищаем целые корпоративные сети, помогаем клиентам эффективно создавать интернет-приложения в глобальном масштабе, ускорять любые веб-сайты или интернет-приложения, отражать DDoS-атаки, не допускать действий хакеров, и можем оказать поддержку на вашем пути к Zero Trust.

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

Чтобы узнать больше о нашей миссии, которая состоит в том, чтобы способствовать развитию и совершенствованию Интернета, начните здесь. Если вы ищете новое направление для развития своей карьеры, ознакомьтесь с нашими открытыми позициями.
Developer WeekРазработчикиDeveloper PlatformFull StackWranglerMiniflare

Подписаться на X

Igor Minar|@IgorMinar
Peter Bacon Darwin|@petebd
Cloudflare|@cloudflare

Связанные публикации

31 октября 2024 г. в 13:00

Moving Baselime from AWS to Cloudflare: simpler architecture, improved performance, over 80% lower cloud costs

Post-acquisition, we migrated Baselime from AWS to the Cloudflare Developer Platform and in the process, we improved query times, simplified data ingestion, and now handle far more events, all while cutting costs. Here’s how we built a modern, high-performing observability platform on Cloudflare’s network. ...

25 октября 2024 г. в 13:00

Elephants in tunnels: how Hyperdrive connects to databases inside your VPC networks

Hyperdrive (Cloudflare’s globally distributed SQL connection pooler and cache) recently added support for directing database traffic from Workers across Cloudflare Tunnels. We dive deep on what it took to add this feature....