Skip to content

Commit 6479fc5

Browse files
authored
Redesign wrangler dev (#9335)
* Better underscore + less linebreaking in Wrangler banner * Remove local/remote hotkey, improve hotkey styling, and pin to top rather than bottom * Improve print-bindings * more redesign * more redesign * fix lint * fix interactive tests * fix pages-dev snapshots * Create kind-dots-argue.md * Address comments * Address comments * fix tests * cleanup tests * fix pages-dev test * fix e2e snapshot * add unsupported wording
1 parent 410d985 commit 6479fc5

29 files changed

+1266
-1445
lines changed

.changeset/kind-dots-argue.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"miniflare": patch
3+
"wrangler": patch
4+
---
5+
6+
Redesign `wrangler dev` to more clearly present information and have a bit of a glow up ✨
7+
![Screenshot 2025-05-22 at 01 11 43](https://github.com/user-attachments/assets/26cc6209-37a1-4ecb-8e91-daac2f79a095)

fixtures/interactive-dev-tests/tests/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ async function startWranglerDev(args: string[], skipWaitingForReady = false) {
137137
if (!skipWaitingForReady) {
138138
let readyMatch: RegExpMatchArray | null = null;
139139
for await (const line of stdoutInterface) {
140-
if ((readyMatch = readyRegexp.exec(line)) !== null) break;
140+
if ((readyMatch = readyRegexp.exec(stripAnsi(line))) !== null) break;
141141
}
142142
assert(readyMatch !== null, "Expected ready message");
143143
result.url = readyMatch[1];

packages/miniflare/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { ReadableStream } from "stream/web";
1212
import util from "util";
1313
import zlib from "zlib";
1414
import exitHook from "exit-hook";
15-
import { $ as colors$ } from "kleur/colors";
15+
import { $ as colors$, green } from "kleur/colors";
1616
import stoppable from "stoppable";
1717
import {
1818
Dispatcher,
@@ -1566,7 +1566,7 @@ export class Miniflare {
15661566
const urlSafeHost = getURLSafeHost(configuredHost);
15671567
if (this.#sharedOpts.core.logRequests) {
15681568
this.#log.info(
1569-
`${ready} on ${secure ? "https" : "http"}://${urlSafeHost}:${entryPort}`
1569+
`${ready} on ${green(`${secure ? "https" : "http"}://${urlSafeHost}:${entryPort}`)}`
15701570
);
15711571
}
15721572

packages/miniflare/src/shared/log.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ const cwdNodeModules = path.join(cwd, "node_modules");
77

88
const LEVEL_PREFIX: { [key in LogLevel]: string } = {
99
[LogLevel.NONE]: "",
10-
[LogLevel.ERROR]: "err",
11-
[LogLevel.WARN]: "wrn",
12-
[LogLevel.INFO]: "inf",
13-
[LogLevel.DEBUG]: "dbg",
14-
[LogLevel.VERBOSE]: "vrb",
10+
[LogLevel.ERROR]: "error",
11+
[LogLevel.WARN]: "warn",
12+
[LogLevel.INFO]: "info",
13+
[LogLevel.DEBUG]: "debug",
14+
[LogLevel.VERBOSE]: "verbose",
1515
};
1616

1717
const LEVEL_COLOUR: { [key in LogLevel]: Colorize } = {
@@ -83,7 +83,7 @@ export class Log {
8383
logWithLevel(level: LogLevel, message: string): void {
8484
if (level <= this.level) {
8585
const prefix = `[${this.#prefix}${LEVEL_PREFIX[level]}${this.#suffix}]`;
86-
this.log(LEVEL_COLOUR[level](`${prefix} ${message}`));
86+
this.log(`${LEVEL_COLOUR[level](prefix)} ${message}`);
8787
}
8888
}
8989

packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,28 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3-
exports[`Pages 'wrangler pages dev' > should merge (with override) \`wrangler.toml\` configuration with configuration provided via the command line, with command line args taking precedence 1`] = `
3+
exports[`wrangler pages dev > should merge (with override) \`wrangler.toml\` configuration with configuration provided via the command line, with command line args taking precedence 1`] = `
44
"✨ Compiled Worker successfully
5-
Your Worker and resources are simulated locally via Miniflare. For more information, see: https://developers.cloudflare.com/workers/testing/local-development.
65
Your Worker has access to the following bindings:
7-
- Durable Objects:
8-
- DO_BINDING_1_TOML: NEW_DO_1 (defined in NEW_DO_SCRIPT_1 [not connected])
9-
- DO_BINDING_2_TOML: DO_2_TOML (defined in DO_SCRIPT_2_TOML [not connected])
10-
- DO_BINDING_3_ARGS: DO_3_ARGS (defined in DO_SCRIPT_3_ARGS [not connected])
11-
- KV Namespaces:
12-
- KV_BINDING_1_TOML: NEW_KV_ID_1 [simulated locally]
13-
- KV_BINDING_2_TOML: KV_ID_2_TOML [simulated locally]
14-
- KV_BINDING_3_ARGS: KV_ID_3_ARGS [simulated locally]
15-
- D1 Databases:
16-
- D1_BINDING_1_TOML: local-D1_BINDING_1_TOML=NEW_D1_NAME_1 (NEW_D1_NAME_1) [simulated locally]
17-
- D1_BINDING_2_TOML: D1_NAME_2_TOML (D1_ID_2_TOML) [simulated locally]
18-
- D1_BINDING_3_ARGS: local-D1_BINDING_3_ARGS=D1_NAME_3_ARGS (D1_NAME_3_ARGS) [simulated locally]
19-
- R2 Buckets:
20-
- R2_BINDING_1_TOML: new-r2-bucket-1 [simulated locally]
21-
- R2_BINDING_2_TOML: r2-bucket-2-toml [simulated locally]
22-
- R2_BINDING_3_TOML: r2-bucket-3-args [simulated locally]
23-
- Services:
24-
- SERVICE_BINDING_1_TOML: NEW_SERVICE_NAME_1 [not connected]
25-
- SERVICE_BINDING_2_TOML: SERVICE_NAME_2_TOML [not connected]
26-
- SERVICE_BINDING_3_TOML: SERVICE_NAME_3_ARGS [not connected]
27-
- AI:
28-
- Name: AI_BINDING_2_TOML [connected to remote resource]
29-
- Vars:
30-
- VAR1: "(hidden)"
31-
- VAR2: "VAR_2_TOML"
32-
- VAR3: "(hidden)"
6+
Binding Resource Mode
7+
env.DO_BINDING_1_TOML (NEW_DO_1, defined in NEW_DO_SCRIPT_1) Durable Object local [not connected]
8+
env.DO_BINDING_2_TOML (DO_2_TOML, defined in DO_SCRIPT_2_TOML) Durable Object local [not connected]
9+
env.DO_BINDING_3_ARGS (DO_3_ARGS, defined in DO_SCRIPT_3_ARGS) Durable Object local [not connected]
10+
env.KV_BINDING_1_TOML (NEW_KV_ID_1) KV Namespace local
11+
env.KV_BINDING_2_TOML (KV_ID_2_TOML) KV Namespace local
12+
env.KV_BINDING_3_ARGS (KV_ID_3_ARGS) KV Namespace local
13+
env.D1_BINDING_1_TOML (local-D1_BINDING_1_TOML=NEW_D1_NAME_1) D1 Database local
14+
env.D1_BINDING_2_TOML (D1_NAME_2_TOML) D1 Database local
15+
env.D1_BINDING_3_ARGS (local-D1_BINDING_3_ARGS=D1_NAME_3_ARGS) D1 Database local
16+
env.R2_BINDING_1_TOML (new-r2-bucket-1) R2 Bucket local
17+
env.R2_BINDING_2_TOML (r2-bucket-2-toml) R2 Bucket local
18+
env.R2_BINDING_3_TOML (r2-bucket-3-args) R2 Bucket local
19+
env.SERVICE_BINDING_1_TOML (NEW_SERVICE_NAME_1) Worker local [not connected]
20+
env.SERVICE_BINDING_2_TOML (SERVICE_NAME_2_TOML) Worker local [not connected]
21+
env.SERVICE_BINDING_3_TOML (SERVICE_NAME_3_ARGS) Worker local [not connected]
22+
env.AI_BINDING_2_TOML AI remote
23+
env.VAR1 ("(hidden)") Environment Variable local
24+
env.VAR2 ("VAR_2_TOML") Environment Variable local
25+
env.VAR3 ("(hidden)") Environment Variable local
3326
Service bindings, Durable Object bindings, and Tail consumers connect to other \`wrangler dev\` processes running locally, with their connection status indicated by [connected] or [not connected]. For more details, refer to https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/#local-development
3427
▲ [WARNING] Using Workers AI always accesses your Cloudflare account in order to run AI models, and so will incur usage charges even in local development.
3528
"

packages/wrangler/e2e/deployments.test.ts

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,6 @@ Uploaded 2 of 3 assets
285285
Uploaded 3 of 3 assets
286286
✨ Success! Uploaded 3 files (TIMINGS)
287287
Total Upload: xx KiB / gzip: xx KiB
288-
No bindings found.
289288
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
290289
Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
291290
https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev
@@ -374,8 +373,8 @@ Uploaded 3 of 3 assets
374373
✨ Success! Uploaded 3 files (TIMINGS)
375374
Total Upload: xx KiB / gzip: xx KiB
376375
Your Worker has access to the following bindings:
377-
- Assets:
378-
- Binding: ASSETS
376+
Binding Resource
377+
env.ASSETS Assets
379378
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
380379
Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
381380
https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev
@@ -541,8 +540,8 @@ Uploaded 3 of 3 assets
541540
✨ Success! Uploaded 3 files (TIMINGS)
542541
Total Upload: xx KiB / gzip: xx KiB
543542
Your Worker has access to the following bindings:
544-
- Assets:
545-
- Binding: ASSETS
543+
Binding Resource
544+
env.ASSETS Assets
546545
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
547546
Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
548547
https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev
@@ -651,7 +650,6 @@ Uploaded 2 of 3 assets
651650
Uploaded 3 of 3 assets
652651
✨ Success! Uploaded 3 files (TIMINGS)
653652
Total Upload: xx KiB / gzip: xx KiB
654-
No bindings found.
655653
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
656654
Dispatch Namespace: tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000
657655
Current Version ID: 00000000-0000-0000-0000-000000000000`);
@@ -663,8 +661,8 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
663661
normalizedStdout = normalize(output.stdout);
664662
expect(normalizedStdout).toEqual(`Total Upload: xx KiB / gzip: xx KiB
665663
Your Worker has access to the following bindings:
666-
- Dispatch Namespaces:
667-
- DISPATCH: tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000
664+
Binding Resource
665+
env.DISPATCH (tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000) Dispatch Namespace
668666
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
669667
Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
670668
https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev
@@ -763,8 +761,8 @@ Uploaded 3 of 3 assets
763761
✨ Success! Uploaded 3 files (TIMINGS)
764762
Total Upload: xx KiB / gzip: xx KiB
765763
Your Worker has access to the following bindings:
766-
- Assets:
767-
- Binding: ASSETS
764+
Binding Resource
765+
env.ASSETS Assets
768766
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
769767
Dispatch Namespace: tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000
770768
Current Version ID: 00000000-0000-0000-0000-000000000000`);
@@ -776,8 +774,8 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
776774
normalizedStdout = normalize(output.stdout);
777775
expect(normalizedStdout).toEqual(`Total Upload: xx KiB / gzip: xx KiB
778776
Your Worker has access to the following bindings:
779-
- Dispatch Namespaces:
780-
- DISPATCH: tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000
777+
Binding Resource
778+
env.DISPATCH (tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000) Dispatch Namespace
781779
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
782780
Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
783781
https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev
@@ -874,8 +872,8 @@ Uploaded 3 of 3 assets
874872
✨ Success! Uploaded 3 files (TIMINGS)
875873
Total Upload: xx KiB / gzip: xx KiB
876874
Your Worker has access to the following bindings:
877-
- Assets:
878-
- Binding: ASSETS
875+
Binding Resource
876+
env.ASSETS Assets
879877
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
880878
Dispatch Namespace: tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000
881879
Current Version ID: 00000000-0000-0000-0000-000000000000`);
@@ -887,8 +885,8 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
887885
normalizedStdout = normalize(output.stdout);
888886
expect(normalizedStdout).toEqual(`Total Upload: xx KiB / gzip: xx KiB
889887
Your Worker has access to the following bindings:
890-
- Dispatch Namespaces:
891-
- DISPATCH: tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000
888+
Binding Resource
889+
env.DISPATCH (tmp-e2e-dispatch-00000000-0000-0000-0000-000000000000) Dispatch Namespace
892890
Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
893891
Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
894892
https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev

packages/wrangler/e2e/dev-mixed-mode.test.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,13 @@ describe("wrangler dev - mixed mode", () => {
136136

137137
// This should only include logs from the user Wrangler session (i.e. a single list of attached bindings, and only one ready message)
138138
expect(normalizeOutput(worker.currentOutput)).toMatchInlineSnapshot(`
139-
"Your Worker and resources are simulated locally via Miniflare. For more information, see: https://developers.cloudflare.com/workers/testing/local-development.
140-
Your Worker has access to the following bindings:
141-
- AI:
142-
- Name: AI [connected to remote resource]
143-
[wrangler:inf] Ready on http://localhost:<PORT>
139+
"Your Worker has access to the following bindings:
140+
Binding Resource Mode
141+
env.AI AI remote
142+
[wrangler:info] Ready on http://localhost:<PORT>
144143
▲ [WARNING] Using Workers AI always accesses your Cloudflare account in order to run AI models, and so will incur usage charges even in local development.
145144
⎔ Starting local server...
146-
[wrangler:inf] GET / 200 OK (TIMINGS)"
145+
[wrangler:info] GET / 200 OK (TIMINGS)"
147146
`);
148147
});
149148

packages/wrangler/e2e/helpers/normalize.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function removeKVId(str: string) {
8686
* Remove the Wrangler version/update check header
8787
*/
8888
function removeVersionHeader(str: string): string {
89-
const header = str.match(/ wrangler .*\n----+\n/);
89+
const header = str.match(/ wrangler .*\n+\n/);
9090
if (header !== null && header.index) {
9191
return str.slice(header.index + header[0].length);
9292
} else {
@@ -176,8 +176,8 @@ function normalizeDebugLogFilepath(stdout: string): string {
176176
*/
177177
function removeLocalPort(stdout: string): string {
178178
return stdout.replace(
179-
/\[wrangler:inf\] Ready on (https?):\/\/(.+):\d{4,5}/,
180-
"[wrangler:inf] Ready on $1://$2:<PORT>"
179+
/\[wrangler:info\] Ready on (https?):\/\/(.+):\d{4,5}/,
180+
"[wrangler:info] Ready on $1://$2:<PORT>"
181181
);
182182
}
183183

0 commit comments

Comments
 (0)