11. modulFejlesztői workflow: wrangler, lokális dev, tesztelés, debug
Cloudflare for Devs · 11. modul (kiegészítő)

Fejlesztői workflow: wrangler, lokális dev, tesztelés, debug

Az eddigi modulok azt mondták meg, mit építs. Ez a modul arról szól, hogyan telik a napod: milyen a fejlesztői hurok, mit tud a wrangler, hol él a lokális állapot, mikor kapcsolódj éles erőforráshoz, hogyan tesztelsz és debugolsz, és hogyan áll be egy új fejlesztő a csapatba.

11.1A napi hurok — mi változik a Beanstalk-rutinhoz képest

A legfontosabb strukturális változás: a lokális futtatás nem szimuláció, hanem ugyanaz a runtime. A wrangler dev a workerd-t (a Workers nyílt forráskódú futtatókörnyezetét) indítja el a gépeden, Miniflare-be csomagolva, a bindingok lokális megfelelőivel. Ez az, amiért a „lokálisan ment, élesben nem" osztály nagyrészt eltűnik.

A fejlesztői hurok — és hol van a visszacsatolás kód írása + wrangler types wrangler dev / vite dev valódi workerd + HMR vitest --watch tesztek a runtime-ban PR preview URL deploy másodpercek ezredmásodperces újratöltés — itt telik a napod tail / logs / metrikák visszacsatolása
11/1. ábra — A belső hurok (kód ↔ dev szerver) másodperc alatti; a külső hurok (PR-preview → deploy) percekben mérhető, nem tíz percekben.
Eddigi szokásodÚj megfelelőjeMi a nyereség
npm run dev (Node lokálisan)wrangler dev / vite dev a Cloudflare pluginnelugyanaz a runtime, mint élesben
AWS-erőforrások mockolása / dev-fióklokális binding-szimuláció, vagy remote: true bindingonkéntoffline is fejlesztesz; ahol kell, valódi erőforrás
Jest + moduláris mockokVitest a workerd-ben futtatvaa teszt látja a bindingokat, nem kell mockolni
eb deploy (percek)wrangler deploy (másodpercek)a deploy megszűnik esemény lenni
CloudWatch-böngészés hiba utánwrangler tail élőbenazonnali visszacsatolás

11.2Wrangler: az egy CLI, ami a fél AWS-konzolt kiváltja

A wrangler egyszerre tölti be az eb, a aws CLI, a terraform és részben a psql/s3cmd szerepét. Érdemes kategóriákban a fejedben tartani:

Projekt és fejlesztés

npm create cloudflare@latest        # új projekt (C3), keretrendszer-sablonokkal
npx wrangler dev                    # lokális dev szerver (workerd)
npx wrangler dev --env staging      # nevesített környezet konfigjával
npx wrangler dev --test-scheduled   # cron-teszteléshez /__scheduled route
npx wrangler dev --tunnel           # lokális szerver megosztása Tunnelen (webhook-teszt!)
npx wrangler types                  # Env típus generálása a bindingokból

Deploy és release (8. modul)

npx wrangler deploy --env production
npx wrangler versions upload        # feltöltés forgalom nélkül
npx wrangler versions deploy        # forgalomarány állítása (kanári)
npx wrangler rollback
npx wrangler deployments list       # mi fut most, mióta

Erőforrások — ez váltja ki az AWS-konzolt

# létrehozás (a 8. modul env-fegyelme szerint -staging / -prod párokban)
npx wrangler d1 create app-prod --location weur
npx wrangler r2 bucket create uploads-prod
npx wrangler kv namespace create CONFIG
npx wrangler queues create jobs

# adatműveletek
npx wrangler d1 execute app-prod --remote --command "SELECT COUNT(*) FROM users" --json
npx wrangler d1 migrations apply app-prod --remote
npx wrangler d1 export app-prod --remote --output=./dump.sql
npx wrangler r2 object put uploads-prod/logo.png --file ./logo.png
npx wrangler kv key put --binding CONFIG feature-flags '{"beta":true}' --remote

# titkok (8. modul)
npx wrangler secret put STRIPE_KEY --env production
npx wrangler secret list --env production

Megfigyelés és hibakeresés (9. modul)

npx wrangler tail --env production --status error
npx wrangler tail --format json | jq '.logs[].message'
Két életmentő szokás: ① tedd a gyakori parancsokat package.json-scriptekbe ("db:migrate:prod", "logs:prod") — így a csapat nem másol félrement flageket, és a veszélyes --remote mindig ott van, ahol lennie kell; ② a --json kimenetet ismerd meg korán: a wrangler szinte minden lekérdező parancsa tud gépi kimenetet, amiből fél óra alatt írsz kis ops-szkripteket (pl. a multitenant flottád registry-riportját, 5b. modul).

11.3Lokális fejlesztés: hol él az állapot?

A wrangler dev minden bindingnak lokális megfelelőt ad: a D1 egy valódi SQLite-fájl, az R2 és a KV a lemezre írnak, a Queues és a Durable Objects lokálisan futnak. Az állapot alapértelmezetten a .wrangler/state mappában perzisztálódik (tehát túléli az újraindítást — és a .gitignore-ba való).

# saját állapot-mappa (pl. több feature-branch külön adattal)
npx wrangler dev --persist-to .state/feature-x

# FONTOS: a lokális adatot módosító parancsoknál is meg kell adni
npx wrangler d1 execute app-dev --local --persist-to .state/feature-x --file=./seed.sql
npx wrangler kv key put --binding CONFIG test 12345 --local --persist-to .state/feature-x

A lokális adat feltöltése (seed) ugyanígy megy: egy seed.sql a repóban, és egy npm run db:seed script — az új fejlesztőnek így a klónozás után két parancs a működő környezet. Ez a Beanstalk-világ „kérj hozzáférést a dev RDS-hez" rituáléjának a helyére lép.

Amit a lokális szimuláció nem ad meg: a valódi hálózati viselkedést (a request.cf mezők, a földrajzi routing, a valódi cache-rétegek), az éles adatok furcsaságait, és a tényleges CPU-limitet — a limitek lokálisan nem érvényesülnek. Ezért kell a staging (8. modul) és a preview URL: a lokális hurok a logikát igazolja, a staging a valóságot.

11.4Remote bindings — a legjobb újítás a napi munkában

Régen két rossz választásod volt: vagy minden lokálisan szimulált (gyors, de az adat nem valódi), vagy wrangler dev --remote, ahol az egész Worker a felhőben fut (valódi, de lassú iteráció). A mai megoldás a kettő legjobbja: a kód lokálisan fut, de bindingonként megmondhatod, hogy az adott erőforrás az éles legyen:

wrangler.jsonc
{
  "r2_buckets": [{
    "binding": "UPLOADS",
    "bucket_name": "uploads-staging",
    "remote": true            // ez a binding az ÉLES (staging) bucketre megy
  }],
  "d1_databases": [{
    "binding": "DB", "database_name": "app-dev", "database_id": "…"
    // remote nincs megadva → lokális SQLite, gyors és eldobható
  }]
}

Tipikus használat: a lokális D1-en dolgozol (gyors, szabadon törölhető), de az R2-bindinget vagy egy külső AI/Vectorize szolgáltatást a valódira kötöd, mert azt nem lehet értelmesen szimulálni. A wrangler dev --local flaggel egy pillanat alatt kikapcsolod az összes remote bindinget (pl. repülőn).

MódHol fut a kódMikor használd
wrangler devlokálisan, lokális bindingokkala napi 90% — leggyorsabb hurok
wrangler dev + remote: truelokálisan, kiválasztott bindingok élesbenha valódi adat vagy nem szimulálható szolgáltatás kell
wrangler dev --remote (legacy)minden a Cloudflare-encsak hálózat-specifikus viselkedés tesztelésére; lassú
Két korlát, amit tudni kell: a Durable Objects és a Workflows nem lehet remote binding — ezek lokálisan futnak. Ha éles DO-val kell beszélned, a bevált kerülőút egy service binding egy deployolt Workerre, ami proxyként éri el őket. És a nyilvánvaló, mégis gyakori baleset: a remote: true valódi adatot ír — soha ne mutasson a production erőforrásra a fejlesztői konfigban, csak stagingre.

11.5Típusok: a bindingjaid legyenek típusosak

A wrangler types a konfigodból generálja az Env típust — vagyis az env.DB, env.UPLOADS, env.STRIPE_KEY mind típusos lesz, és a hiányzó binding fordítási hiba, nem éjszakai riasztás:

npx wrangler types            # → worker-configuration.d.ts

Tedd be a package.json-ba a postinstall-ba vagy a dev-script elé, hogy soha ne csússzon el a konfigtól. Nuxt-projektben (3. modul) ezután deklaráld a H3EventContext-en, hogy az event.context.cloudflare.env is típusos legyen — így a server route-jaidban is IDE-támogatást kapsz.

11.6Tesztelés: a tesztjeid a Workers-runtime-ban futnak

Ez a rész az, ami Node-háttérrel a legkellemesebb meglepetés. A hivatalos ajánlás a Vitest-integráció (@cloudflare/vitest-pool-workers): a teszt-fájljaid nem Node-ban, hanem a workerd-ben futnak, így közvetlenül elérik a bindingokat és a runtime API-kat — nincs több „mockoljuk az S3-klienst" kör.

vitest.config.ts
import { cloudflareTest } from "@cloudflare/vitest-pool-workers";
import { defineConfig } from "vitest/config";

export default defineConfig({
  plugins: [cloudflareTest({ wrangler: { configPath: "./wrangler.jsonc" } })],
});

1. példa: unit teszt valódi bindinggal

import { env } from "cloudflare:workers";
import { it, expect } from "vitest";
import { createInvoice } from "../src/invoices";

it("számlát ír a D1-be", async () => {
  await createInvoice(env, { tenantId: "acme", total: 1000 });

  // közvetlenül ellenőrizzük a binding állapotát — nincs mock!
  const row = await env.DB
    .prepare("SELECT total FROM invoices WHERE tenant_id = ?")
    .bind("acme").first();
  expect(row.total).toBe(1000);
});

A tárolás teszt-fájlonként izolált, tehát a tesztek nem szemetelnek egymásnak — ez az, amit Node-világban külön tranzakció-rollback trükkökkel értél el.

2. példa: a teljes Worker meghívása (integrációs jelleggel)

import { exports } from "cloudflare:workers";
import "../src/index";

it("404-et ad ismeretlen útvonalra", async () => {
  const res = await exports.default.fetch("http://example.com/nincs-ilyen");
  expect(res.status).toBe(404);
});

3. példa: Durable Object tesztelése — a különleges eszközök

A DO-k (7. modul) tesztelésére saját segédfüggvények vannak, amikkel a belsejükbe nyúlhatsz és az időt is „előretekerheted":

import { env } from "cloudflare:workers";
import { runInDurableObject, runDurableObjectAlarm, evictDurableObject }
  from "cloudflare:test";

it("lejáró foglalást felszabadít az alarm", async () => {
  const stub = env.EVENT_SEATS.get(env.EVENT_SEATS.idFromName("gala"));
  await stub.reserve("user-1", 2);

  // belenézünk az objektum saját tárába
  await runInDurableObject(stub, async (instance, state) => {
    const free = state.storage.sql.exec("SELECT free FROM seats").one().free;
    expect(free).toBe(98);
  });

  await runDurableObjectAlarm(stub);   // nem várunk 10 percet — most lefuttatjuk
  await evictDurableObject(stub);      // szimulált kilakoltatás: túléli a memória-vesztést?
});
Mit teszteljünk és mit ne? A saját üzleti logikádat teszteld (számítás, jogosultság, állapotgép, tenant-izoláció) — ezekhez a valódi bindingok most már ingyen adottak. Ne teszteld a platformot (hogy a KV visszaadja-e, amit beírtál). A migrációk és a séma helyességét pedig a stagingen bizonyítod (8. modul), nem unit tesztben. Egy dolgot viszont érdemes lefedni, mert olcsó és sokat ment: az idempotencia — a queue-consumer kétszer kapja meg ugyanazt az üzenetet (7. modul), és a teszt igazolja, hogy nem lesz dupla számla.

11.7Debug: breakpointok, profil, élő log

11.8Több Worker, monorepo, service bindings

Ahogy nő a rendszer, jellemzően szétválik: a fő Nuxt-app Worker, mellette egy-két háttér-Worker (queue-consumer, cron, admin-API). A szervezés eszközei:

11.9Csapat: onboarding, hozzáférés, IaC

Egy új fejlesztő első napja

  1. git clone + npm i
  2. npx wrangler login (böngészős OAuth — nincs kulcs-csereberélés)
  3. .dev.vars kitöltése a csapat titkos-tárából (a secrets.required lista megmondja, mi kell — 8. modul)
  4. npm run db:seednpm run dev — és fut a teljes stack lokálisan

Ehhez nem kell AWS-konzol-hozzáférés, VPN, dev-RDS jelszó vagy IAM-szerepkör. Az élesre írási jogot pedig a Cloudflare API-token szintjén szabod (a tokenek hatóköre szűkíthető: csak Workers, csak egy zóna, csak olvasás).

Infrastructure as Code — mikor éri meg?

A wrangler-konfig maga már IaC: a bindingok, route-ok, cron-ok, limitek a repóban vannak és verziózottak. Ami nincs benne: maguknak az erőforrásoknak a létrehozása (D1, bucket, queue — 8. modul). Kis-közepes csapatnál ez néhány dokumentált parancs, és ez teljesen elég. Terraformot akkor húzz be, ha több fiókod/környezeted van, auditálható erőforrás-életciklus kell, vagy a Cloudflare-en kívüli infrád is Terraformmal megy — a provider támogatja a Workerst, assetekkel együtt. Van emellett automatic provisioning is: a wrangler deploykor felajánlja a hiányzó erőforrások létrehozását — kényelmes fejlesztéshez, de éles környezetben inkább explicit legyen minden.

11.10Napi menü — cheatsheet

HelyzetParancs
fejleszteknpm run dev (wrangler dev / vite dev)
új binding került a configbanpx wrangler types
tesztek watch módbannpx vitest
lokális DB újratöltésenpm run db:reset && npm run db:seed
cron kipróbálásawrangler dev --test-scheduled + curl "…/__scheduled?cron=..."
webhook tesztelése kívülrőlwrangler dev --tunnel
séma-változás stagingrewrangler d1 migrations apply app-staging --env staging --remote
„mi történik most élesben?"wrangler tail --env production --status error
„mi fut most élesben?"wrangler deployments list --env production
gyors éles lekérdezéswrangler d1 execute app-prod --remote --command "…" --json
ég a házwrangler rollback --env production

11.11Ellenőrizd magad

  1. Miért kisebb a „lokálisan ment, élesben nem" kockázat, mint a Node+Lambda világban — és mit nem fed le mégsem a lokális futtatás?
    Válasz

    Mert a wrangler dev ugyanazt a workerd runtime-ot futtatja, ami élesben is fut — nem egy másik környezetet szimulál. Nem fedi le viszont: a valódi hálózati/földrajzi viselkedést, az éles adat furcsaságait, és a limiteket (a CPU-limit lokálisan nem érvényesül) — ezekre való a staging és a preview URL.

  2. Mit jelent a remote: true egy bindingon, és miben más ez, mint a wrangler dev --remote?
    Válasz

    A remote: true esetén a kód továbbra is lokálisan fut, csak az adott binding műveletei mennek a valódi (deployolt) erőforrásra — gyors hurok, valódi adat. A --remote ezzel szemben az egész Workert feltölti és a Cloudflare-en futtatja: minden binding éles, de minden változtatás új feltöltéssel jár, tehát lassú.

  3. Miért nem kell mockolni a D1-t vagy az R2-t a tesztekben?
    Válasz

    Mert a Vitest-integrációval a tesztek maguk is a workerd-ben futnak, és közvetlen hozzáférésük van a bindingokhoz (izolált, teszt-fájlonkénti tárolással). A teszt így a valódi API-t hívja, nem egy mock viselkedését ellenőrzi.

  4. Egy Durable Object 10 perces alarmját kell tesztelned. Hogyan csinálod anélkül, hogy 10 percet várnál?
    Válasz

    runDurableObjectAlarm(stub) — azonnal lefuttatja a beütemezett alarmot. Ha a memória-vesztés utáni viselkedést is ellenőrzöd, evictDurableObject(stub)-bal szimulálod a kilakoltatást, a belső állapotot pedig runInDurableObject()-tel nézed meg.

  5. Új fejlesztő érkezik. Sorold fel, mi kell neki az első futó dev-környezethez — és mi az, ami a régi világból elmarad.
    Válasz

    Kell: repo-klón, npm i, wrangler login, .dev.vars a titkokkal, seed + dev script. Elmarad: AWS-konzol-hozzáférés, VPN, dev-adatbázis jelszó, IAM-szerepkör — a lokális bindingok szimuláltak, tehát senki nem nyúl éles erőforráshoz az első napján.

  6. Mikor van szükséged Terraformra a wrangler-konfig mellett?
    Válasz

    Ha több fiók/környezet auditálható erőforrás-életciklusa kell, vagy a Cloudflare-en kívüli infrád is Terraformmal megy. A wrangler-konfig maga már verziózza a bindingokat, route-okat, cronokat; a hiányzó rész csak az erőforrások létrehozása, ami kis csapatnál pár dokumentált parancs.

Előző10. modul — Migrációs stratégia: a te stacked átállítása Következő 12. modul — A wrangler konfigurációs fájl: teljes referencia