소스 정보
- 저장소
- tools-only/X-Skills
- 최근 소스 활동
- 2026년 3월 1일 03:37
- 감지된 SKILL.md 언어
- 영어
- 스타
- 7
- 포크
- 1
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
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)