Nuxt на Edge
Введение
В сентябре 2017 года Cloudflare представила Cloudflare Workers, дав возможность запускать JavaScript на их сети Edge. Это означает, что ваш код будет развернут на всей сети Edge в более чем ста локациях по всему миру примерно за 30 секунд. Эта технология позволяет вам сосредоточиться на написании вашего приложения ближе к вашим пользователям, где бы они ни находились в мире (~50мс задержка).
Среда выполнения воркеров отличается от Node.js или браузера, она выполняет код с использованием V8, движка JavaScript, разработанного Google Chrome. До сих пор, что вы могли запускать на их платформе, были небольшие скрипты, выполняющиеся на Edge перед обращением к вашему серверу для повышения производительности или добавления некоторой логики на основе заголовков запроса, например.
В ноябре 2020 года, работая над Nuxt 3, мы сделали ставку на запуск Nuxt в продакшене на edge-рантаймах / изоляциях V8.
Это открывает возможность серверного рендеринга страниц в ~50мс со всего мира при использовании платформы, такой как CloudFlare Workers, без необходимости иметь дело с серверами, балансировщиками нагрузки и кэшированием, примерно за $0.3 за миллион запросов. На сегодняшний день, новые платформы появляются, чтобы позволить запускать приложения на изоляциях V8, такие как Deno Deploy.
Вызов
Чтобы заставить Nuxt работать в воркерах, нам пришлось переписать некоторые части Nuxt, чтобы они были независимы от среды (работают в Node.js, браузере или V8).
Мы начали с нашего сервера и создали unjs/h3: минимальный http-фреймворк, построенный для высокой производительности и переносимости. Он заменяет Connectкоторый мы использовали в Nuxt 2, но совместим с ним, так что вы можете продолжать использовать middleware Connect/Express. В воркерах для каждого входящего запроса он запускает Nuxt в продакшене, отправляет запрос в него и отправляет обратно ответ.
В Nuxt 2, время запуска сервера в продакшене в памяти (также известное как холодный старт) составляло около ~300мс, потому что нам приходилось загружать все зависимости вашего сервера и приложения, чтобы обработать запрос.
Работая над h3, мы решили разделить каждый обработчик, прикрепленный к серверу, и загружать их только по запросу. Когда вы запускаете Nuxt 3, мы загружаем в память только h3 и соответствующие обработчики. Когда приходит запрос, мы загружаем обработчик, соответствующий маршруту, и выполняем его.
Приняв этот подход, мы сократили холодный старт с ~300мс до ~2мс.
У нас была еще одна проблема, чтобы запустить Nuxt на Edge: размер продакшен бандла. Это включает в себя сервер, Vue-приложение и зависимости Node.js вместе. Cloudflare workers в настоящее время имеют лимит в 1MB (бесплатный план) и 5MB ($5 в месяц план) для размера воркера.
Чтобы достичь этого, мы создали unjs/nitro, Чтобы достичь этого, мы создали nuxt build
, он упаковывает весь ваш проект и включает все зависимости в окончательный вывод. Он использует Rollup и vercel/nft для трассировки только кода, используемого node_modules
, чтобы удалить ненужный код. Общий размер сгенерированного вывода для базового приложения Nuxt 3 составляет около 700kB gzip.
Наконец, чтобы обеспечить одинаковый опыт разработчика между разработкой (Node.js) и продакшеном на Cloudflare (Edge runtime), мы создали unjs/unenv: библиотеку для преобразования JavaScript-кода для запуска везде (независимо от платформы) путем имитации или добавления полифилов для известных зависимостей.
В Nuxt мы верим, что вы должны иметь свободу выбора провайдера хостинга, который подходит вам лучше всего.
Вот почему вы можете развернуть Nuxt-приложение с рендерингом на стороне Edge на:
- NuxtHub
- Cloudflare Page
- Deno Deploy
- Vercel Edge Functions (используя CloudFlare Workers под капотом)
- Netlify Edge Functions (используя Deno под капотом)
Мы также поддерживаем множество других провайдеров развертывания, включая статический хостинг или традиционные серверные хосты Node.js.
Расширение возможностей полнофункциональных приложений
Теперь, когда у нас есть Nuxt, работающий на Edge runtime, мы можем делать больше, чем просто рендерить Vue-приложение. Благодаря директории сервера, создание маршрута API — это TypeScript-файл.
Чтобы добавить маршрут /api/hello
, создайте файл server/api/hello.ts
:
export default defineEventHandler((event) => {
return {
hello: 'world'
}
})
Теперь вы можете универсально вызывать этот API в ваших страницах и компонентах:
<script setup>
const { data } = await useFetch('/api/hello')
</script>
<template>
<pre>{{ data }}</pre>
</template>
Важно отметить, что когда мы создавали useFetch и $fetch во время серверного рендеринга, если вы вызываете ваши маршруты API, он будет эмулировать запрос и вызывать код функции напрямую: избегая HTTP-запроса и сокращая время рендеринга страницы..
С точки зрения опыта разработчика, вы заметите, что при создании серверных файлов, Nuxt-сервер продолжает работать без перестроения Vue-приложения. Это потому, что Nuxt 3 поддерживает Hot Module Replacement (HMR) при создании API и серверных маршрутов.
Более того, используя Object Relational Mapping (ORM) вроде drizzle-orm, разработчики могут подключать Edge & Serverless базы данных, такие как D1, Turso, Neon, Planetscale и другие.
Я создал Atidone, открытый демонстрационный проект, чтобы продемонстрировать полнофункциональное приложение с аутентификацией и базой данных, работающее на Edge. Исходный код доступен на GitHub под лицензией MIT в репозитории atinux/atidone.
Заключение
Мы в восторге от рендеринга на стороне Edge и того, что он открывает. Наша команда в Nuxt не может дождаться, чтобы увидеть, что вы построите на основе этого!
Не стесняйтесь присоединиться к нашему Discord-серверу или упомянуть @nuxt_js в Twitter, чтобы поделиться своей работой.
Nuxt 3.7
Вышел Nuxt 3.7 с новым CLI, нативными веб-стримами и ответами, оптимизацией рендеринга, поддержкой асинхронного контекста и многим другим
Nuxt 3.6
Вышел Nuxt 3.6, предлагающий улучшения производительности, полностью статические серверные компоненты, улучшенное встраивание стилей, предустановки для статики, повышенную безопасность типов и многое другое.