wrangler 2.0.19 → 2.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/api/dev.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { startDev } from "../dev";
2
2
  import { logger } from "../logger";
3
3
 
4
+ import type { EnablePagesAssetsServiceBindingOptions } from "../miniflare-cli";
4
5
  import type { RequestInit, Response } from "undici";
5
6
 
6
7
  interface DevOptions {
@@ -13,39 +14,72 @@ interface DevOptions {
13
14
  siteInclude?: string[];
14
15
  siteExclude?: string[];
15
16
  nodeCompat?: boolean;
17
+ compatibilityDate?: string;
16
18
  experimentalEnableLocalPersistence?: boolean;
17
- _: (string | number)[]; //yargs wants this
18
- $0: string; //yargs wants this
19
+ liveReload?: boolean;
20
+ watch?: boolean;
21
+ vars: {
22
+ [key: string]: unknown;
23
+ };
24
+ kv?: {
25
+ binding: string;
26
+ id: string;
27
+ preview_id?: string;
28
+ }[];
29
+ durableObjects?: {
30
+ name: string;
31
+ class_name: string;
32
+ script_name?: string | undefined;
33
+ environment?: string | undefined;
34
+ }[];
35
+ showInteractiveDevSession?: boolean;
36
+ logLevel?: "none" | "error" | "log" | "warn" | "debug";
37
+ logPrefix?: string;
38
+ inspect?: boolean;
39
+ forceLocal?: boolean;
40
+ enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
41
+ _?: (string | number)[]; //yargs wants this
42
+ $0?: string; //yargs wants this
19
43
  }
20
44
  /**
21
45
  * unstable_dev starts a wrangler dev server, and returns a promise that resolves with utility functions to interact with it.
22
46
  * @param {string} script
23
47
  * @param {DevOptions} options
24
48
  */
25
- export async function unstable_dev(script: string, options: DevOptions) {
26
- logger.warn(
27
- `unstable_dev() is experimental\nunstable_dev()'s behaviour will likely change in future releases`
28
- );
49
+ export async function unstable_dev(
50
+ script: string,
51
+ options: DevOptions,
52
+ disableExperimentalWarning?: boolean
53
+ ) {
54
+ if (!disableExperimentalWarning) {
55
+ logger.warn(
56
+ `unstable_dev() is experimental\nunstable_dev()'s behaviour will likely change in future releases`
57
+ );
58
+ }
29
59
 
30
60
  return new Promise<{
31
61
  stop: () => void;
32
62
  fetch: (init?: RequestInit) => Promise<Response | undefined>;
63
+ waitUntilExit: () => Promise<void>;
33
64
  }>((resolve) => {
34
65
  //lmao
35
66
  return new Promise<Awaited<ReturnType<typeof startDev>>>((ready) => {
36
67
  const devServer = startDev({
37
68
  script: script,
38
- ...options,
39
- local: true,
40
- onReady: () => ready(devServer),
41
69
  inspect: false,
42
70
  logLevel: "none",
43
71
  showInteractiveDevSession: false,
72
+ _: [],
73
+ $0: "",
74
+ ...options,
75
+ local: true,
76
+ onReady: () => ready(devServer),
44
77
  });
45
78
  }).then((devServer) => {
46
79
  resolve({
47
80
  stop: devServer.stop,
48
81
  fetch: devServer.fetch,
82
+ waitUntilExit: devServer.devReactElement.waitUntilExit,
49
83
  });
50
84
  });
51
85
  });
package/src/bundle.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import assert from "node:assert";
2
2
  import * as fs from "node:fs";
3
3
  import { builtinModules } from "node:module";
4
+ import * as os from "node:os";
4
5
  import * as path from "node:path";
5
6
  import NodeGlobalsPolyfills from "@esbuild-plugins/node-globals-polyfill";
6
7
  import NodeModulesPolyfills from "@esbuild-plugins/node-modules-polyfill";
@@ -92,14 +93,37 @@ export async function bundleWorker(
92
93
  rules,
93
94
  });
94
95
 
96
+ // In dev, we want to patch `fetch()` with a special version that looks
97
+ // for bad usages and can warn the user about them; so we inject
98
+ // `checked-fetch.js` to do so. However, with yarn 3 style pnp,
99
+ // we need to extract that file to an accessible place before injecting
100
+ // it in, hence this code here.
101
+ const osTempDir = os.tmpdir();
102
+ const checkedFetchFileToInject = path.join(
103
+ osTempDir,
104
+ "--temp-wrangler-files--",
105
+ "checked-fetch.js"
106
+ );
107
+
108
+ if (checkFetch && !fs.existsSync(checkedFetchFileToInject)) {
109
+ fs.mkdirSync(path.join(osTempDir, "--temp-wrangler-files--"), {
110
+ recursive: true,
111
+ });
112
+ fs.writeFileSync(
113
+ checkedFetchFileToInject,
114
+ fs.readFileSync(path.resolve(__dirname, "../templates/checked-fetch.js"))
115
+ );
116
+ }
117
+ // TODO: we need to have similar logic like above for other files
118
+ // like the static asset facade, and other middleware that we
119
+ // plan on injecting/referencing.
120
+
95
121
  const result = await esbuild.build({
96
122
  ...getEntryPoint(entry.file, serveAssetsFromWorker),
97
123
  bundle: true,
98
124
  absWorkingDir: entry.directory,
99
125
  outdir: destination,
100
- inject: checkFetch
101
- ? [path.resolve(__dirname, "../templates/checked-fetch.js")]
102
- : [],
126
+ inject: checkFetch ? [checkedFetchFileToInject] : [],
103
127
  external: ["__STATIC_CONTENT_MANIFEST"],
104
128
  format: entry.format === "modules" ? "esm" : "iife",
105
129
  target: "es2020",
@@ -109,7 +133,9 @@ export async function bundleWorker(
109
133
  conditions: ["worker", "browser"],
110
134
  ...(process.env.NODE_ENV && {
111
135
  define: {
112
- "process.env.NODE_ENV": `"${process.env.NODE_ENV}"`,
136
+ // use process.env["NODE_ENV" + ""] so that esbuild doesn't replace it
137
+ // when we do a build of wrangler. (re: https://github.com/cloudflare/wrangler2/issues/1477)
138
+ "process.env.NODE_ENV": `"${process.env["NODE_ENV" + ""]}"`,
113
139
  ...(nodeCompat ? { global: "globalThis" } : {}),
114
140
  ...(checkFetch ? { fetch: "checkedFetch" } : {}),
115
141
  ...options.define,
@@ -180,6 +180,13 @@ export interface DevConfig {
180
180
  */
181
181
  port: number | undefined;
182
182
 
183
+ /**
184
+ * Port for the local dev server's inspector to listen on
185
+ *
186
+ * @default `9229`
187
+ */
188
+ inspector_port: number | undefined;
189
+
183
190
  /**
184
191
  * Protocol that local wrangler dev server listens to requests on.
185
192
  *
@@ -359,6 +359,7 @@ function normalizeAndValidateDev(
359
359
  const {
360
360
  ip = "localhost",
361
361
  port,
362
+ inspector_port,
362
363
  local_protocol = "http",
363
364
  upstream_protocol = "https",
364
365
  host,
@@ -368,6 +369,13 @@ function normalizeAndValidateDev(
368
369
 
369
370
  validateOptionalProperty(diagnostics, "dev", "ip", ip, "string");
370
371
  validateOptionalProperty(diagnostics, "dev", "port", port, "number");
372
+ validateOptionalProperty(
373
+ diagnostics,
374
+ "dev",
375
+ "inspector_port",
376
+ inspector_port,
377
+ "number"
378
+ );
371
379
  validateOptionalProperty(
372
380
  diagnostics,
373
381
  "dev",
@@ -385,7 +393,7 @@ function normalizeAndValidateDev(
385
393
  ["http", "https"]
386
394
  );
387
395
  validateOptionalProperty(diagnostics, "dev", "host", host, "string");
388
- return { ip, port, local_protocol, upstream_protocol, host };
396
+ return { ip, port, inspector_port, local_protocol, upstream_protocol, host };
389
397
  }
390
398
 
391
399
  /**
@@ -247,7 +247,9 @@ export async function createWorkerPreview(
247
247
  }
248
248
  },
249
249
  (err) => {
250
- logger.warn("worker failed to prewarm: ", err);
250
+ if ((err as { code: string }).code !== "ABORT_ERR") {
251
+ logger.warn("worker failed to prewarm: ", err);
252
+ }
251
253
  }
252
254
  );
253
255
 
package/src/dev/dev.tsx CHANGED
@@ -19,6 +19,7 @@ import { useEsbuild } from "./use-esbuild";
19
19
  import type { Config } from "../config";
20
20
  import type { Route } from "../config/environment";
21
21
  import type { Entry } from "../entry";
22
+ import type { EnablePagesAssetsServiceBindingOptions } from "../miniflare-cli";
22
23
  import type { AssetPaths } from "../sites";
23
24
  import type { CfWorkerInit } from "../worker";
24
25
 
@@ -39,6 +40,7 @@ export type DevProps = {
39
40
  localProtocol: "https" | "http";
40
41
  localUpstream: string | undefined;
41
42
  enableLocalPersistence: boolean;
43
+ liveReload: boolean;
42
44
  bindings: CfWorkerInit["bindings"];
43
45
  define: Config["define"];
44
46
  crons: Config["triggers"]["crons"];
@@ -55,10 +57,13 @@ export type DevProps = {
55
57
  zone: string | undefined;
56
58
  host: string | undefined;
57
59
  routes: Route[] | undefined;
58
- inspect: boolean | undefined;
60
+ inspect: boolean;
59
61
  logLevel: "none" | "error" | "log" | "warn" | "debug" | undefined;
62
+ logPrefix?: string;
60
63
  onReady: (() => void) | undefined;
61
64
  showInteractiveDevSession: boolean | undefined;
65
+ forceLocal: boolean | undefined;
66
+ enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
62
67
  };
63
68
 
64
69
  export function DevImplementation(props: DevProps): JSX.Element {
@@ -101,16 +106,18 @@ export function DevImplementation(props: DevProps): JSX.Element {
101
106
  }
102
107
 
103
108
  function InteractiveDevSession(props: DevProps) {
104
- const toggles = useHotkeys(
105
- {
109
+ const toggles = useHotkeys({
110
+ initial: {
106
111
  local: props.initialMode === "local",
107
112
  tunnel: false,
108
113
  },
109
- props.port,
110
- props.ip,
111
- props.inspectorPort,
112
- props.localProtocol
113
- );
114
+ port: props.port,
115
+ ip: props.ip,
116
+ inspectorPort: props.inspectorPort,
117
+ inspect: props.inspect,
118
+ localProtocol: props.localProtocol,
119
+ forceLocal: props.forceLocal,
120
+ });
114
121
 
115
122
  useTunnel(toggles.tunnel);
116
123
 
@@ -120,10 +127,18 @@ function InteractiveDevSession(props: DevProps) {
120
127
  <Box borderStyle="round" paddingLeft={1} paddingRight={1}>
121
128
  <Text bold={true}>[b]</Text>
122
129
  <Text> open a browser, </Text>
123
- <Text bold={true}>[d]</Text>
124
- <Text> open Devtools, </Text>
125
- <Text bold={true}>[l]</Text>
126
- <Text> {toggles.local ? "turn off" : "turn on"} local mode, </Text>
130
+ {props.inspect ? (
131
+ <>
132
+ <Text bold={true}>[d]</Text>
133
+ <Text> open Devtools, </Text>
134
+ </>
135
+ ) : null}
136
+ {!props.forceLocal ? (
137
+ <>
138
+ <Text bold={true}>[l]</Text>
139
+ <Text> {toggles.local ? "turn off" : "turn on"} local mode, </Text>
140
+ </>
141
+ ) : null}
127
142
  <Text bold={true}>[c]</Text>
128
143
  <Text> clear console, </Text>
129
144
  <Text bold={true}>[x]</Text>
@@ -173,12 +188,15 @@ function DevSession(props: DevSessionProps) {
173
188
  rules={props.rules}
174
189
  inspectorPort={props.inspectorPort}
175
190
  enableLocalPersistence={props.enableLocalPersistence}
191
+ liveReload={props.liveReload}
176
192
  crons={props.crons}
177
193
  localProtocol={props.localProtocol}
178
194
  localUpstream={props.localUpstream}
179
195
  logLevel={props.logLevel}
196
+ logPrefix={props.logPrefix}
180
197
  inspect={props.inspect}
181
198
  onReady={props.onReady}
199
+ enablePagesAssetsServiceBinding={props.enablePagesAssetsServiceBinding}
182
200
  />
183
201
  ) : (
184
202
  <Remote
@@ -193,6 +211,9 @@ function DevSession(props: DevSessionProps) {
193
211
  ip={props.ip}
194
212
  localProtocol={props.localProtocol}
195
213
  inspectorPort={props.inspectorPort}
214
+ // TODO: @threepointone #1167
215
+ // liveReload={props.liveReload}
216
+ inspect={props.inspect}
196
217
  compatibilityDate={props.compatibilityDate}
197
218
  compatibilityFlags={props.compatibilityFlags}
198
219
  usageModel={props.usageModel}
@@ -346,13 +367,24 @@ type useHotkeysInitialState = {
346
367
  local: boolean;
347
368
  tunnel: boolean;
348
369
  };
349
- function useHotkeys(
350
- initial: useHotkeysInitialState,
351
- port: number,
352
- ip: string,
353
- inspectorPort: number,
354
- localProtocol: "http" | "https"
355
- ) {
370
+ function useHotkeys(props: {
371
+ initial: useHotkeysInitialState;
372
+ port: number;
373
+ ip: string;
374
+ inspectorPort: number;
375
+ inspect: boolean;
376
+ localProtocol: "http" | "https";
377
+ forceLocal: boolean | undefined;
378
+ }) {
379
+ const {
380
+ initial,
381
+ port,
382
+ ip,
383
+ inspectorPort,
384
+ inspect,
385
+ localProtocol,
386
+ forceLocal,
387
+ } = props;
356
388
  // UGH, we should put port in context instead
357
389
  const [toggles, setToggles] = useState(initial);
358
390
  const { exit } = useApp();
@@ -377,11 +409,14 @@ function useHotkeys(
377
409
  }
378
410
  // toggle inspector
379
411
  case "d": {
380
- await openInspector(inspectorPort);
412
+ if (inspect) {
413
+ await openInspector(inspectorPort);
414
+ }
381
415
  break;
382
416
  }
383
417
  // toggle local
384
418
  case "l":
419
+ if (forceLocal) return;
385
420
  setToggles((previousToggles) => ({
386
421
  ...previousToggles,
387
422
  local: !previousToggles.local,
package/src/dev/local.tsx CHANGED
@@ -9,6 +9,7 @@ import { logger } from "../logger";
9
9
  import { DEFAULT_MODULE_RULES } from "../module-collection";
10
10
  import { waitForPortToBeAvailable } from "../proxy";
11
11
  import type { Config } from "../config";
12
+ import type { EnablePagesAssetsServiceBindingOptions } from "../miniflare-cli";
12
13
  import type { AssetPaths } from "../sites";
13
14
  import type { CfWorkerInit, CfScriptFormat } from "../worker";
14
15
  import type { EsbuildBundle } from "./use-esbuild";
@@ -28,12 +29,15 @@ interface LocalProps {
28
29
  rules: Config["rules"];
29
30
  inspectorPort: number;
30
31
  enableLocalPersistence: boolean;
32
+ liveReload: boolean;
31
33
  crons: Config["triggers"]["crons"];
32
34
  localProtocol: "http" | "https";
33
35
  localUpstream: string | undefined;
34
- inspect: boolean | undefined;
36
+ inspect: boolean;
35
37
  onReady: (() => void) | undefined;
36
38
  logLevel: "none" | "error" | "log" | "warn" | "debug" | undefined;
39
+ logPrefix?: string;
40
+ enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
37
41
  }
38
42
 
39
43
  export function Local(props: LocalProps) {
@@ -56,8 +60,10 @@ function useLocalWorker({
56
60
  assetPaths,
57
61
  isWorkersSite,
58
62
  port,
63
+ inspectorPort,
59
64
  rules,
60
65
  enableLocalPersistence,
66
+ liveReload,
61
67
  ip,
62
68
  crons,
63
69
  localProtocol,
@@ -65,6 +71,8 @@ function useLocalWorker({
65
71
  inspect,
66
72
  onReady,
67
73
  logLevel,
74
+ logPrefix,
75
+ enablePagesAssetsServiceBinding,
68
76
  }: LocalProps) {
69
77
  // TODO: pass vars via command line
70
78
  const local = useRef<ChildProcess>();
@@ -212,6 +220,7 @@ function useLocalWorker({
212
220
  r2Persist: true,
213
221
  }),
214
222
 
223
+ liveReload,
215
224
  sitePath: assetPaths?.assetDirectory
216
225
  ? path.join(assetPaths.baseDirectory, assetPaths.assetDirectory)
217
226
  : undefined,
@@ -230,6 +239,7 @@ function useLocalWorker({
230
239
  crons,
231
240
  upstream,
232
241
  disableLogs: logLevel === "none",
242
+ logOptions: logPrefix ? { prefix: logPrefix } : undefined,
233
243
  };
234
244
 
235
245
  // The path to the Miniflare CLI assumes that this file is being run from
@@ -248,16 +258,21 @@ function useLocalWorker({
248
258
  // "--log=VERBOSE", // uncomment this to Miniflare to log "everything"!
249
259
  ];
250
260
  if (inspect) {
251
- nodeOptions.push("--inspect"); // start Miniflare listening for a debugger to attach
261
+ nodeOptions.push("--inspect=" + `${ip}:${inspectorPort}`); // start Miniflare listening for a debugger to attach
252
262
  }
253
- const child = (local.current = fork(
254
- miniflareCLIPath,
255
- [miniflareOptions],
256
- {
257
- cwd: path.dirname(scriptPath),
258
- execArgv: nodeOptions,
259
- }
260
- ));
263
+
264
+ const forkOptions = [miniflareOptions];
265
+
266
+ if (enablePagesAssetsServiceBinding) {
267
+ forkOptions.push(JSON.stringify(enablePagesAssetsServiceBinding));
268
+ }
269
+
270
+ const child = (local.current = fork(miniflareCLIPath, forkOptions, {
271
+ cwd: path.dirname(scriptPath),
272
+ execArgv: nodeOptions,
273
+ stdio: "pipe",
274
+ }));
275
+
261
276
  child.on("message", (message) => {
262
277
  if (message === "ready") {
263
278
  onReady?.();
@@ -330,6 +345,7 @@ function useLocalWorker({
330
345
  workerName,
331
346
  format,
332
347
  port,
348
+ inspectorPort,
333
349
  ip,
334
350
  bindings.durable_objects?.bindings,
335
351
  bindings.kv_namespaces,
@@ -339,6 +355,7 @@ function useLocalWorker({
339
355
  compatibilityDate,
340
356
  compatibilityFlags,
341
357
  localPersistencePath,
358
+ liveReload,
342
359
  assetPaths,
343
360
  isWorkersSite,
344
361
  rules,
@@ -350,7 +367,9 @@ function useLocalWorker({
350
367
  localUpstream,
351
368
  inspect,
352
369
  logLevel,
370
+ logPrefix,
353
371
  onReady,
372
+ enablePagesAssetsServiceBinding,
354
373
  ]);
355
374
  return { inspectorUrl };
356
375
  }
@@ -42,6 +42,7 @@ export function Remote(props: {
42
42
  port: number;
43
43
  ip: string;
44
44
  localProtocol: "https" | "http";
45
+ inspect: boolean;
45
46
  inspectorPort: number;
46
47
  accountId: string | undefined;
47
48
  bindings: CfWorkerInit["bindings"];
@@ -68,7 +69,6 @@ export function Remote(props: {
68
69
  bindings: props.bindings,
69
70
  assetPaths: props.assetPaths,
70
71
  isWorkersSite: props.isWorkersSite,
71
- port: props.port,
72
72
  compatibilityDate: props.compatibilityDate,
73
73
  compatibilityFlags: props.compatibilityFlags,
74
74
  usageModel: props.usageModel,
@@ -91,7 +91,10 @@ export function Remote(props: {
91
91
  });
92
92
 
93
93
  useInspector({
94
- inspectorUrl: previewToken ? previewToken.inspectorUrl.href : undefined,
94
+ inspectorUrl:
95
+ props.inspect && previewToken
96
+ ? previewToken.inspectorUrl.href
97
+ : undefined,
95
98
  port: props.inspectorPort,
96
99
  logToTerminal: true,
97
100
  });
@@ -149,7 +152,6 @@ export function useWorker(props: {
149
152
  bindings: CfWorkerInit["bindings"];
150
153
  assetPaths: AssetPaths | undefined;
151
154
  isWorkersSite: boolean;
152
- port: number;
153
155
  compatibilityDate: string | undefined;
154
156
  compatibilityFlags: string[] | undefined;
155
157
  usageModel: "bundled" | "unbound" | undefined;
@@ -171,7 +173,6 @@ export function useWorker(props: {
171
173
  compatibilityDate,
172
174
  compatibilityFlags,
173
175
  usageModel,
174
- port,
175
176
  onReady,
176
177
  } = props;
177
178
  const [session, setSession] = useState<CfPreviewSession | undefined>();
@@ -362,7 +363,6 @@ export function useWorker(props: {
362
363
  bundle,
363
364
  format,
364
365
  accountId,
365
- port,
366
366
  assetPaths,
367
367
  props.isWorkersSite,
368
368
  compatibilityDate,