@astrojs/cloudflare
Un adaptador SSR para usar con los objetivos de las funciones de Cloudflare Pages. Escribe tu código en Astro/Javascript y despliegalo en Cloudflare Pages.
Instalar
Sección titulada InstalarAgrega el adaptador de Cloudflare para habilitar el SSR en tu proyecto de Astro con el comando astro add
. Esto instalará el adaptador y realizará los cambios necesarios en tu archivo astro.config.mjs
en un solo paso.
# Usando NPMnpx astro add cloudflare# Usando Yarnyarn astro add cloudflare# Usando PNPMpnpm astro add cloudflare
Si prefieres instalar el adaptador manualmente en su lugar, sigue los siguientes dos pasos:
- Agrega el adaptador de Cloudflare como una dependencia de tu proyecto utilizando el gestor de paquetes de tu preferencia. Si estás utilizando npm o no estás seguro, ejecuta el siguiente comando en la terminal:
npm install @astrojs/cloudflare
- Agrega lo siguiente a tu archivo
astro.config.mjs
:
import { defineConfig } from 'astro/config';import cloudflare from '@astrojs/cloudflare';
export default defineConfig({ output: 'server', adapter: cloudflare(),});
Opciones
Sección titulada Opcionesmode: "advanced" | "directory"
Por defecto "advanced"
Cloudflare Pages tiene 2 modos diferentes para implementar funciones, el modo advanced
que busca el archivo _worker.js
en dist
, o un modo directory
donde las páginas compilarán el worker a partir de una carpeta de funciones en la raíz del proyecto. Para la mayoría de los proyectos, el valor predeterminado del adaptador advanced
será suficiente; la carpeta dist
contendrá tu proyecto compilado.
mode:directory
Sección titulada mode:directoryCambiar al modo de directorio te permite usar plugins de páginas como Sentry o escribir código personalizado para habilitar el registro.
export default defineConfig({ adapter: cloudflare({ mode: 'directory' }),});
En el modo directory
, el adaptador compilará la parte del lado del cliente de tu aplicación de la misma manera que en el modo advanced
de forma predeterminada, pero moverá el script del worker a una carpeta functions
en la raíz del proyecto. En este caso, el adaptador solo colocará un archivo [[path]].js
en esa carpeta, lo que te permitirá agregar plugins adicionales y middleware de páginas que pueden ser incluidos en el control de versiones.
Para en cambio compilar un paquete separado para cada página, establece la opción functionPerPath
en la configuración de tu adaptador de Cloudflare. Esta opción requiere cierto mantenimiento manual de la carpeta functions
. Los archivos emitidos por Astro sobrescribirán los archivos functions
existentes con nombres idénticos, por lo que debes elegir nombres de archivo únicos para cada archivo que agregues manualmente. Además, el adaptador nunca vaciará la carpeta functions
de archivos obsoletos, por lo que debes limpiar la carpeta manualmente cuando elimines páginas.
import {defineConfig} from "astro/config"; import cloudflare from '@astrojs/cloudflare';
export default defineConfig({ adapter: cloudflare({ mode: 'directory', functionPerRoute: true })})
Ten en cuenta que este adaptador no admite el uso de Middleware de Cloudflare Pages. Astro incluirá el middleware de Astro en cada página.
routes.strategy
Sección titulada routes.strategyroutes.strategy: "auto" | "include" | "exclude"
por defecto "auto"
Determina como routes.json
será generado si no se provee un _routes.json personalizado.
Hay tres opciones disponibles:
-
"auto"
(por defecto): Seleccionará automáticamente la estrategia que genere la menor cantidad de entradas. Esto debería ser casi siempre suficiente, así que elige esta opción a menos que tengas una razón específica para no hacerlo. -
include
: Las páginas y endpoints que no sean pre-renderizados se enumeran como entradasinclude
, indicando a Cloudflare que invoque estas rutas como funciones. Las entradasexclude
solo se utilizan para resolver conflictos. Por lo general, la mejor estrategia cuando tu sitio web tiene principalmente páginas estáticas y solo algunas páginas o endpoints dinámicos.Ejemplo: Para
src/pages/index.astro
(estático),src/pages/company.astro
(estático),src/pages/users/faq.astro
(estático) ysrc/pages/users/[id].astro
(SSR) esto producirá el siguiente_routes.json
:{"version": 1,"include": ["/_image", // Endpoint de imagen de Astro"/users/*" // Ruta dinámica],"exclude": [// Las rutas estáticas que deben estar exentas de la ruta dinámica de comodín anterior"/users/faq/","/users/faq/index.html"]}exclude
: Las páginas pre-renderizadas se enumeran como entradasexclude
(indicando a Cloudflare que maneje estas rutas como activos estáticos). Por lo general, la mejor estrategia cuando tu sitio web tiene principalmente páginas o endpoints dinámicos y solo algunas páginas estáticas.Ejemplo: Para las mismas páginas que en el ejemplo anterior, esto producirá el siguiente
_routes.json
:{"version": 1,"include": ["/*" // Toma todo como función excepto las rutas a continuación],"exclude": [// Todos los archivos estáticos"/","/company/","/index.html","/users/faq/","/favicon.png","/company/index.html","/users/faq/index.html"]}
routes.include
Sección titulada routes.includeroutes.include: string[]
por defecto []
Si quieres usar la generación automática de _routes.json
, pero quieres incluir rutas adicionales (por ejemplo, cuando tienes funciones personalizadas en la carpeta functions
), puedes usar la opción routes.include
para agregar rutas adicionales al array include
.
routes.exclude
Sección titulada routes.excluderoutes.exclude: string[]
por defecto []
Si quieres usar la generación automática de _routes.json
, pero quieres excluir rutas adicionales, puedes usar la opción routes.exclude
para agregar rutas adicionales al array exclude
.
El siguiente ejemplo automáticamente genera _routes.json
mientras incluye y excluye rutas adicionales. Ten en cuenta que esto solo es necesario si tienes funciones personalizadas en la carpeta functions
que no son manejadas por Astro.
export default defineConfig({ adapter: cloudflare({ mode: 'directory', routes: { strategy: 'include', include: ['/users/*'], // // manejado por una función personalizada: functions/users/[id].js exclude: ['/users/faq'], // manejado por una página estática: pages/users/faq.astro }, }),});
Habilitando la Vista Previa
Sección titulada Habilitando la Vista PreviaPara que la vista previa funcione, debes instalar wrangler
pnpm install wrangler --save-dev
Después es posible actualizar el script de vista previa en tu package.json
a "preview": "wrangler pages dev ./dist"
. Esto te permitirá ejecutar toda tu aplicación localmente con Wrangler, que admite secretos, variables de entorno, espacios de nombres KV, objetos duraderos y todas las otras vinculaciones admitidas por Cloudflare.
Acceso al runtime de Cloudflare
Sección titulada Acceso al runtime de CloudflarePuedes acceder a todos los enlaces y variables de entorno de Cloudflare desde los componentes y rutas de la API de Astro a través de Astro.locals
.
Si estás dentro de un archivo .astro
, puedes acceder al runtime utilizando el global Astro.locals
:
const env = Astro.locals.runtime.env;
Desde un endpoint:
export function GET(context) { const runtime = context.locals.runtime;
return new Response('Algún cuerpo');}
Dependiendo del modo de adaptador que estés utilizando (avanzado = worker, directorio = páginas), el objeto runtime tendrá una apariencia un poco diferente debido a las diferencias en la API de Cloudflare.
Si estás usando el runtime advanced
, puedes escribir el objeto runtime
de la siguiente manera:
/// <reference types="astro/client" />import type { AdvancedRuntime } from '@astrojs/cloudflare';
type ENV = { SERVER_URL: string;};
declare namespace App { interface Locals extends AdvancedRuntime<ENV> { user: { name: string; surname: string; }; }}
Si estás usando el runtime directory
, puedes escribir el objeto runtime
de la siguiente manera:
/// <reference types="astro/client" />import type { DirectoryRuntime } from '@astrojs/cloudflare';
type ENV = { SERVER_URL: string;};
declare namespace App { interface Locals extends DirectoryRuntime<ENV> { user: { name: string; surname: string; }; }}
Variables de entorno
Sección titulada Variables de entornoMira la documentación de Cloudflare para trabajar con variables de entorno.
export function GET({ params }) { // Accede a las variables de entorno por solicitud dentro de una función. const serverUrl = import.meta.env.SERVER_URL; const result = await fetch(serverUrl + "/user/" + params.id); return { body: await result.text(), };}
cloudflare.runtime
Sección titulada cloudflare.runtimeruntime: "off" | "local" | "remote"
Por defecto: "off"
Esta bandera opcional permite que el servidor de desarrollo de Astro llene las variables de entorno y el objeto de solicitud de Cloudflare, evitando la necesidad de Wrangler.
local
: las variables de entorno están disponibles, pero el objeto de solicitud se rellena con un valor de placeholder estático.remote
: las variables de entorno y el objeto de solicitud en vivo recuperado están disponibles.off
: el servidor de desarrollo de Astro no rellenará las variables de entorno ni el objeto de solicitud. Usa Wrangler para acceder a las vinculaciones y variables de entorno de Cloudflare.
import { defineConfig } from 'astro/config';import cloudflare from '@astrojs/cloudflare';
export default defineConfig({ output: 'server', adapter: cloudflare({ runtime: 'off' | 'local' | 'remote', }),});
Importaciones de módulos Wasm
Sección titulada Importaciones de módulos WasmwasmModuleImports: boolean
por defecto: false
Si importar o no los archivos .wasm
directamente como módulos ES.
Agrega wasmModuleImports: true
a astro.config.mjs
para habilitar tanto en la compilación de Cloudflare como en el servidor de desarrollo de Astro.
import {defineConfig} from "astro/config";import cloudflare from '@astrojs/cloudflare';
export default defineConfig({ adapter: cloudflare({ wasmModuleImports: true }), output: 'server'})
Una vez habilitado, puedes importar un módulo de web assembly en Astro con una importación .wasm?module
.
El siguiente es un ejemplo de importación de un módulo Wasm que luego responde a las solicitudes sumando los parámetros numéricos de la solicitud.
import mod from '../util/add.wasm?module';
// crea una instancia de antes para compartir el móduloconst addModule: any = new WebAssembly.Instance(mod);
export async function GET(context) { const a = Number.parseInt(context.params.a); const b = Number.parseInt(context.params.b); return new Response(`${addModule.exports.add(a, b)}`);}
Mientras que este ejemplo es trivial, Wasm puede ser utilizado para acelerar operaciones computacionalmente intensivas que no involucran operaciones I/O significativas, como incrustar una biblioteca de procesamiento de imágenes.
Encabezados, redireccionamientos y rutas de invocación de funciones.
Sección titulada Encabezados, redireccionamientos y rutas de invocación de funciones.Cloudflare ofrece soporte para agregar encabezados personalizados, configurar redirecciones estáticas y definir qué rutas deben invocar funciones. Cloudflare busca archivos _headers
, _redirects
, y _routes.json
en el directorio de salida de tu compilación para configurar estas características. Esto significa que deben ser colocados en el directorio public/
de tu proyecto Astro.
_routes.json
personalizado
Sección titulada _routes.json personalizadoPor defecto, @astrojs/cloudflare
generará un archivo _routes.json
con reglas de include
y exclude
basadas en las rutas dinámicas y estáticas de tu aplicación. Esto permitirá que Cloudflare sirva archivos y procese redireccionamientos estáticos sin necesidad de una invocación de función. Crear un archivo _routes.json
personalizado anulará esta optimización automática y, si no se configura manualmente, provocará invocaciones de funciones que contarán en contra de los límites de solicitudes de tu plan de Cloudflare.
Consulta la documentación de Cloudflare para obtener más detalles.
Compatibilidad con Node.js.
Sección titulada Compatibilidad con Node.js.El adaptador de Cloudflare de Astro te permite utilizar cualquier API de tiempo de ejecución Node.js soportada por Cloudflare.
- assert
- AsyncLocalStorage
- Buffer
- Diagnostics Channel
- EventEmitter
- path
- process
- Streams
- StringDecoder
- util
Para usar estas APIs, la página o el endpoint debe ser renderizado en el lado del servidor (no pre-renderizado) y debe utilizar la sintaxis de importación import {} from 'node:*'
.
export const prerender = false;import { Buffer } from 'node:buffer';
Además, deberás habilitar la Bandera de Compatibilidad en Cloudflare. La configuración de esta bandera puede variar según donde implementes tu sitio de Astro.
Para obtener una guía detallada, por favor consulta la documentación de Cloudflare.
Solución de problemas
Sección titulada Solución de problemasPara obtener ayuda, consulta el canal #support
en Discord. ¡Nuestros amables miembros del Equipo de Soporte están aquí para ayudar!
También puedes consultar nuestra documentación de integraciones de Astro para obtener más información sobre las integraciones.
Mensajes de error significativos
Sección titulada Mensajes de error significativosActualmente, los errores que surjan durante la ejecución de tu aplicación en Wrangler no son muy útiles debido a la minificación de tu código. Para una mejor depuración, puedes agregar la configuración vite.build.minify = false
a tu archivo astro.config.mjs
.
export default defineConfig({ adapter: cloudflare(), output: 'server',
vite: { build: { minify: false, }, },});
Contribuyendo
Sección titulada ContribuyendoEste paquete es mantenido por el equipo de Astro. ¡Estás invitado a abrir una issue o PR!