Aller au contenu

Cloudflare Pages ​

Attention

Pour les nouveaux projets, Cloudflare recommande désormais Cloudflare Workers plutôt que Cloudflare Pages. Workers prend en charge les ressources statiques et offre davantage de fonctionnalités. Si vous créez une nouvelle application full-stack, consultez Cloudflare Workers + Vite, qui succède à cette configuration Pages. L'adaptateur hono/cloudflare-pages est obsolète et sera supprimé dans Hono v5.

Cloudflare Pages est une plateforme edge pour les applications web full-stack. Elle sert des fichiers statiques et du contenu dynamique fourni par Cloudflare Workers.

Hono prend entièrement en charge Cloudflare Pages. L'expérience de développement est agréable : le serveur de développement Vite est rapide et le déploiement avec Wrangler est très rapide.

1. Configuration ​

Un modèle de démarrage est disponible pour Cloudflare Pages. Créez votre projet avec la commande « create-hono ». Sélectionnez le modèle cloudflare-pages pour cet exemple.

sh
npm create hono@latest my-app
sh
yarn create hono my-app
sh
pnpm create hono my-app
sh
bun create hono@latest my-app
sh
deno init --npm hono my-app

Ouvrez my-app et installez les dépendances.

sh
cd my-app
npm i
sh
cd my-app
yarn
sh
cd my-app
pnpm i
sh
cd my-app
bun i

Voici une arborescence de base.

text
./
├── package.json
├── public
│   └── static // Put your static files.
│       └── style.css // You can refer to it as `/static/style.css`.
├── src
│   ├── index.tsx // The entry point for server-side.
│   └── renderer.tsx
├── tsconfig.json
└── vite.config.ts

2. Bonjour le monde ​

Modifiez src/index.tsx comme suit :

tsx
import { Hono } from 'hono'
import { renderer } from './renderer'

const app = new Hono()

app.get('*', renderer)

app.get('/', (c) => {
  return c.render(<h1>Hello, Cloudflare Pages!</h1>)
})

export default app

3. Exécution ​

Démarrez le serveur de développement localement. Ensuite, ouvrez http://localhost:5173 dans votre navigateur web.

sh
npm run dev
sh
yarn dev
sh
pnpm dev
sh
bun run dev

4. Déploiement ​

Si vous avez un compte Cloudflare, vous pouvez déployer sur Cloudflare. Dans package.json, remplacez $npm_execpath par le gestionnaire de paquets de votre choix.

sh
npm run deploy
sh
yarn deploy
sh
pnpm run deploy
sh
bun run deploy

Déployer depuis le tableau de bord Cloudflare avec GitHub ​

  1. Connectez-vous au tableau de bord Cloudflare et sélectionnez votre compte.
  2. Sur la page d'accueil du compte, sélectionnez Workers & Pages > Create application > Pages > Connect to Git.
  3. Autorisez l'accès à votre compte GitHub et sélectionnez le dépôt. Dans Set up builds and deployments, renseignez les informations suivantes :
Option de configurationValeur
Branche de productionmain
Commande de compilationnpm run build
Répertoire de compilationdist

Bindings ​

Vous pouvez utiliser les bindings Cloudflare, tels que les variables, KV, D1 et autres. Dans cette section, nous utiliserons les variables et KV.

Créer wrangler.toml ​

Créez d'abord wrangler.toml pour les bindings locaux :

sh
touch wrangler.toml

Modifiez wrangler.toml. Définissez une variable nommée MY_NAME.

toml
[vars]
MY_NAME = "Hono"

Créer un espace KV ​

Ensuite, créez l'espace KV. Exécutez la commande wrangler suivante :

sh
wrangler kv namespace create MY_KV --preview

Notez le preview_id affiché dans le résultat suivant :

{ binding = "MY_KV", preview_id = "abcdef" }

Renseignez preview_id avec le nom du binding, MY_KV :

toml
[[kv_namespaces]]
binding = "MY_KV"
id = "abcdef"

Modifier vite.config.ts ​

Modifiez vite.config.ts :

ts
import devServer from '@hono/vite-dev-server'
import adapter from '@hono/vite-dev-server/cloudflare'
import build from '@hono/vite-cloudflare-pages'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    devServer({
      entry: 'src/index.tsx',
      adapter, // Cloudflare Adapter
    }),
    build(),
  ],
})

Utiliser les bindings dans votre application ​

Utilisez la variable et KV dans votre application. Définissez leurs types.

ts
type Bindings = {
  MY_NAME: string
  MY_KV: KVNamespace
}

const app = new Hono<{ Bindings: Bindings }>()

Utilisez-les :

tsx
app.get('/', async (c) => {
  await c.env.MY_KV.put('name', c.env.MY_NAME)
  const name = await c.env.MY_KV.get('name')
  return c.render(<h1>Hello! {name}</h1>)
})

En production ​

Pour Cloudflare Pages, vous utiliserez wrangler.toml en développement local, mais vous configurerez les bindings dans le tableau de bord en production.

Côté client ​

Vous pouvez écrire des scripts côté client et les importer dans votre application grâce aux fonctionnalités de Vite. Si /src/client.ts est le point d'entrée du client, indiquez-le simplement dans la balise script. De plus, import.meta.env.PROD permet de déterminer si le code s'exécute sur un serveur de développement ou pendant la compilation.

tsx
app.get('/', (c) => {
  return c.html(
    <html>
      <head>
        {import.meta.env.PROD ? (
          <script type='module' src='/static/client.js'></script>
        ) : (
          <script type='module' src='/src/client.ts'></script>
        )}
      </head>
      <body>
        <h1>Hello</h1>
      </body>
    </html>
  )
})

Pour compiler correctement le script, vous pouvez utiliser l'exemple de fichier de configuration vite.config.ts ci-dessous.

ts
import pages from '@hono/vite-cloudflare-pages'
import devServer from '@hono/vite-dev-server'
import { defineConfig } from 'vite'

export default defineConfig(({ mode }) => {
  if (mode === 'client') {
    return {
      build: {
        rollupOptions: {
          input: './src/client.ts',
          output: {
            entryFileNames: 'static/client.js',
          },
        },
      },
    }
  } else {
    return {
      plugins: [
        pages(),
        devServer({
          entry: 'src/index.tsx',
        }),
      ],
    }
  }
})

Vous pouvez exécuter la commande suivante pour compiler le serveur et le script client.

sh
vite build --mode client && vite build

Middlewares Cloudflare Pages ​

Cloudflare Pages utilise son propre système de middlewares, différent de celui de Hono. Vous pouvez l'activer en exportant onRequest dans un fichier nommé _middleware.ts, comme suit :

ts
// functions/_middleware.ts
export async function onRequest(pagesContext) {
  console.log(`You are accessing ${pagesContext.request.url}`)
  return await pagesContext.next()
}

Avec handleMiddleware, vous pouvez utiliser les middlewares Hono comme middlewares Cloudflare Pages.

ts
// functions/_middleware.ts
import { handleMiddleware } from 'hono/cloudflare-pages'

export const onRequest = handleMiddleware(async (c, next) => {
  console.log(`You are accessing ${c.req.url}`)
  await next()
})

Vous pouvez aussi utiliser les middlewares intégrés et tiers de Hono. Par exemple, pour ajouter une authentification Basic, utilisez le middleware d'authentification Basic de Hono.

ts
// functions/_middleware.ts
import { handleMiddleware } from 'hono/cloudflare-pages'
import { basicAuth } from 'hono/basic-auth'

export const onRequest = handleMiddleware(
  basicAuth({
    username: 'hono',
    password: 'acoolproject',
  })
)

Pour appliquer plusieurs middlewares, écrivez :

ts
import { handleMiddleware } from 'hono/cloudflare-pages'

// ...

export const onRequest = [
  handleMiddleware(middleware1),
  handleMiddleware(middleware2),
  handleMiddleware(middleware3),
]

Accéder à EventContext ​

Vous pouvez accéder à l'objet EventContext via c.env dans handleMiddleware.

ts
// functions/_middleware.ts
import { handleMiddleware } from 'hono/cloudflare-pages'

export const onRequest = [
  handleMiddleware(async (c, next) => {
    c.env.eventContext.data.user = 'Joe'
    await next()
  }),
]

Vous pouvez ensuite accéder à la valeur data via c.env.eventContext dans le gestionnaire :

ts
// functions/api/[[route]].ts
import type { EventContext } from 'hono/cloudflare-pages'
import { handle } from 'hono/cloudflare-pages'

// ...

type Env = {
  Bindings: {
    eventContext: EventContext
  }
}

const app = new Hono<Env>().basePath('/api')

app.get('/hello', (c) => {
  return c.json({
    message: `Hello, ${c.env.eventContext.data.user}!`, // 'Joe'
  })
})

export const onRequest = handle(app)

Publié sous licence MIT.