
【免费下载链接】autoskillsOne command. Your entire AI skill stack. Installed.项目地址https://gitcode.com/gh_mirrors/au/autoskills点击查看免费下载Miniflare 是 Cloudflare Workers 的本地模拟器在 workerd 沙箱中运行 Worker 并实现全部运行时 API全程无需联网。本文以 packages/autoskills/skills-registry/cloudflare-deploy/references/miniflare/ 下 README、configuration、patterns、gotchas、api 五份文档为骨架结合本仓库 cloudflare-deploy 技能 的定位完整讲解 Miniflare 的选型决策、安装启动、绑定配置、测试模式、程序化 API 与排障清单读完即可在本地对 KV、Durable Objects、R2、D1、Queues、WebSocket 等能力做全功能验证并直接把测试流程接入 Vitest/Jest 与 CI/CD。Miniflare 是什么为 Workers 打造的本地运行时模拟器Miniflare 是面向 Cloudflare Workers 开发与测试的本地模拟器它在workerd 沙箱中运行你的 Worker并实现 Workers 运行时 API不需要互联网连接即可完成开发与测试。从本仓库的关联文档miniflare/README.md可以看到它的能力定位功能齐全支持 KV、Durable Objects、R2、D1、WebSockets、Queues 等核心绑定完全本地无需联网即可测试支持即时重载TypeScript 原生提供详细日志与 source map高级测试可不经 HTTP 直接派发事件dispatch events模拟 Worker 之间的连接。在仓库的技能体系中Miniflare 隶属于 cloudflare-deploy 技能下的 Developer Tools 参考模块与 wranglerCLI 工具其wrangler dev内部即嵌入 Miniflare、workerd驱动 Miniflare 的运行时三者形成CLI → 模拟器 → 运行时的完整链路。何时使用 Miniflare测试方案决策树针对需要测试 Workers 吗这一问题文档给出了一棵清晰的决策树用于在单元测试、集成测试与本地开发之间做出选择Need to test Workers? │ ├─ Unit tests for business logic only? │ └─ getPlatformProxy (Vitest/Jest) → patterns.md#getplatformproxy │ Fast, no HTTP, direct binding access │ ├─ Integration tests with full runtime? │ ├─ Single Worker? │ │ └─ Miniflare API → Quick Start │ │ Full control, programmatic access │ │ │ ├─ Multiple Workers service bindings? │ │ └─ Miniflare workers array → configuration.md#multiple-workers │ │ Shared storage, inter-worker calls │ │ │ └─ Vitest test runner integration? │ └─ vitest-pool-workers → patterns.md#vitest-pool-workers │ Full Workers env in Vitest │ └─ Local dev server? └─ wrangler dev (not Miniflare) Hot reload, automatic config三种工具的适用边界总结如下场景推荐方案理由业务逻辑单元测试getPlatformProxy快、无 HTTP 开销、直接访问绑定适合 Vitest/Jest 环境带完整运行时语义的集成测试Miniflare API完全控制、程序化访问、可派发 fetch/queue/scheduled 事件本地开发与生产部署Wranglerwrangler dev热重载、自动读取配置、wrangler deploy上线用 Miniflare 做集成测试、绑定与本地存储测试、带 service bindings 的多 Worker 测试、程序化事件派发。用 getPlatformProxy 做快速业务逻辑单元测试、无 HTTP 开销的测试。用 Wrangler 做本地开发工作流、生产部署。安装与快速上手安装为开发依赖对应 miniflare/README.md 的 Setup 一节npm i -D miniflareMiniflare 基于 ES modules 运行需要在package.json中声明{type: module}快速启动一个最小 Worker两分钟跑通import { Miniflare } from miniflare; const mf new Miniflare({ modules: true, script: export default { async fetch(request, env, ctx) { return new Response(Hello Miniflare!); } } , }); const res await mf.dispatchFetch(http://localhost:8787/); console.log(await res.text()); // Hello Miniflare! await mf.dispose();要点modules: true表示以 ES modules 语法加载内联脚本dispatchFetch直接派发 fetch 事件而不需要启动 HTTP 服务器dispose()负责释放资源测试中务必在清理阶段调用对应 miniflare/gotchas.md 的最佳实践。配置详解脚本加载、兼容性与各类绑定脚本加载的三种方式configuration.md 给出了内联、文件与多模块三种加载方式// 内联脚本 new Miniflare({ modules: true, script: export default { ... } }); // 文件方式 new Miniflare({ scriptPath: worker.js }); // 多模块按规则分类加载 new Miniflare({ scriptPath: src/index.js, modules: true, modulesRules: [ { type: ESModule, include: [**/*.js] }, { type: Text, include: [**/*.txt] }, ], });modulesRules中的type可取值包括ESModule编译执行、Text作为文本资源导入、Data二进制数据等include为匹配的文件 glob。多模块模式用于 Worker 依赖多个资源文件如模板、静态文本的场景。compatibilityDate 与 compatibilityFlags兼容性配置直接决定可用 API 的范围是本地模拟与生产保持一致的关键new Miniflare({ compatibilityDate: 2026-01-01, // 使用较新日期以启用最新特性 compatibilityFlags: [ nodejs_compat, // 启用 Node.js APIprocess、Buffer 等 streams_enable_constructors, // 启用 Stream 构造函数 ], upstream: https://example.com, // 未处理请求的回退目标 });文档特别强调必须使用compatibilityDate: 2026-01-01或最新日期以匹配生产运行时过旧的日期会限制可用 API。这与 workerd 的Compatibility date: Feature gate (always set!)理念一脉相承——兼容性日期是 Workers 生态中恒定的功能开关机制。HTTP 服务器与 Request.cfnew Miniflare({ port: 8787, // 默认8787 host: 127.0.0.1, https: true, // 自签名证书 liveReload: true, // HTML 自动重载 cf: true, // 获取实时 Request.cf 数据带缓存 // cf: ./cf.json, // 或从文件加载 // cf: { colo: DFW }, // 或内联 mock });注意测试场景请用dispatchFetch()不要启动 HTTP 服务器这样可以避免端口冲突详见下文排障章节的 EADDRINUSE 问题。Request.cf对象在本地是缓存/模拟的并非真实的边缘数据——这是与生产环境的行为差异之一。存储类绑定KV / R2 / Durable Objects / D1 / Cachenew Miniflare({ // KV kvNamespaces: [TEST_NAMESPACE, CACHE], kvPersist: ./kv-data, // 可选持久化到磁盘 // R2 r2Buckets: [BUCKET, IMAGES], r2Persist: ./r2-data, // Durable Objects modules: true, durableObjects: { COUNTER: Counter, // className API_OBJECT: { className: ApiObject, scriptName: api-worker }, }, durableObjectsPersist: ./do-data, // D1 d1Databases: [DB], d1Persist: ./d1-data, // Cache cache: true, // 默认开启 cachePersist: ./cache-data, });绑定说明KVkvNamespaces传入绑定名数组kvPersist指向目录而非文件写成文件路径会导致数据不持久化详见排障章节R2r2Buckets声明桶r2Persist磁盘持久化Durable Objects对象值既可以是字符串Counter表示 className也可以是{ className, scriptName }对象——scriptName用于引用多 Worker 配置中其他 Worker 导出的类D1d1Databases声明数据库持久化选项同理Cache默认开启可关闭或持久化。关于各类存储的选型可结合 bindings/patterns.md 的指引KV 适合读多写少、全局分布、可接受最终一致性的场景D1 适合关系型数据与 JOINR2 适合大对象文件Durable Objects 适合强一致性与实时协调。普通绑定环境变量、Wasm、文本、队列生产者new Miniflare({ // 环境变量 bindings: { SECRET_KEY: my-secret-value, API_URL: https://api.example.com, DEBUG: true, }, // 其他绑定 wasmBindings: { ADD_MODULE: ./add.wasm }, textBlobBindings: { TEXT: ./data.txt }, queueProducers: [QUEUE], });bindings对象中的值会直接注入 Worker 的envwasmBindings注册 WebAssembly 模块textBlobBindings注册文本资源queueProducers声明队列生产者绑定。注意生产环境中敏感信息应通过wrangler secret put注入见 bindings/patterns.md 的 Secrets 章节本地测试用bindings模拟即可。多 Worker 与 service bindings使用workers数组可以模拟多 Worker 拓扑并实现共享存储与 Worker 间调用new Miniflare({ workers: [ { name: main, kvNamespaces: { DATA: shared }, serviceBindings: { API: api-worker }, script: export default { ... }, }, { name: api-worker, kvNamespaces: { DATA: shared }, // 共享存储 script: export default { ... }, }, ], });带路由的多 Workerworkers: [ { name: api, scriptPath: ./api.js, routes: [api.example.com/*] }, { name: web, scriptPath: ./web.js, routes: [example.com/*] }, ],多 Worker 模式下kvNamespaces的键是绑定名、值是存储名同名存储即实现跨 Worker 共享。service bindings 的调用语义可参考 bindings/patterns.md绑定调用忽略 hostname/protocol路由只依据绑定名且在同一 isolate 内零延迟。日志、性能与 Workers Sitesimport { Log, LogLevel } from miniflare; new Miniflare({ log: new Log(LogLevel.DEBUG), // DEBUG | INFO | WARN | ERROR | NONE scriptTimeout: 30000, // CPU 时间上限毫秒 workersConcurrencyLimit: 10, // 最大并发 Worker 数 });静态站点Workers Sitesnew Miniflare({ sitePath: ./public, siteInclude: [**/*.html, **/*.css], siteExclude: [**/*.map], });从 wrangler.toml 迁移配置Miniflare 不会自动读取wrangler.toml需要手动翻译配置# wrangler.toml name my-worker main src/index.ts compatibility_date 2026-01-01 [[kv_namespaces]] binding KV// Miniflare 等价配置 new Miniflare({ scriptPath: src/index.ts, compatibilityDate: 2026-01-01, kvNamespaces: [KV], });这一限制在 gotchas.md 的迁移指南中被再次强调从wrangler dev迁移到 Miniflare API 时需把wrangler.toml中的 main、compatibility_date、bindings 逐项翻译为构造参数。测试模式getPlatformProxy、vitest-pool-workers 与 Miniflare APIpatterns.md 给出三种测试方案的横向对比方案适用场景速度配置成本运行时getPlatformProxy单元测试、逻辑测试快低MiniflareMiniflare API集成测试、完全控制中中Miniflarevitest-pool-workersVitest 运行器集成中中workerd快速指南单元测试 → getPlatformProxy集成测试 → Miniflare APIVitest 工作流 → vitest-pool-workers。getPlatformProxy轻量单元测试在不启动完整 Worker 运行时的情况下提供绑定访问// vitest.config.js export default { test: { environment: node } };import { env } from cloudflare:test; import { describe, it, expect } from vitest; describe(Business logic, () { it(processes data with KV, async () { await env.KV.put(test, value); expect(await env.KV.get(test)).toBe(value); }); });优点快、简单缺点没有完整运行时无法测试 fetch handler。vitest-pool-workersVitest 中的完整 Workers 运行时读取wrangler.toml并跑在真正的 workerd 上npm i -D cloudflare/vitest-pool-workers// vitest.config.js import { defineWorkersConfig } from cloudflare/vitest-pool-workers/config; export default defineWorkersConfig({ test: { poolOptions: { workers: { wrangler: { configPath: ./wrangler.toml } } }, }, });import { env, SELF } from cloudflare:test; import { it, expect } from vitest; it(handles fetch, async () { const res await SELF.fetch(http://example.com/); expect(res.status).toBe(200); });优点完整运行时、使用wrangler.toml缺点依赖 Wrangler 配置。Miniflare API node:testNode 内置测试运行器与 Miniflare 的组合import assert from node:assert; import test, { after, before } from node:test; import { Miniflare } from miniflare; let mf; before(() { mf new Miniflare({ scriptPath: src/index.js, kvNamespaces: [TEST_KV] }); }); test(fetch, async () { const res await mf.dispatchFetch(http://localhost/); assert.strictEqual(await res.text(), Hello); }); after(() mf.dispose());测试 Durable Objects、队列与定时事件Miniflare 支持对各类事件进行程序化派发详见 api.md 的 Event Dispatching 一节// Durable Objects const ns await mf.getDurableObjectNamespace(COUNTER); const stub ns.get(ns.idFromName(test-counter)); await stub.fetch(http://localhost/increment); // 直接访问 DO 存储 const storage await mf.getDurableObjectStorage(ns.idFromName(test-counter)); const count await storage.get(count); // 队列事件 const worker await mf.getWorker(); await worker.queue(my-queue, [ { id: msg1, timestamp: new Date(), body: { userId: 123 }, attempts: 1 }, ]); // 定时cron事件 await worker.scheduled({ cron: 0 0 * * * });测试隔离与 Mock 外部 API// 每个测试独立实例保证隔离 beforeEach(() { mf new Miniflare({ kvNamespaces: [TEST] }); }); afterEach(() mf.dispose()); // 用第二个 Worker mock 外部 API new Miniflare({ workers: [ { name: main, serviceBindings: { API: mock-api }, script: ... }, { name: mock-api, script: export default { async fetch() { return Response.json({mock: true}); } } }, ], });类型安全的绑定访问通过泛型getBindingsEnv()让绑定访问具备完整类型提示import type { KVNamespace } from cloudflare/workers-types; interface Env { KV: KVNamespace; API_KEY: string; } const env await mf.getBindingsEnv(); await env.KV.put(key, value); // Typed! export default { async fetch(req: Request, env: Env) { return new Response(await env.KV.get(key)); } } satisfies ExportedHandlerEnv;WebSocket 测试const res await mf.dispatchFetch(http://localhost/ws, { headers: { Upgrade: websocket }, }); assert.strictEqual(res.status, 101);从 unstable_dev 迁移unstable_dev已被弃用官方推荐直接使用 Miniflare// 旧已弃用 import { unstable_dev } from wrangler; const worker await unstable_dev(src/index.ts); // 新 import { Miniflare } from miniflare; const mf new Miniflare({ scriptPath: src/index.ts });CI/CD 注意事项// 内存存储更快不传 persist 选项即为内存模式 new Miniflare({ kvNamespaces: [TEST] }); // No persist in-memory // 使用 dispatchFetch 避免端口冲突 await mf.dispatchFetch(http://localhost/);CI 场景推荐内存存储更快、无磁盘残留与dispatchFetch无需分配端口。程序化 APIMiniflare 类的完整方法参考api.md 给出了Miniflare类的完整类型签名class Miniflare { constructor(options: MiniflareOptions); // 生命周期 ready: PromiseURL; // 服务器就绪后解析返回 URL dispose(): Promisevoid; // 清理资源 setOptions(options: MiniflareOptions): Promisevoid; // 重载配置 // 事件派发 dispatchFetch(url: string | URL | Request, init?: RequestInit): PromiseResponse; getWorker(name?: string): PromiseWorker; // 绑定访问 getBindingsBindings Recordstring, unknown(name?: string): PromiseBindings; getCf(name?: string): PromiseIncomingRequestCfProperties | undefined; getKVNamespace(name: string): PromiseKVNamespace; getR2Bucket(name: string): PromiseR2Bucket; getDurableObjectNamespace(name: string): PromiseDurableObjectNamespace; getDurableObjectStorage(id: DurableObjectId): PromiseDurableObjectStorage; getD1Database(name: string): PromiseD1Database; getCaches(): PromiseCacheStorage; getQueueProducer(name: string): PromiseQueueProducer; // 调试 getInspectorURL(): PromiseURL; // Chrome DevTools inspector URL }事件派发详解fetch无需 HTTP 服务器const res await mf.dispatchFetch(http://localhost:8787/path, { method: POST, headers: { Authorization: Bearer token }, body: JSON.stringify({ data: value }), });自定义 Host 路由用于多路由 Worker 场景const res await mf.dispatchFetch(http://localhost:8787/, { headers: { Host: api.example.com }, });scheduled 事件const worker await mf.getWorker(); const result await worker.scheduled({ cron: 30 * * * * }); // result: { outcome: ok, noRetry: false }queue 事件const worker await mf.getWorker(); const result await worker.queue(queue-name, [ { id: msg1, timestamp: new Date(), body: data, attempts: 1 }, ]); // result: { outcome: ok, retryAll: false, ackAll: false, ... }各绑定的程序化访问环境变量与类型安全const bindings await mf.getBindings(); console.log(bindings.SECRET_KEY); // 推荐泛型类型安全 interface Env { SECRET_KEY: string; API_URL: string; KV: KVNamespace; } const env await mf.getBindingsEnv(); env.SECRET_KEY; // string (typed!) env.KV.get(key); // KVNamespace methods availableRequest.cfconst cf await mf.getCf(); console.log(cf?.colo); // DFW console.log(cf?.country); // USKVconst ns await mf.getKVNamespace(TEST_NAMESPACE); await ns.put(key, value); const value await ns.get(key);R2const bucket await mf.getR2Bucket(BUCKET); await bucket.put(file.txt, content); const object await bucket.get(file.txt);Durable Objects 与直接存储const ns await mf.getDurableObjectNamespace(COUNTER); const id ns.idFromName(test); const stub ns.get(id); const res await stub.fetch(http://localhost/); // 直接访问存储 const storage await mf.getDurableObjectStorage(id); await storage.put(key, value);D1const db await mf.getD1Database(DB); await db.exec(CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)); await db.prepare(INSERT INTO users (name) VALUES (?)).bind(Alice).run();Cache 与队列生产者const caches await mf.getCaches(); const defaultCache caches.default; await defaultCache.put(http://example.com, new Response(cached)); const producer await mf.getQueueProducer(QUEUE); await producer.send({ body: message data });生命周期管理重载配置await mf.setOptions({ scriptPath: worker.js, bindings: { VERSION: 2.0 }, });手动文件监听重载模拟热更新import { watch } from fs; const config { scriptPath: worker.js }; const mf new Miniflare(config); watch(worker.js, async () { console.log(Reloading...); await mf.setOptions(config); });清理await mf.dispose();调试与就绪等待Chrome DevTools inspectorconst url await mf.getInspectorURL(); console.log(DevTools: ${url}); // 在 Chrome DevTools 中打开用于断点与性能分析等待服务器就绪const mf new Miniflare({ scriptPath: worker.js }); const url await mf.ready; // PromiseURL console.log(Server running at ${url}); // http://127.0.0.1:8787 // 注意dispatchFetch() 会自动等待无需手动 await ready const res await mf.dispatchFetch(http://localhost/); // 立即生效常见坑与排障指南Miniflare 的已知限制不支持的平台能力gotchas.mdAnalytics Engine改用 mockCloudflare Images / StreamBrowser Rendering APITail WorkersWorkers for Platforms部分支持与生产环境的行为差异本地运行 workerd而非 Cloudflare 边缘存储是本地的文件系统/内存非分布式Request.cf是缓存/模拟数据非真实边缘数据性能表现与边缘不同缓存实现可能略有差异。高频错误与解决方案Cannot find module原因模块路径错误或modulesRules未配置。解决new Miniflare({ modules: true, modulesRules: [{ type: ESModule, include: [**/*.js] }], });Data not persisting数据不持久化原因persist 路径被写成文件而非目录。解决kvPersist: ./data/kv, // 必须是目录不是文件Cannot run TypeScript无法运行 TypeScript原因Miniflare 不负责转译 TypeScript。解决先用 esbuild/tsc 构建再运行编译后的 JS。request.cfis undefined原因CF 数据未配置。解决new Miniflare({ cf: true }); // 或 cf: ./cf.jsonEADDRINUSE 端口冲突原因多个实例使用同一端口。解决使用dispatchFetch()不启动 HTTP 服务器或port: 0自动分配端口。Durable Object not found原因类导出名与配置名不匹配。解决export class Counter {} // 必须与配置一致 new Miniflare({ durableObjects: { COUNTER: Counter } });调试三板斧启用详细日志import { Log, LogLevel } from miniflare; new Miniflare({ log: new Log(LogLevel.DEBUG) });Chrome DevTools 断点调试const url await mf.getInspectorURL(); console.log(DevTools: ${url}); // 在 Chrome 中打开检查绑定与存储const env await mf.getBindings(); console.log(Object.keys(env)); const ns await mf.getKVNamespace(TEST); const { keys } await ns.list();最佳实践清单✓ 应该做测试用dispatchFetch()不启动 HTTP 服务器CI 中使用内存存储省略 persist 选项每个测试新建独立实例以保证隔离用 interface 实现类型安全的绑定清理阶段await mf.dispose()。✗ 避免测试中启动 HTTP 服务器共享实例却不做清理使用过旧的兼容性日期应使用 2026 年及以后。资源限制速查限制项值说明CPU 时间默认 30s可通过scriptTimeout配置存储文件系统性能随磁盘而异内存取决于系统无人工限制Request.cf缓存/模拟非真实边缘数据版本迁移指南从 Miniflare 2.x 迁移到 3的破坏性变更v2v3getBindings()同步getBindings()返回 Promiseready为 voidready返回PromiseURLservice-worker-mock基于 workerd 构建选项结构不同构造函数重构// v2 const bindings mf.getBindings(); mf.ready; // void // v3 const bindings await mf.getBindings(); const url await mf.ready; // PromiseURL从 unstable_dev 迁移直接用new Miniflare({ scriptPath })替换unstable_dev(path)。从 Wrangler Dev 迁移手动翻译wrangler.tomlMiniflare 不自动读取new Miniflare({ scriptPath: dist/worker.js, compatibilityDate: 2026-01-01, kvNamespaces: [KV], bindings: { API_KEY: process.env.API_KEY }, });与 Wrangler、workerd 的生态关系在 Cloudflare Workers 的工具链中Miniflare 处于承上启下的位置参见 wrangler/README.md 与 workerd/README.mdWranglerCloudflare 官方 CLI负责创建、开发与部署 Worker。其wrangler dev内部嵌入 Miniflare 提供本地开发服务器热重载、自动读取配置因此日常本地开发优先用wrangler dev而需要程序化控制与深度测试时才直接使用 Miniflare APIworkerd基于 V8 的 JS/Wasm 运行时是驱动 Miniflare 与wrangler dev的底层引擎实现了 Fetch API、Web Crypto、Streams、WebSocket 等标准 API。注意 workerd 不是加固的沙箱不应直接运行不可信代码这一安全边界同样适用于基于它的 Miniflare。三者合起来构成完整的开发闭环wrangler dev负责日常热开发Miniflare API 负责可编程的集成测试wrangler deploy负责最终上线而workerd是这一切的运行时底座。本仓库的 cloudflare-deploy 技能将其统一纳入开发者工具参考体系供 Agent 在部署前对 Worker 逻辑进行本地验证。阅读路径建议按 miniflare/README.md 的 Reading Order初次接触 MiniflareQuick Start - 两分钟跑通When to Use - 选对测试方案patterns.md - 测试模式getPlatformProxy、Vitest、node:testconfiguration.md - 配置绑定、存储、多 Worker排障gotchas.md - 常见错误与调试API 参考api.md - 完整方法参考相关资源wrangler嵌入 Miniflare 的 CLI、workerd驱动 Miniflare 的运行时、bindings绑定模式与最佳实践。赞分享【免费下载链接】autoskillsOne command. Your entire AI skill stack. Installed.项目地址https://gitcode.com/gh_mirrors/au/autoskills点击查看免费下载相关推荐shadPS4 怎么快速更新游戏版本Bloodborne 1.09 实测shadPS4 怎么快速更新游戏版本Bloodborne 1.09 实测 把 1.09 更新补丁丢进游戏目录后shadPS4 里 Bloodborne 仍显autoskills Cloudflare 技能库Miniflare 测试模式实战——Workers 单元测试、集成测试与事件测试全解autoskills Cloudflare 技能库Miniflare 测试模式实战——Workers 单元测试、集成测试与事件测试全解 本文围绕 autoskMiniflare 完全指南在本地 workerd 沙箱中模拟 Cloudflare Workers 测试与调试Miniflare 完全指南在本地 workerd 沙箱中模拟 Cloudflare Workers 测试与调试 Miniflare 是 Cloudflare上一篇如何快速批量下载Cyberdrop和Bunkr文件终极自动化解决方案下一篇Timecamp 自动化实战基于 Rube MCPComposio的 Claude Skill 完整使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考