用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/tools-only/X-Skills --skill infrastructure-cloudflare-workers命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Index of Build Systems Skills
Coordination patterns for distributed dataflow systems including barriers, epochs, and distributed snapshots
Windowing, sessionization, time-series aggregation, and late data handling for streaming systems
基于 SOC 职业分类
正在显示 SKILL.md
| name | infrastructure-cloudflare-workers |
| description | Building serverless APIs at the edge (low latency globally) |
Scope: Edge computing with Cloudflare Workers - Edge functions, KV storage, Durable Objects, R2 Lines: 365 Last Updated: 2025-10-18 Format Version: 1.0 (Atomic)
Activate when:
Prerequisites:
npm install -g wrangler)Common scenarios:
// src/index.js - Simple worker
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
// Simple routing
if (url.pathname === '/api/hello') {
return new Response(JSON.stringify({
message: 'Hello from the edge!',
location: request.cf.city,
country: request.cf.country
}), {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
}
});
}
// 404 response
return new Response('Not Found', { status: 404 });
}
};
# wrangler.toml
name = "my-worker"
main = "src/index.js"
compatibility_date = "2024-01-01"
# Environment variables
[vars]
ENVIRONMENT = "production"
API_VERSION = "v1"
# KV Namespace bindings
[[kv_namespaces]]
binding = "CACHE"
id = "abcdef1234567890abcdef1234567890"
# Durable Object bindings
[[durable_objects.bindings]]
name = "COUNTER"
class_name = "Counter"
# R2 bucket bindings
[[r2_buckets]]
binding = "ASSETS"
bucket_name = "my-assets"
# Secrets (set with: wrangler secret put SECRET_NAME)
# Access via env.SECRET_NAME
# Routes (custom domain)
[[routes]]
pattern = "api.example.com/*"
zone_name = "example.com"
# Workers for Platforms (optional)
[dispatch_namespaces]
binding = "DISPATCHER"
namespace = "my-namespace"
// src/index.ts - TypeScript worker
interface Env {
CACHE: KVNamespace;
API_KEY: string;
ENVIRONMENT: string;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
// CORS handling
if (request.method === 'OPTIONS') {
return handleCORS();
}
// Authentication
const apiKey = request.headers.get('X-API-Key');
if (apiKey !== env.API_KEY) {
return new Response('Unauthorized', { status: 401 });
}
// Route handling
switch (url.pathname) {
case '/api/data':
return handleData(request, env, ctx);
:
(request, env);
:
(, { : });
}
}
};
(): {
(, {
: {
: ,
: ,
: ,
: ,
}
});
}
(): <> {
cacheKey = (request.).;
cached = env..(cacheKey, );
(cached) {
.(cached, {
: { : }
});
}
data = ();
ctx.(
env..(cacheKey, .(data), {
:
})
);
.(data, {
: { : }
});
}
() {
response = ();
response.();
}
// KV operations
interface Env {
CACHE: KVNamespace;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const key = url.searchParams.get('key');
if (request.method === 'GET') {
// Get value
const value = await env.CACHE.get(key);
if (!value) {
return new Response('Not Found', { status: 404 });
}
return new Response(value);
}
if (request.method === 'POST') {
// Put value with expiration
const value = await request.text();
await env.CACHE.put(key, value, {
expirationTtl: ,
: { : .() }
});
(, { : });
}
(request. === ) {
env..(key);
(, { : });
}
(url. === ) {
prefix = url..() || ;
list = env..({ prefix, : });
.(list.);
}
(, { : });
}
};
// src/counter.ts - Durable Object
export class Counter {
state: DurableObjectState;
value: number;
constructor(state: DurableObjectState, env: Env) {
this.state = state;
this.value = 0;
}
async initialize() {
// Load state from storage
const stored = await this.state.storage.get('value');
this.value = stored || 0;
}
async fetch(request: Request): Promise<Response> {
await this.initialize();
const url = new URL(request.url);
if (url.pathname === '/increment') {
this.value++;
await ...(, .);
.({ : . });
}
(url. === ) {
.--;
...(, .);
.({ : . });
}
(url. === ) {
.({ : . });
}
(, { : });
}
}
{ } ;
{
: ;
}
{
(: , : ): <> {
id = env..();
stub = env..(id);
stub.(request);
}
};
// R2 bucket operations
interface Env {
ASSETS: R2Bucket;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const key = url.pathname.slice(1); // Remove leading /
if (request.method === 'GET') {
// Get object
const object = await env.ASSETS.get(key);
if (!object) {
return new Response('Not Found', { status: 404 });
}
const headers = new Headers();
object.writeHttpMetadata(headers);
headers.set('etag', object.httpEtag);
return new Response(., { headers });
}
(request. === ) {
env..(key, request., {
: {
: request..() || ,
},
: {
: ,
: ().(),
}
});
(, { : });
}
(request. === ) {
env..(key);
(, { : });
}
(, { : });
}
};
// Cache API with edge caching
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const cache = caches.default;
// Try to get from cache
let response = await cache.match(request);
if (response) {
return response;
}
// Fetch from origin
response = await fetch(request);
// Cache successful responses
if (response.ok) {
const responseToCache = response.clone();
ctx.waitUntil(cache.put(request, responseToCache));
}
return response;
}
};
// Rewrite requests to different origins
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
// API proxy
if (url.pathname.startsWith('/api/')) {
url.hostname = 'api.backend.com';
url.pathname = url.pathname.replace('/api/', '/v1/');
const modifiedRequest = new Request(url.toString(), {
method: request.method,
headers: request.headers,
body: request.body,
});
return fetch(modifiedRequest);
}
// Default to static assets
url.hostname = 'static.example.com';
return fetch(url.toString());
}
};
// A/B testing with cookie-based variants
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
// Check for existing variant cookie
let variant = getCookie(request, 'ab_variant');
if (!variant) {
// Assign random variant
variant = Math.random() < 0.5 ? 'A' : 'B';
}
// Fetch variant-specific content
const response = await fetch(`https://origin.com/${variant}${url.pathname}`);
// Set variant cookie
const newResponse = new Response(response.body, response);
newResponse.headers.set('Set-Cookie', `ab_variant=${variant}; Path=/; Max-Age=86400`);
return newResponse;
}
};
function getCookie(request: Request, name: string): string | {
cookies = request..();
(!cookies) ;
cookie = cookies.().( c.().());
cookie ? cookie.()[] : ;
}
// Rate limiting with Durable Objects
export class RateLimiter {
state: DurableObjectState;
requests: Map<string, number[]>;
constructor(state: DurableObjectState) {
this.state = state;
this.requests = new Map();
}
async fetch(request: Request): Promise<Response> {
const clientId = request.headers.get('CF-Connecting-IP') || 'unknown';
const now = Date.now();
const windowMs = 60000; // 1 minute
const maxRequests = 100;
// Get request timestamps for this client
let timestamps = this.requests.get(clientId) || [];
// Remove old timestamps outside window
timestamps = timestamps.filter(ts => now - ts < windowMs);
// Check if limit exceeded
(timestamps. >= maxRequests) {
(, {
: ,
: {
:
}
});
}
timestamps.(now);
..(clientId, timestamps);
.({
: ,
: maxRequests - timestamps.
});
}
}
// Image transformation
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
// Parse resize parameters
const width = parseInt(url.searchParams.get('width') || '800');
const quality = parseInt(url.searchParams.get('quality') || '85');
const format = url.searchParams.get('format') || 'auto';
// Fetch original image
const imageUrl = url.searchParams.get('url');
if (!imageUrl) {
return new Response('Missing url parameter', { status: 400 });
}
const response = await fetch(imageUrl);
// Transform with Cloudflare Image Resizing
return new Response(response.body, {
: {
: ,
: ,
: width.(),
: quality.(),
: format,
}
});
}
};
# Development
wrangler dev # Local development server
wrangler dev --remote # Remote development (actual edge)
# Deployment
wrangler deploy # Deploy to production
wrangler deploy --env staging # Deploy to staging
# KV operations
wrangler kv:namespace create "CACHE"
wrangler kv:key put --binding=CACHE "key" "value"
wrangler kv:key get --binding=CACHE "key"
wrangler kv:key delete --binding=CACHE "key"
wrangler kv:key list --binding=CACHE
# R2 operations
wrangler r2 bucket create my-bucket
wrangler r2 object put my-bucket/file.txt --file=./file.txt
wrangler r2 object get my-bucket/file.txt
# Secrets
wrangler secret put API_KEY
wrangler secret delete API_KEY
wrangler secret list
# Logs
wrangler tail # Stream logs
wrangler tail --format=pretty
# Account info
wrangler whoami
wrangler deployments list
CPU Time: 10ms (free), 30s (paid) per request
Memory: 128 MB
Subrequest limit: 50 (free), 1000 (paid)
Script size: 1 MB (free), 10 MB (paid)
KV read: 100,000/day (free), unlimited (paid)
KV write: 1,000/day (free), unlimited (paid)
Durable Objects: Paid feature only
R2 storage: 10 GB (free), unlimited (paid)
// ❌ NEVER: Store secrets in code
const API_KEY = "sk-1234567890abcdef"; // NEVER
// ✅ CORRECT: Use environment bindings
interface Env {
API_KEY: string; // Set with: wrangler secret put API_KEY
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.headers.get('X-API-Key') !== env.API_KEY) {
return new Response('Unauthorized', { status: 401 });
}
// ...
}
};
// ❌ NEVER: Perform blocking operations
export default {
async fetch(request: Request): Promise<Response> {
// CPU-intensive synchronous work
let result = 0;
for (let i = 0; i < 1000000000; i++) { // Will hit CPU limit
result += i;
}
return Response.json({ result });
}
};
// ✅ CORRECT: Use Durable Objects for stateful work
// Or offload to origin API for heavy computation
// ❌ NEVER: Use global state
let counter = 0; // Not shared across requests!
export default {
async fetch(request: Request): Promise<Response> {
counter++; // Each request gets own isolate
return Response.json({ counter }); // Always 1
}
};
// ✅ CORRECT: Use KV or Durable Objects
interface Env {
CACHE: KVNamespace;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const counter = parseInt(await env.CACHE.get('counter') || '0');
await env.CACHE.put('counter', (counter + 1).toString());
return Response.json({ counter: counter + 1 });
}
};
// ❌ Don't forget CORS headers
export default {
async fetch(request: Request): Promise<Response> {
return Response.json({ data: 'value' });
// Browser will block cross-origin requests
}
};
// ✅ CORRECT: Add CORS headers
export default {
async fetch(request: Request): Promise<Response> {
const headers = {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
};
return Response.json({ data: 'value' }, { headers });
}
};
Infrastructure:
aws-serverless.md - Alternative serverless platform (Lambda, API Gateway)infrastructure-security.md - Authentication, authorization patternscost-optimization.md - Workers pricing, caching strategiesDevelopment:
modal-functions-basics.md - Python-focused serverless alternativeterraform-patterns.md - Infrastructure as Code for Cloudflare resourcesStandards from CLAUDE.md:
wrangler secret putLast Updated: 2025-10-18 Format Version: 1.0 (Atomic)