TL;DR — Résumé Rapide

Cloudflare Workers exécute JavaScript en périphérie avec des isolats V8. Déployez votre premier Worker avec Wrangler, KV, secrets et CI/CD via GitHub Actions.

Cloudflare Workers apporte le calcul serverless à la périphérie — votre code s’exécute dans des data centers répartis dans plus de 300 villes à travers le monde, à quelques millisecondes de vos utilisateurs, sans aucun provisionnement ou mise à l’échelle de serveurs. Construit sur des isolats V8 (le même moteur qui propulse Chrome et Node.js), Workers atteint des temps de démarrage à froid inférieurs à 1 milliseconde, étant dramatiquement plus rapide que les fonctions serverless traditionnelles basées sur des conteneurs. Dans ce guide, vous passerez de zéro à un Worker entièrement déployé en production avec stockage KV, secrets chiffrés, domaines personnalisés et un pipeline de déploiement automatisé avec GitHub Actions.

Prérequis

  • Node.js 18+ installé localement
  • Un compte Cloudflare (le niveau gratuit fonctionne pour tout dans ce guide)
  • Familiarité de base avec JavaScript ou TypeScript
  • Un domaine enregistré ajouté à Cloudflare (requis uniquement pour la section domaine personnalisé)
  • npm ou pnpm comme gestionnaire de paquets

Créer votre Premier Worker

Installez Wrangler, la CLI officielle de Cloudflare, globalement :

npm install -g wrangler
wrangler login

La commande wrangler login ouvre une fenêtre de navigateur et vous demande d’autoriser Wrangler à accéder à votre compte Cloudflare. Après l’autorisation, les identifiants sont stockés dans ~/.wrangler/config/default.toml.

Créez un nouveau projet :

wrangler init my-api-worker
cd my-api-worker

Wrangler présente quelques questions — choisissez TypeScript et le template “Hello World” Worker. La structure du répertoire résultante est :

my-api-worker/
  src/
    index.ts          ← votre code Worker
  wrangler.toml       ← configuration du projet
  package.json
  tsconfig.json

Comprendre wrangler.toml

Le fichier wrangler.toml est le manifeste du projet. Une configuration minimale ressemble à :

name = "my-api-worker"
main = "src/index.ts"
compatibility_date = "2024-09-23"

[[routes]]
pattern = "api.example.com/*"
zone_name = "example.com"

Champs clés :

ChampRôle
nameNom du Worker affiché dans le tableau de bord
mainFichier d’entrée résolu par Wrangler
compatibility_dateFixe le comportement de l’API runtime à une date spécifique
routesMappe les patterns d’URL vers ce Worker
[[kv_namespaces]]Lie les namespaces KV comme variables d’environnement
[vars]Variables d’environnement en texte brut

La compatibility_date est importante — Cloudflare introduit occasionnellement des changements incompatibles dans les APIs Worker, et cette date fixe quel ensemble d’APIs votre Worker voit.

Écrire le Worker

Le point d’entrée du Worker exporte un objet par défaut avec un handler fetch. Chaque requête HTTP entrante appelle ce handler :

export interface Env {
  MY_KV: KVNamespace;
  API_SECRET: string;
}

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const url = new URL(request.url);

    // Route : retourner du JSON
    if (url.pathname === '/api/status') {
      return Response.json({ status: 'ok', region: request.cf?.colo });
    }

    // Route : retourner du HTML
    if (url.pathname === '/') {
      return new Response(
        `<h1>Bonjour depuis la périphérie !</h1>`,
        { headers: { 'Content-Type': 'text/html;charset=UTF-8' } }
      );
    }

    return new Response('Non Trouvé', { status: 404 });
  }
};

Patterns de Request et Response

Workers utilise l’API Fetch standard — Request, Response et Headers sont identiques aux APIs du navigateur. Cela signifie que le code que vous écrivez pour Workers est largement portable.

Retourner du JSON est idiomatique avec Response.json() :

return Response.json({ items: ['a', 'b', 'c'] }, {
  headers: { 'Cache-Control': 'public, max-age=60' }
});

Rediriger une requête :

return Response.redirect('https://example.com/nouveau-chemin', 301);

Modifier une réponse proxiée (le pattern “transform”) :

const upstream = await fetch(request);
const body = await upstream.text();
return new Response(body.replace('ancien texte', 'nouveau texte'), upstream);

Développement Local

Démarrez le serveur de développement local :

wrangler dev

Wrangler démarre un serveur local sur http://localhost:8787 qui émule le runtime Cloudflare incluant KV, Durable Objects, R2 et l’objet de métadonnées request.cf. Le rechargement à chaud se déclenche automatiquement lors des changements de fichiers.

Pour tester contre l’infrastructure réelle de Cloudflare :

wrangler dev --remote

Inspectez le trafic en temps réel avec le log tail intégré dans un second terminal :

wrangler tail

Déployer en Production

Déployez avec une seule commande :

wrangler deploy

Wrangler compile votre TypeScript, empaquète les dépendances et télécharge le Worker sur le réseau Cloudflare. Le déploiement se propage mondialement en secondes. La sortie inclut l’URL workers.dev :

Published my-api-worker (2.45 sec)
  https://my-api-worker.votre-sous-domaine.workers.dev

Connecter un Domaine Personnalisé

Ajoutez un bloc routes dans wrangler.toml pour router les requêtes de votre domaine proxié par Cloudflare vers le Worker :

[[routes]]
pattern = "api.example.com/*"
zone_name = "example.com"

Alternativement, utilisez la fonctionnalité Custom Domains :

[[routes]]
pattern = "api.example.com"
custom_domain = true

Variables d’Environnement et Secrets

Variables Simples

La configuration non sensible vit dans wrangler.toml :

[vars]
ENVIRONMENT = "production"
MAX_RETRIES = "3"

Secrets Chiffrés

Les secrets sont chiffrés au repos et ne sont jamais visibles après le téléchargement. Ajoutez-les via CLI :

wrangler secret put API_KEY

Wrangler vous demande de saisir la valeur de manière interactive. Listez les secrets existants :

wrangler secret list

Dans le Worker, les secrets apparaissent comme env.API_KEY — indiscernables des variables simples à l’exécution mais stockés chiffrés dans le coffre de Cloudflare.

Stockage KV

KV (Workers KV) est un stockage clé-valeur distribué mondialement avec cohérence éventuelle. Il excelle pour stocker des configurations, sessions utilisateurs, réponses d’API en cache et feature flags.

Créez un namespace KV :

wrangler kv namespace create CACHE

Ajoutez le binding à wrangler.toml :

[[kv_namespaces]]
binding = "CACHE"
id = "abc123def456..."

Écrivez et lisez depuis KV dans le Worker :

// Écrire (avec TTL optionnel en secondes)
await env.CACHE.put('utilisateur:123', JSON.stringify(donneesUtil), { expirationTtl: 3600 });

// Lire
const raw = await env.CACHE.get('utilisateur:123');
const utilisateur = raw ? JSON.parse(raw) : null;

// Supprimer
await env.CACHE.delete('utilisateur:123');

Comparaison

FonctionnalitéCloudflare WorkersAWS Lambda@EdgeDeno Deploy
RuntimeIsolats V8Conteneur Node.jsIsolats V8
Démarrage à froid< 1 ms100–500 ms~50 ms
PoP mondiaux300+~4 régions CloudFront35 régions
Niveau gratuit100k req/jourPaiement par requête100k req/jour
Temps CPU max.50 ms (gratuit) / 30 s (payant)30 s50 ms
StockageKV, R2, D1, Durable ObjectsDynamoDB (séparé)Deno KV
TypeScriptNatif (intégré)Via étape de buildNatif
Prix (au-delà du gratuit)0,50$/million requêtes~0,60$/million + Lambda0,50$/million requêtes

Workers gagne sur le démarrage à froid et la distribution mondiale. Lambda@Edge est le bon choix si vous êtes déjà profondément investi dans l’écosystème AWS. Deno Deploy est une bonne alternative si vous voulez le modèle de permissions de Deno.

Scénario Réel : Worker Proxy d’API

Vous avez une API tierce qui ne supporte pas CORS, nécessite une clé API que vous ne pouvez pas exposer au navigateur, et répond avec des données que vous souhaitez mettre en cache et transformer. Un Cloudflare Worker est la solution parfaite.

export interface Env {
  UPSTREAM_API_KEY: string;
  CACHE: KVNamespace;
}

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const url = new URL(request.url);
    const upstreamUrl = `https://api.tiers.com${url.pathname}${url.search}`;
    const cacheKey = upstreamUrl;

    // Vérifier le cache KV d'abord
    const cached = await env.CACHE.get(cacheKey);
    if (cached) {
      return Response.json(JSON.parse(cached), {
        headers: { 'X-Cache': 'HIT', 'Access-Control-Allow-Origin': '*' }
      });
    }

    // Récupérer depuis l'upstream avec la clé secrète
    const upstream = await fetch(upstreamUrl, {
      headers: { 'Authorization': `Bearer ${env.UPSTREAM_API_KEY}` }
    });

    if (!upstream.ok) {
      return new Response('Erreur upstream', { status: upstream.status });
    }

    const data = await upstream.json();

    // Mettre en cache la réponse pour 5 minutes
    ctx.waitUntil(env.CACHE.put(cacheKey, JSON.stringify(data), { expirationTtl: 300 }));

    return Response.json(data, {
      headers: { 'X-Cache': 'MISS', 'Access-Control-Allow-Origin': '*' }
    });
  }
};

Ce Worker garde la clé API côté serveur, ajoute des en-têtes CORS manquants, et sert des réponses en cache depuis les emplacements edge les plus proches de chaque utilisateur.

CI/CD avec GitHub Actions

Automatisez les déploiements à chaque push vers main :

# .github/workflows/deploy.yml
name: Deploy Worker

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    name: Deploy
    steps:
      - uses: actions/checkout@v4

      - name: Configurer Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'

      - name: Installer les dépendances
        run: npm ci

      - name: Déployer sur Cloudflare Workers
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CF_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

Ajoutez CF_API_TOKEN et CLOUDFLARE_ACCOUNT_ID comme secrets du dépôt dans GitHub. Créez le token API dans le tableau de bord Cloudflare sous Profil → Tokens API → Créer un Token en utilisant le modèle “Edit Cloudflare Workers”.

Pièges et Cas Particuliers

Limite de temps CPU — Le plan gratuit autorise 10 ms de temps CPU par requête. Le plan Workers Paid augmente cela à 30 secondes. Un travail intensif en CPU peut atteindre cette limite ; déchargez les calculs lourds vers une file d’attente ou utilisez des Durable Objects.

Limites de sous-requêtes — Chaque invocation de Worker peut effectuer jusqu’à 50 appels fetch() sortants sur le plan gratuit (1000 sur le plan payant).

Date de compatibilité et changements incompatibles — Lors de la mise à jour de compatibility_date, examinez le journal des modifications des flags de compatibilité.

Limites de taille — Les scripts Worker sont limités à 1 Mo après compression (10 Mo sur le plan payant). Les grandes dépendances npm peuvent dépasser cette limite ; utilisez le tree shaking.

Pas d’accès au système de fichiers — Les Workers n’ont pas d’E/S disque. Toute persistance doit passer par KV, R2, D1 ou Durable Objects.

waitUntil pour le travail en arrière-plan — Utilisez ctx.waitUntil(promise) pour le travail devant se terminer après l’envoi de la réponse (comme les écritures en cache).

Résolution de Problèmes

Error: Script startup exceeded CPU time limit — Votre Worker effectue un travail coûteux lors de l’initialisation du module. Déplacez les opérations coûteuses à l’intérieur du handler ou utilisez une initialisation lazy.

TypeError: Cannot read properties of undefined (reading 'get') — Un binding KV ou autre binding est absent de wrangler.toml, ou vous accédez à env.MON_BINDING avant que le binding ne soit configuré.

wrangler deploy échoue avec “Authentication error” — Votre session Wrangler a expiré. Exécutez wrangler login à nouveau ou définissez la variable d’environnement CLOUDFLARE_API_TOKEN.

Erreurs CORS dans le navigateur — La réponse du Worker manque Access-Control-Allow-Origin. Ajoutez l’en-tête dans votre constructeur Response. Gérez également la requête de preflight OPTIONS séparément.

Le domaine personnalisé ne route pas vers le Worker — Assurez-vous que le domaine est proxié par Cloudflare (nuage orange dans les paramètres DNS), que le pattern de route dans wrangler.toml utilise le joker /* si nécessaire, et que vous avez redéployé après avoir modifié wrangler.toml.

Résumé

  • Les Cloudflare Workers sont des fonctions serverless basées sur des isolats V8 qui s’exécutent à la périphérie avec des démarrages à froid inférieurs à la milliseconde et une distribution mondiale
  • Installez Wrangler avec npm install -g wrangler, créez le squelette avec wrangler init et testez localement avec wrangler dev
  • Le fichier wrangler.toml contrôle le nom du Worker, le point d’entrée, la date de compatibilité, les routes et tous les bindings de ressources
  • Utilisez wrangler secret put pour les valeurs sensibles et [vars] dans wrangler.toml pour la configuration non sensible
  • Les namespaces KV fournissent un stockage clé-valeur distribué mondialement, accessible via env.BINDING.get/put/delete
  • Workers surpasse Lambda@Edge sur le démarrage à froid et la portée mondiale ; Lambda@Edge est préférable pour une intégration profonde dans l’écosystème AWS
  • L’Action wrangler-action de GitHub fournit un CI/CD clé en main ; limitez votre token API aux seules permissions Workers
  • Surveillez les limites de temps CPU, les plafonds de sous-requêtes et le plafond de 1 Mo de taille de script sur le plan gratuit

Articles Connexes