Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 1c76db6

Browse files
authored
Merge pull request #4 from mrbbot/dev
Version 1.0.0
2 parents 70bc602 + f3b885a commit 1c76db6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+17386
-1334
lines changed

.gitignore

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
.tmp
55
node_modules
66
dist
7-
.env
8-
*.toml
7+
8+
# wrangler build artifacts
9+
test/fixtures/wrangler/rust/pkg
10+
test/fixtures/wrangler/rust/target
11+
test/fixtures/wrangler/rust/worker/generated
12+
test/fixtures/wrangler/webpack/worker

.prettierrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"proseWrap": "always"
3+
}

README.md

Lines changed: 80 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,106 @@
1-
# 🔥 Miniflare (WIP)
1+
# 🔥 Miniflare
22

3-
Fun, fully-local Cloudflare Workers simulator for developing and testing Workers
3+
Fun, full-featured, fully-local simulator for developing and testing Cloudflare
4+
Workers
5+
6+
**See <https://miniflare.dev> for many more details.**
47

58
## Features
69

10+
- 📨 Fetch Events (with HTTP server and manual triggering)
11+
- ⏰ Scheduled Events (with manual and cron triggering)
12+
- 🔑 Variables and Secrets with `.env` Files
13+
- 📚 Modules Support
714
- 📦 KV (with optional persistence)
815
- ✨ Cache (with optional persistence)
16+
- 📌 Durable Objects (with optional persistence)
917
- 🌐 Workers Sites
10-
- 📨 Fetch Events (with HTTP server and manual triggering)
11-
- ⏰ Scheduled Events (with manual and cron triggering)
12-
- 🔑 `.env` File Support (for secrets)
18+
- ✉️ WebSockets
19+
- 🛠 Custom & Wrangler Builds Support
20+
- ⚙️ WebAssembly Support
1321
- 🗺 Source Map Support
22+
- 🕸 Web Standards: Base64, Timers, Fetch, Encoding, URL, Streams, Crypto
23+
- 📄 HTMLRewriter
1424
- 👀 Automatic Reload on File Changes
1525
- 💪 Written in TypeScript
1626

17-
## Coming Soon
27+
## Install
1828

19-
- 📌 Durable Objects
20-
- ✉️ WebSockets
21-
- 📄 HTMLRewriter
22-
- 🛠 Custom Builds Support
23-
- ⚙️ WebAssembly Support
24-
- 🤹 Custom [Jest Environment](https://jestjs.io/docs/configuration#testenvironment-string)
25-
- ✅ More Tests
26-
27-
## CLI Usage
29+
Miniflare is installed using npm:
2830

31+
```shell
32+
$ npm install -g miniflare # either globally..
33+
$ npm install -D miniflare # ...or as a dev dependency
2934
```
30-
Usage: miniflare <script> [options]
3135

32-
Options:
33-
-h, --help Show help [boolean]
34-
-v, --version Show version number [boolean]
35-
-p, --port HTTP server port (8787 by default) [number]
36-
-d, --debug Log debug messages [boolean]
37-
-c, --wrangler-config Path to wrangler.toml [string]
38-
--wrangler-env Environment in wrangler.toml to use [string]
39-
-w, --watch Watch files for changes [boolean]
40-
-u, --upstream URL of upstream origin [string]
41-
-t, --cron Cron pattern to trigger scheduled events with [array]
42-
-k, --kv KV namespace to bind [array]
43-
--kv-persist Path to persist KV data to (omit path for default)
44-
--cache-persist Path to persist cached data to (omit path for default)
45-
-s, --site Path to serve Workers Site files from [string]
46-
--site-include Glob pattern of site files to serve [array]
47-
--site-exclude Glob pattern of site files not to serve [array]
48-
-e, --env Path to .env file [string]
49-
-b, --binding Bind variable/secret (KEY=VALUE) [array]
36+
## Using the CLI
37+
38+
```shell
39+
$ miniflare worker.js --watch --debug
40+
[mf:dbg] Options:
41+
[mf:dbg] - Scripts: worker.js
42+
[mf:dbg] Reloading worker.js...
43+
[mf:inf] Worker reloaded!
44+
[mf:dbg] Watching .env, worker.js, wrangler.toml...
45+
[mf:inf] Listening on :8787
46+
[mf:inf] - http://127.0.0.1:8787
5047
```
5148

52-
`<script>` should be a path to a pre-bundled Worker.
53-
If you're using Webpack for instance, set this to your output file.
49+
## Using the API
5450

55-
Use `--debug`/`-d` to see additional log messages including processed options and watched files. **(recommended)**
51+
```js
52+
import { Miniflare } from "miniflare";
5653

57-
Use `--wrangler-config <toml_path>`/`-c <toml_path>` to load options for KV, cache, etc from a `wrangler.toml` file. **(recommended)**
58-
You can also include an additional `[miniflare]` section for Miniflare specific configuration:
59-
60-
```toml
61-
[miniflare]
62-
upstream = "https://mrbbot.dev" # --upstream
63-
kv_persist = true # --kv-persist
64-
cache_persist = true # --cache-persist
65-
env_path = ".env" # --env
66-
port = 8787 # --port
54+
const mf = new Miniflare({
55+
script: `
56+
addEventListener("fetch", (event) => {
57+
event.respondWith(new Response("Hello Miniflare!"));
58+
});
59+
`,
60+
});
61+
const res = await mf.dispatchFetch("http://localhost:8787/");
62+
console.log(await res.text()); // Hello Miniflare!
6763
```
6864

69-
KV and cache persistence can be enabled with the `--kv-persist` and `--cache-persist` flags respectively.
70-
Including these on their own will store KV and Cache data in the `.mf` directory.
71-
Optionally, you can specify a path (e.g. `--kv-persist ./data`) to use a different location.
72-
73-
## Programmatic Usage
74-
75-
```javascript
76-
import vm from "vm";
77-
import { ConsoleLog, Miniflare, Request } from "miniflare";
78-
79-
// Loading script from file
80-
const mf = new Miniflare("./path/to/script.js", {
81-
// Some options omitted, see src/options/index.ts for the full list
82-
sourceMap: true,
83-
log: new ConsoleLog(), // Defaults to no-op logger
84-
wranglerConfigPath: "wrangler.toml",
85-
watch: true,
86-
port: 8787,
87-
upstream: "https://mrbbot.dev",
88-
crons: ["0 * * * *"],
89-
kvNamespaces: ["TEST_NAMESPACE"],
90-
kvPersist: true,
91-
cachePersist: "./data/",
92-
sitePath: "./public/",
93-
envPath: ".env",
94-
});
65+
## CLI Reference
66+
67+
```
68+
Usage: miniflare [script] [options]
9569
96-
// Loading script from string
97-
const mf = new Miniflare(
98-
new vm.Script(`
99-
addEventListener("fetch", (event) => {
100-
event.respondWith(handleRequest(event.request));
101-
event.waitUntil(Promise.resolve("Something"));
102-
});
103-
104-
async function handleRequest(request) {
105-
const value = await TEST_NAMESPACE.get("key");
106-
return new Response(\`Hello from Miniflare! key="\${value}"\`, {
107-
headers: { "content-type": "text/plain" },
108-
})
109-
}
110-
111-
addEventListener("scheduled", (event) => {
112-
event.waitUntil(Promise.resolve("Something else"));
113-
});
114-
`),
115-
{
116-
kvNamespaces: ["TEST_NAMESPACE"],
117-
log: new ConsoleLog(),
118-
}
119-
);
120-
121-
// Manipulate KV outside of worker (useful for testing)
122-
const ns = await mf.getNamespace("TEST_NAMESPACE");
123-
await ns.put("key", "testing");
124-
125-
// Manipulate cache outside of worker
126-
const cache = await mf.getCache();
127-
const cachedRes = await cache.match(new Request("http://localhost"));
128-
129-
// Dispatch fetch events and get body
130-
const res = await mf.dispatchFetch(new Request("http://localhost"));
131-
132-
const body = await res.text();
133-
console.log(body); // Hello from Miniflare! key="testing"
134-
135-
const waitUntil = await res.waitUntil();
136-
console.log(waitUntil[0]); // Something
137-
138-
// Start HTTP server
139-
mf.createServer().listen(3000);
140-
141-
// Dispatch scheduled event at specific time
142-
const waitUntil2 = await mf.dispatchScheduled(Date.now());
143-
console.log(waitUntil2[0]); // Something else
70+
Options:
71+
-h, --help Show help [boolean]
72+
-v, --version Show version number [boolean]
73+
-H, --host HTTP server host to listen on (all by default)[string]
74+
-p, --port HTTP server port (8787 by default) [number]
75+
-d, --debug Log debug messages [boolean]
76+
-c, --wrangler-config Path to wrangler.toml [string]
77+
--wrangler-env Environment in wrangler.toml to use [string]
78+
-m, --modules Enable modules [boolean]
79+
--modules-rule Modules import rule (TYPE=GLOB) [array]
80+
--build-command Command to build project [string]
81+
--build-base-path Working directory for build command [string]
82+
--build-watch-path Directory to watch for rebuilding on changes [string]
83+
-w, --watch Watch files for changes [boolean]
84+
-u, --upstream URL of upstream origin [string]
85+
-t, --cron Cron pattern to trigger scheduled events with [array]
86+
-k, --kv KV namespace to bind [array]
87+
--kv-persist Path to persist KV data to (omit path for default)
88+
--cache-persist Path to persist cached data to (omit path for default)
89+
-s, --site Path to serve Workers Site files from [string]
90+
--site-include Glob pattern of site files to serve [array]
91+
--site-exclude Glob pattern of site files not to serve [array]
92+
-o, --do Durable Object to bind (NAME=CLASS) [array]
93+
--do-persist Path to persist Durable Object data to (omit path for
94+
default)
95+
-e, --env Path to .env file [string]
96+
-b, --binding Bind variable/secret (KEY=VALUE) [array]
97+
--wasm WASM module to bind (NAME=PATH) [array]
14498
```
14599

146100
## Acknowledgements
147101

148-
Many thanks to [dollarshaveclub/cloudworker](https://github.com/dollarshaveclub/cloudworker) and [gja/cloudflare-worker-local](https://github.com/gja/cloudflare-worker-local) for inspiration.
102+
Many thanks to
103+
[dollarshaveclub/cloudworker](https://github.com/dollarshaveclub/cloudworker)
104+
and
105+
[gja/cloudflare-worker-local](https://github.com/gja/cloudflare-worker-local)
106+
for inspiration.

ava.config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ export default {
22
files: ["test/**/*.spec.ts"],
33
extensions: ["ts"],
44
require: ["ts-node/register"],
5+
timeout: "1m",
6+
nodeArguments: ["--experimental-vm-modules"],
57
};

docs/.vitepress/config.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module.exports = {
2+
title: "Miniflare",
3+
description:
4+
"Fun, full-featured, fully-local simulator for Cloudflare Workers",
5+
themeConfig: {
6+
repo: "mrbbot/miniflare",
7+
docsDir: "docs",
8+
editLinks: true,
9+
sidebar: [
10+
{
11+
text: "Getting Started",
12+
children: [
13+
{ text: "🔥 Miniflare", link: "/" },
14+
{ text: "💻 Using the CLI", link: "/cli.html" },
15+
{ text: "🧰 Using the API", link: "/api.html" },
16+
// { text: "🚧 Changelog", link: "/changelog.html" },
17+
],
18+
},
19+
{
20+
text: "Guide",
21+
children: [
22+
{ text: "📨 Fetch Events", link: "/fetch.html" },
23+
{ text: "⏰ Scheduled Events", link: "/scheduled.html" },
24+
{ text: "🔑 Variables and Secrets", link: "/variables-secrets.html" },
25+
{ text: "📚 Modules", link: "/modules.html" },
26+
{ text: "📦 KV", link: "/kv.html" },
27+
{ text: "✨ Cache", link: "/cache.html" },
28+
{ text: "📌 Durable Objects", link: "/durable-objects.html" },
29+
{ text: "🌐 Workers Sites", link: "/sites.html" },
30+
{ text: "✉️ WebSockets", link: "/web-sockets.html" },
31+
{ text: "🛠 Builds", link: "/builds.html" },
32+
{ text: "⚙️ WebAssembly", link: "/web-assembly.html" },
33+
{ text: "🗺 Source Maps", link: "/source-maps.html" },
34+
{ text: "🕸 Web Standards", link: "/standards.html" },
35+
{ text: "📄 HTMLRewriter", link: "/html-rewriter.html" },
36+
],
37+
},
38+
{
39+
text: "Recipes",
40+
children: [
41+
{
42+
text: "⚡️ Developing with esbuild",
43+
link: "/recipes/esbuild.html",
44+
},
45+
{ text: "✅ Testing with AVA", link: "/recipes/ava.html" },
46+
],
47+
},
48+
],
49+
},
50+
};

docs/.vitepress/theme/custom.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/*https://github.com/vuejs/vitepress/blob/master/src/client/theme-default/styles/vars.css*/
2+
:root {
3+
--c-brand: #ff8132;
4+
--c-brand-light: #ff9257;
5+
}

docs/.vitepress/theme/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import DefaultTheme from "vitepress/theme";
2+
import "./custom.css";
3+
4+
export default DefaultTheme;

0 commit comments

Comments
 (0)