AstroMiddleTechnical

Что такое адаптеры (adapters) в Astro и когда они нужны?

Адаптеры — это плагины, которые упаковывают Astro-приложение под конкретную серверную платформу (Node.js, Vercel, Cloudflare Workers и др.). Они нужны только в SSR-режиме (output: 'server' или 'hybrid').

Что такое адаптеры в Astro

Адаптер — это пакет, который знает, как запустить собранное Astro-приложение на конкретной серверной платформе. При статической сборке (output: 'static') сервер не нужен, поэтому адаптеры там не применяются. Как только вы включаете SSR (output: 'server') или гибридный режим (output: 'hybrid'), Astro требует адаптер, чтобы знать, как обернуть запросы и ответы для конкретной среды выполнения.

Официальные адаптеры

  • @astrojs/node — Node.js (Express, Fastify или standalone HTTP-сервер)
  • @astrojs/vercel — Vercel Edge/Serverless Functions
  • @astrojs/cloudflare — Cloudflare Workers / Pages
  • @astrojs/netlify — Netlify Edge Functions
  • @astrojs/deno — Deno Deploy

Установка и настройка

Пример для Node.js:

npx astro add node

Это автоматически установит пакет и добавит его в astro.config.mjs:

import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({
    mode: 'standalone', // или 'middleware'
  }),
});

Режимы адаптера Node.js

  • standalone — Astro поднимает собственный HTTP-сервер; запуск: node ./dist/server/entry.mjs
  • middleware — экспортирует Express/Connect-совместимый middleware; вы встраиваете его в существующий сервер
// middleware-режим: server.mjs
import express from 'express';
import { handler as ssrHandler } from './dist/server/entry.mjs';

const app = express();
app.use('/static', express.static('./dist/client'));
app.use(ssrHandler);
app.listen(3000);

Адаптер Cloudflare

import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'server',
  adapter: cloudflare({
    mode: 'directory', // или 'advanced'
    functionPerRoute: false,
  }),
});

После сборки (astro build) деплой выполняется командой wrangler pages deploy ./dist.

Написание собственного адаптера

Адаптер — это объект, реализующий интерфейс AstroAdapter:

export default function myAdapter() {
  return {
    name: 'my-adapter',
    serverEntrypoint: './my-server-entry.mjs',
    hooks: {
      'astro:config:done': ({ setAdapter }) => {
        setAdapter({
          name: 'my-adapter',
          serverEntrypoint: './my-server-entry.mjs',
          supportedAstroFeatures: {
            staticOutput: 'unsupported',
            serverOutput: 'stable',
          },
        });
      },
    },
  };
}

Подводные камни

  • Забыть указать output: 'server' — адаптер без этой настройки не активируется, и SSR-страницы компилируются как статические.
  • Node.js-адаптер в режиме standalone не раздаёт статические файлы из dist/client/ автоматически — нужно настроить nginx или express.static вручную.
  • Cloudflare Workers не поддерживает Node.js API (fs, crypto и др.) без флага nodejs_compat в wrangler.toml.
  • Разные адаптеры имеют разные ограничения на размер бандла, время выполнения и поддержку Web Streams — проверяйте документацию платформы.
  • В гибридном режиме (output: 'hybrid') страницы по умолчанию статические; чтобы сделать маршрут серверным, добавьте export const prerender = false.
  • Переменные окружения на Vercel/Cloudflare нужно добавлять через панель платформы, а не только через .env — локальный .env не читается в продакшне.
  • При использовании @astrojs/vercel в режиме Edge-функций нельзя использовать тяжёлые Node.js-зависимости — среда выполнения ограничена V8 isolates.

Common mistakes

  • Запускать output: 'server' без подключённого адаптера.
  • Использовать в коде Node-only API при деплое на edge-рантайм.
  • Подключать сразу несколько адаптеров.

What the interviewer is testing

  • Объясняет роль адаптера и связь с output.
  • Различает Node, edge и serverless рантаймы.
  • Знает, как платформенный контекст пробрасывается в Astro.locals.

Sources

Related topics