wrangler 0.0.0-e33294b0 → 0.0.0-e351afcf

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.
Files changed (127) hide show
  1. package/bin/wrangler.js +1 -1
  2. package/miniflare-dist/index.mjs +183 -92
  3. package/package.json +15 -10
  4. package/src/__tests__/api-devregistry.test.ts +121 -0
  5. package/src/__tests__/api.test.ts +27 -5
  6. package/src/__tests__/configuration.test.ts +294 -18
  7. package/src/__tests__/constellation.test.ts +371 -0
  8. package/src/__tests__/d1/execute.test.ts +3 -1
  9. package/src/__tests__/d1/migrate.test.ts +102 -0
  10. package/src/__tests__/delete.test.ts +6 -0
  11. package/src/__tests__/deployments.test.ts +335 -95
  12. package/src/__tests__/dev.test.tsx +87 -57
  13. package/src/__tests__/generate.test.ts +3 -4
  14. package/src/__tests__/guess-worker-format.test.ts +35 -0
  15. package/src/__tests__/helpers/mock-console.ts +6 -0
  16. package/src/__tests__/helpers/msw/handlers/deployments.ts +70 -3
  17. package/src/__tests__/helpers/msw/index.ts +4 -2
  18. package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
  19. package/src/__tests__/index.test.ts +14 -6
  20. package/src/__tests__/init.test.ts +136 -104
  21. package/src/__tests__/jest.setup.ts +4 -0
  22. package/src/__tests__/kv.test.ts +9 -9
  23. package/src/__tests__/logger.test.ts +68 -2
  24. package/src/__tests__/middleware.scheduled.test.ts +2 -2
  25. package/src/__tests__/middleware.test.ts +4 -3
  26. package/src/__tests__/mtls-certificates.test.ts +7 -3
  27. package/src/__tests__/pages/deployment-list.test.ts +2 -0
  28. package/src/__tests__/pages/functions-build.test.ts +159 -39
  29. package/src/__tests__/pages/project-list.test.ts +2 -0
  30. package/src/__tests__/pages/project-upload.test.ts +43 -24
  31. package/src/__tests__/pages/publish.test.ts +267 -148
  32. package/src/__tests__/publish.test.ts +1040 -339
  33. package/src/__tests__/pubsub.test.ts +3 -0
  34. package/src/__tests__/queues.test.ts +5 -2
  35. package/src/__tests__/test-old-node-version.js +3 -3
  36. package/src/__tests__/traverse-module-graph.test.ts +220 -0
  37. package/src/__tests__/tsconfig.tsbuildinfo +1 -1
  38. package/src/__tests__/type-generation.test.ts +1 -0
  39. package/src/__tests__/user.test.ts +2 -2
  40. package/src/__tests__/worker-namespace.test.ts +1 -0
  41. package/src/api/dev.ts +15 -22
  42. package/src/api/pages/create-worker-bundle-contents.ts +1 -0
  43. package/src/api/pages/publish.tsx +64 -61
  44. package/src/bundle.ts +51 -16
  45. package/src/config/environment.ts +36 -4
  46. package/src/config/index.ts +30 -2
  47. package/src/config/validation-helpers.ts +1 -1
  48. package/src/config/validation.ts +149 -5
  49. package/src/constellation/createProject.tsx +51 -0
  50. package/src/constellation/deleteProject.ts +51 -0
  51. package/src/constellation/deleteProjectModel.ts +68 -0
  52. package/src/constellation/index.ts +75 -0
  53. package/src/constellation/listCatalog.tsx +35 -0
  54. package/src/constellation/listModel.tsx +41 -0
  55. package/src/constellation/listProject.tsx +28 -0
  56. package/src/constellation/listRuntime.tsx +28 -0
  57. package/src/constellation/options.ts +17 -0
  58. package/src/constellation/types.ts +17 -0
  59. package/src/constellation/uploadModel.tsx +64 -0
  60. package/src/constellation/utils.ts +90 -0
  61. package/src/create-worker-preview.ts +19 -8
  62. package/src/create-worker-upload-form.ts +28 -3
  63. package/src/d1/backups.tsx +19 -15
  64. package/src/d1/create.tsx +45 -39
  65. package/src/d1/delete.ts +1 -1
  66. package/src/d1/execute.tsx +23 -20
  67. package/src/d1/list.tsx +14 -12
  68. package/src/d1/migrations/apply.tsx +36 -30
  69. package/src/d1/migrations/create.tsx +15 -12
  70. package/src/d1/migrations/helpers.ts +5 -8
  71. package/src/d1/migrations/list.tsx +10 -7
  72. package/src/deployments.ts +260 -8
  73. package/src/dev/dev.tsx +6 -4
  74. package/src/dev/local.tsx +65 -40
  75. package/src/dev/start-server.ts +57 -52
  76. package/src/dev/use-esbuild.ts +59 -52
  77. package/src/dev/validate-dev-props.ts +9 -0
  78. package/src/dev-registry.ts +2 -1
  79. package/src/dev.tsx +38 -18
  80. package/src/docs/helpers.ts +50 -0
  81. package/src/docs/index.ts +25 -68
  82. package/src/entry.ts +19 -9
  83. package/src/environment-variables/factory.ts +2 -1
  84. package/src/generate/index.ts +2 -2
  85. package/src/index.ts +87 -24
  86. package/src/init.ts +144 -134
  87. package/src/inspect.ts +16 -1
  88. package/src/kv/helpers.ts +7 -4
  89. package/src/logger.ts +23 -4
  90. package/src/metrics/send-event.ts +2 -1
  91. package/src/miniflare-cli/assets.ts +8 -7
  92. package/src/miniflare-cli/index.ts +3 -3
  93. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -1
  94. package/src/module-collection.ts +92 -26
  95. package/src/pages/build.ts +290 -100
  96. package/src/pages/buildFunctions.ts +20 -10
  97. package/src/pages/deployments.tsx +3 -5
  98. package/src/pages/dev.ts +44 -26
  99. package/src/pages/errors.ts +1 -0
  100. package/src/pages/functions/buildPlugin.ts +57 -34
  101. package/src/pages/functions/buildWorker.ts +91 -31
  102. package/src/pages/functions/tsconfig.tsbuildinfo +1 -1
  103. package/src/pages/projects.tsx +2 -5
  104. package/src/pages/publish.tsx +1 -10
  105. package/src/pages/upload.tsx +29 -9
  106. package/src/paths.ts +1 -1
  107. package/src/publish/index.ts +1 -1
  108. package/src/publish/publish.ts +29 -34
  109. package/src/queues/cli/commands/consumer/add.ts +6 -0
  110. package/src/queues/client.ts +1 -0
  111. package/src/r2/helpers.ts +1 -0
  112. package/src/secret/index.ts +2 -1
  113. package/src/sites.ts +164 -52
  114. package/src/traverse-module-graph.ts +53 -0
  115. package/src/type-generation.ts +1 -1
  116. package/src/user/user.ts +2 -1
  117. package/src/utils/render.ts +93 -0
  118. package/src/worker.ts +18 -1
  119. package/templates/d1-beta-facade.js +5 -2
  120. package/templates/gitignore +1 -0
  121. package/templates/middleware/middleware-miniflare3-json-error.ts +17 -5
  122. package/templates/pages-template-plugin.ts +7 -3
  123. package/templates/tsconfig.init.json +1 -2
  124. package/templates/tsconfig.tsbuildinfo +1 -1
  125. package/wrangler-dist/cli.d.ts +552 -16
  126. package/wrangler-dist/cli.js +32141 -24052
  127. package/src/__tests__/api-devregistry.test.js +0 -64
package/src/pages/dev.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { execSync, spawn } from "node:child_process";
2
- import { existsSync, readFileSync } from "node:fs";
2
+ import { existsSync, lstatSync, readFileSync } from "node:fs";
3
3
  import { homedir, tmpdir } from "node:os";
4
4
  import { join, resolve } from "node:path";
5
5
  import { watch } from "chokidar";
@@ -85,16 +85,9 @@ export function Options(yargs: CommonYargsArgv) {
85
85
  hidden: true,
86
86
  },
87
87
  "no-bundle": {
88
- type: "boolean",
89
- default: true,
90
- description: "Whether to run bundling on `_worker.js`",
91
- },
92
- "experimental-worker-bundle": {
93
88
  type: "boolean",
94
89
  default: false,
95
- hidden: true,
96
- description:
97
- "Whether to process non-JS module imports or not, such as wasm/text/binary, when we run bundling on `functions` or `_worker.js`",
90
+ description: "Whether to run bundling on `_worker.js`",
98
91
  },
99
92
  binding: {
100
93
  type: "array",
@@ -147,7 +140,7 @@ export function Options(yargs: CommonYargsArgv) {
147
140
  requiresArg: true,
148
141
  },
149
142
  "node-compat": {
150
- describe: "Enable node.js compatibility",
143
+ describe: "Enable Node.js compatibility",
151
144
  default: false,
152
145
  type: "boolean",
153
146
  hidden: true,
@@ -181,7 +174,6 @@ export const Handler = async ({
181
174
  proxy: requestedProxyPort,
182
175
  bundle,
183
176
  noBundle,
184
- experimentalWorkerBundle,
185
177
  scriptPath: singleWorkerScriptPath,
186
178
  binding: bindings = [],
187
179
  kv: kvs = [],
@@ -193,7 +185,7 @@ export const Handler = async ({
193
185
  experimentalEnableLocalPersistence,
194
186
  persist,
195
187
  persistTo,
196
- nodeCompat,
188
+ nodeCompat: legacyNodeCompat,
197
189
  experimentalLocal,
198
190
  config: config,
199
191
  _: [_pages, _dev, ...remaining],
@@ -263,22 +255,26 @@ export const Handler = async ({
263
255
  directory !== undefined
264
256
  ? join(directory, singleWorkerScriptPath)
265
257
  : singleWorkerScriptPath;
258
+ const usingWorkerDirectory =
259
+ existsSync(workerScriptPath) && lstatSync(workerScriptPath).isDirectory();
266
260
  const usingWorkerScript = existsSync(workerScriptPath);
261
+ // TODO: Here lies a known bug. If you specify both `--bundle` and `--no-bundle`, this behavior is undefined and you will get unexpected results.
262
+ // There is no sane way to get the true value out of yargs, so here we are.
263
+ const enableBundling = bundle ?? !noBundle;
267
264
 
268
265
  const functionsDirectory = "./functions";
269
266
  let usingFunctions = !usingWorkerScript && existsSync(functionsDirectory);
270
267
 
271
268
  let scriptPath = "";
272
269
 
270
+ const nodejsCompat = compatibilityFlags?.includes("nodejs_compat");
271
+
273
272
  if (usingWorkerScript) {
274
273
  scriptPath = workerScriptPath;
275
274
  let runBuild = async () => {
276
275
  await checkRawWorker(workerScriptPath, () => scriptReadyResolve());
277
276
  };
278
277
 
279
- // TODO: Here lies a known bug. If you specify both `--bundle` and `--no-bundle`, this behavior is undefined and you will get unexpected results.
280
- // There is no sane way to get the true value out of yargs, so here we are.
281
- const enableBundling = (bundle ?? !noBundle) || experimentalWorkerBundle;
282
278
  if (enableBundling) {
283
279
  // We want to actually run the `_worker.js` script through the bundler
284
280
  // So update the final path to the script that will be uploaded and
@@ -287,14 +283,16 @@ export const Handler = async ({
287
283
  runBuild = async () => {
288
284
  try {
289
285
  await buildRawWorker({
290
- workerScriptPath,
286
+ workerScriptPath: usingWorkerDirectory
287
+ ? join(workerScriptPath, "index.js")
288
+ : workerScriptPath,
291
289
  outfile: scriptPath,
292
290
  directory: directory ?? ".",
291
+ nodejsCompat,
293
292
  local: true,
294
293
  sourcemap: true,
295
294
  watch: true,
296
295
  onEnd: () => scriptReadyResolve(),
297
- experimentalWorkerBundle,
298
296
  });
299
297
  } catch (e: unknown) {
300
298
  logger.warn("Failed to bundle _worker.js.", e);
@@ -303,7 +301,7 @@ export const Handler = async ({
303
301
  }
304
302
 
305
303
  await runBuild();
306
- watch([scriptPath], {
304
+ watch([workerScriptPath], {
307
305
  persistent: true,
308
306
  ignoreInitial: true,
309
307
  }).on("all", async () => {
@@ -313,9 +311,16 @@ export const Handler = async ({
313
311
  // Try to use Functions
314
312
  scriptPath = join(tmpdir(), `./functionsWorker-${Math.random()}.mjs`);
315
313
 
316
- if (nodeCompat) {
314
+ if (legacyNodeCompat) {
317
315
  console.warn(
318
- "Enabling node.js compatibility mode for builtins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details."
316
+ "Enabling Node.js compatibility mode for builtins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details."
317
+ );
318
+ }
319
+
320
+ if (legacyNodeCompat && nodejsCompat) {
321
+ throw new FatalError(
322
+ "The `nodejs_compat` compatibility flag cannot be used in conjunction with the legacy `--node-compat` flag. If you want to use the Workers runtime Node.js compatibility features, please remove the `--node-compat` argument from your CLI command or `node_compat = true` from your config file.",
323
+ 1
319
324
  );
320
325
  }
321
326
 
@@ -330,9 +335,9 @@ export const Handler = async ({
330
335
  watch: true,
331
336
  onEnd,
332
337
  buildOutputDirectory: directory,
333
- nodeCompat,
338
+ legacyNodeCompat,
339
+ nodejsCompat,
334
340
  local: true,
335
- experimentalWorkerBundle,
336
341
  });
337
342
  await metrics.sendMetricsEvent("build pages functions");
338
343
  };
@@ -395,7 +400,10 @@ export const Handler = async ({
395
400
  let entrypoint = scriptPath;
396
401
 
397
402
  // custom _routes.json apply only to Functions or Advanced Mode Pages projects
398
- if (directory && (usingFunctions || usingWorkerScript)) {
403
+ if (
404
+ directory &&
405
+ (usingFunctions || usingWorkerScript || usingWorkerDirectory)
406
+ ) {
399
407
  const routesJSONPath = join(directory, "_routes.json");
400
408
 
401
409
  if (existsSync(routesJSONPath)) {
@@ -503,7 +511,7 @@ export const Handler = async ({
503
511
  localProtocol,
504
512
  compatibilityDate,
505
513
  compatibilityFlags,
506
- nodeCompat,
514
+ nodeCompat: legacyNodeCompat,
507
515
  vars: Object.fromEntries(
508
516
  bindings
509
517
  .map((binding) => binding.toString().split("="))
@@ -537,11 +545,21 @@ export const Handler = async ({
537
545
  r2: r2s.map((binding) => {
538
546
  return { binding: binding.toString(), bucket_name: "" };
539
547
  }),
548
+ processEntrypoint: true,
549
+ moduleRoot: workerScriptPath,
550
+ rules: usingWorkerDirectory
551
+ ? [
552
+ {
553
+ type: "ESModule",
554
+ globs: ["**/*.js"],
555
+ },
556
+ ]
557
+ : undefined,
558
+ bundle: enableBundling,
540
559
  persist,
541
560
  persistTo,
542
561
  inspect: undefined,
543
- logPrefix: "pages",
544
- logLevel: logLevel ?? "warn",
562
+ logLevel,
545
563
  experimental: {
546
564
  d1Databases: d1s.map((binding) => ({
547
565
  binding: binding.toString(),
@@ -9,6 +9,7 @@ import { RoutesValidationError } from "./functions/routes-validation";
9
9
  * Exit code for `pages functions build` when no routes are found.
10
10
  */
11
11
  export const EXIT_CODE_FUNCTIONS_NO_ROUTES_ERROR = 156;
12
+ export const EXIT_CODE_FUNCTIONS_NOTHING_TO_BUILD_ERROR = 157;
12
13
 
13
14
  /**
14
15
  * Pages error when no routes are found in the functions directory
@@ -1,21 +1,24 @@
1
1
  import { access, lstat } from "node:fs/promises";
2
- import { dirname, relative, resolve } from "node:path";
2
+ import { relative, resolve } from "node:path";
3
3
  import { bundleWorker } from "../../bundle";
4
4
  import { getBasePath } from "../../paths";
5
5
  import { D1_BETA_PREFIX } from "../../worker";
6
6
  import { buildNotifierPlugin } from "./buildWorker";
7
7
  import type { Options as WorkerOptions } from "./buildWorker";
8
8
 
9
- type Options = Omit<WorkerOptions, "fallbackService" | "buildOutputDirectory">;
9
+ type Options = Omit<
10
+ WorkerOptions,
11
+ "outfile" | "fallbackService" | "buildOutputDirectory" | "nodejsCompat"
12
+ > & { outdir: string };
10
13
 
11
14
  export function buildPlugin({
12
15
  routesModule,
13
- outfile = "bundle.js",
16
+ outdir,
14
17
  minify = false,
15
18
  sourcemap = false,
16
19
  watch = false,
17
20
  onEnd = () => {},
18
- nodeCompat,
21
+ legacyNodeCompat,
19
22
  functionsDirectory,
20
23
  local,
21
24
  betaD1Shims,
@@ -25,14 +28,20 @@ export function buildPlugin({
25
28
  file: resolve(getBasePath(), "templates/pages-template-plugin.ts"),
26
29
  directory: functionsDirectory,
27
30
  format: "modules",
31
+ moduleRoot: functionsDirectory,
28
32
  },
29
- resolve(outfile),
33
+ resolve(outdir),
30
34
  {
31
35
  inject: [routesModule],
36
+ entryName: "index",
32
37
  minify,
33
38
  sourcemap,
34
39
  watch,
35
- nodeCompat,
40
+ legacyNodeCompat,
41
+ // We don't currently have a mechanism for Plugins 'requiring' a specific compat date/flag,
42
+ // but if someone wants to publish a Plugin which does require this new `nodejs_compat` flag
43
+ // and they document that on their README.md, we should let them.
44
+ nodejsCompat: true,
36
45
  define: {},
37
46
  betaD1Shims: (betaD1Shims || []).map(
38
47
  (binding) => `${D1_BETA_PREFIX}${binding}`
@@ -43,43 +52,57 @@ export function buildPlugin({
43
52
  {
44
53
  name: "Assets",
45
54
  setup(pluginBuild) {
46
- if (pluginBuild.initialOptions.outfile) {
47
- const outdir = dirname(pluginBuild.initialOptions.outfile);
55
+ pluginBuild.onResolve({ filter: /^assets:/ }, async (args) => {
56
+ const directory = resolve(
57
+ args.resolveDir,
58
+ args.path.slice("assets:".length)
59
+ );
48
60
 
49
- pluginBuild.onResolve({ filter: /^assets:/ }, async (args) => {
50
- const directory = resolve(
51
- args.resolveDir,
52
- args.path.slice("assets:".length)
53
- );
61
+ const exists = await access(directory)
62
+ .then(() => true)
63
+ .catch(() => false);
54
64
 
55
- const exists = await access(directory)
56
- .then(() => true)
57
- .catch(() => false);
65
+ const isDirectory =
66
+ exists && (await lstat(directory)).isDirectory();
58
67
 
59
- const isDirectory =
60
- exists && (await lstat(directory)).isDirectory();
68
+ if (!isDirectory) {
69
+ return {
70
+ errors: [
71
+ {
72
+ text: `'${directory}' does not exist or is not a directory.`,
73
+ },
74
+ ],
75
+ };
76
+ }
61
77
 
62
- if (!isDirectory) {
63
- return {
64
- errors: [
65
- {
66
- text: `'${directory}' does not exist or is not a directory.`,
67
- },
68
- ],
69
- };
70
- }
78
+ const path = `assets:./${relative(outdir, directory)}`;
71
79
 
72
- const path = `assets:./${relative(outdir, directory)}`;
73
-
74
- return { path, external: true, namespace: "assets" };
75
- });
76
- }
80
+ return { path, external: true, namespace: "assets" };
81
+ });
82
+ },
83
+ },
84
+ // TODO: Replace this with a proper outdir solution for Plugins
85
+ // But for now, let's just mark all wasm/bin files as external
86
+ {
87
+ name: "Mark externals",
88
+ setup(pluginBuild) {
89
+ pluginBuild.onResolve(
90
+ { filter: /.*\.(wasm|bin)$/ },
91
+ async (args) => {
92
+ return {
93
+ external: true,
94
+ path: `./${relative(
95
+ outdir,
96
+ resolve(args.resolveDir, args.path)
97
+ )}`,
98
+ };
99
+ }
100
+ );
77
101
  },
78
102
  },
79
103
  ],
80
- isOutfile: true,
81
104
  serveAssetsFromWorker: false,
82
- disableModuleCollection: true,
105
+ disableModuleCollection: false,
83
106
  rules: [],
84
107
  checkFetch: local,
85
108
  targetConsumer: local ? "dev" : "publish",
@@ -1,61 +1,66 @@
1
1
  import { access, cp, lstat, rm } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
2
3
  import { join, resolve } from "node:path";
3
4
  import { build as esBuild } from "esbuild";
4
5
  import { nanoid } from "nanoid";
5
6
  import { bundleWorker } from "../../bundle";
7
+ import { FatalError } from "../../errors";
6
8
  import { logger } from "../../logger";
7
9
  import { getBasePath } from "../../paths";
10
+ import traverseModuleGraph from "../../traverse-module-graph";
8
11
  import { D1_BETA_PREFIX } from "../../worker";
12
+ import type { BundleResult } from "../../bundle";
9
13
  import type { Plugin } from "esbuild";
10
14
 
11
15
  export type Options = {
12
16
  routesModule: string;
13
- outfile: string;
17
+ outfile?: string;
18
+ outdir?: string;
14
19
  minify?: boolean;
15
20
  sourcemap?: boolean;
16
21
  fallbackService?: string;
17
22
  watch?: boolean;
18
23
  onEnd?: () => void;
19
24
  buildOutputDirectory?: string;
20
- nodeCompat?: boolean;
25
+ legacyNodeCompat?: boolean;
26
+ nodejsCompat?: boolean;
21
27
  functionsDirectory: string;
22
28
  local: boolean;
23
29
  betaD1Shims?: string[];
24
- experimentalWorkerBundle?: boolean;
25
30
  };
26
31
 
27
32
  export function buildWorker({
28
33
  routesModule,
29
- outfile = "bundle.js",
34
+ outfile = join(tmpdir(), `./functionsWorker-${Math.random()}.js`),
35
+ outdir,
30
36
  minify = false,
31
37
  sourcemap = false,
32
38
  fallbackService = "ASSETS",
33
39
  watch = false,
34
40
  onEnd = () => {},
35
41
  buildOutputDirectory,
36
- nodeCompat,
42
+ legacyNodeCompat,
43
+ nodejsCompat,
37
44
  functionsDirectory,
38
45
  local,
39
46
  betaD1Shims,
40
- experimentalWorkerBundle = false,
41
47
  }: Options) {
42
48
  return bundleWorker(
43
49
  {
44
50
  file: resolve(getBasePath(), "templates/pages-template-worker.ts"),
45
51
  directory: functionsDirectory,
46
52
  format: "modules",
53
+ moduleRoot: functionsDirectory,
47
54
  },
48
- resolve(outfile),
55
+ outdir ? resolve(outdir) : resolve(outfile),
49
56
  {
50
57
  inject: [routesModule],
58
+ ...(outdir ? { entryName: "index" } : {}),
51
59
  minify,
52
60
  sourcemap,
53
61
  watch,
54
- nodeCompat,
55
- loader: {
56
- ".txt": "text",
57
- ".html": "text",
58
- },
62
+ legacyNodeCompat,
63
+ nodejsCompat,
59
64
  define: {
60
65
  __FALLBACK_SERVICE__: JSON.stringify(fallbackService),
61
66
  },
@@ -140,9 +145,9 @@ export function buildWorker({
140
145
  },
141
146
  },
142
147
  ],
143
- isOutfile: true,
148
+ isOutfile: !outdir,
144
149
  serveAssetsFromWorker: false,
145
- disableModuleCollection: experimentalWorkerBundle ? false : true,
150
+ disableModuleCollection: false,
146
151
  rules: [],
147
152
  checkFetch: local,
148
153
  targetConsumer: local ? "dev" : "publish",
@@ -154,18 +159,20 @@ export function buildWorker({
154
159
 
155
160
  export type RawOptions = {
156
161
  workerScriptPath: string;
157
- outfile: string;
162
+ outfile?: string;
163
+ outdir?: string;
158
164
  directory: string;
165
+ bundle?: boolean;
159
166
  minify?: boolean;
160
167
  sourcemap?: boolean;
161
168
  watch?: boolean;
162
169
  plugins?: Plugin[];
163
170
  onEnd?: () => void;
164
171
  buildOutputDirectory?: string;
165
- nodeCompat?: boolean;
172
+ legacyNodeCompat?: boolean;
173
+ nodejsCompat?: boolean;
166
174
  local: boolean;
167
175
  betaD1Shims?: string[];
168
- experimentalWorkerBundle?: boolean;
169
176
  };
170
177
 
171
178
  /**
@@ -177,43 +184,44 @@ export type RawOptions = {
177
184
  */
178
185
  export function buildRawWorker({
179
186
  workerScriptPath,
180
- outfile,
187
+ outfile = join(tmpdir(), `./functionsWorker-${Math.random()}.js`),
188
+ outdir,
181
189
  directory,
190
+ bundle = true,
182
191
  minify = false,
183
192
  sourcemap = false,
184
193
  watch = false,
185
194
  plugins = [],
186
195
  onEnd = () => {},
187
- nodeCompat,
196
+ legacyNodeCompat,
197
+ nodejsCompat,
188
198
  local,
189
199
  betaD1Shims,
190
- experimentalWorkerBundle = false,
191
200
  }: RawOptions) {
192
201
  return bundleWorker(
193
202
  {
194
203
  file: workerScriptPath,
195
204
  directory: resolve(directory),
196
205
  format: "modules",
206
+ moduleRoot: resolve(directory),
197
207
  },
198
- resolve(outfile),
208
+ outdir ? resolve(outdir) : resolve(outfile),
199
209
  {
210
+ bundle,
200
211
  minify,
201
212
  sourcemap,
202
213
  watch,
203
- nodeCompat,
204
- loader: {
205
- ".txt": "text",
206
- ".html": "text",
207
- },
214
+ legacyNodeCompat,
215
+ nodejsCompat,
208
216
  define: {},
209
217
  betaD1Shims: (betaD1Shims || []).map(
210
218
  (binding) => `${D1_BETA_PREFIX}${binding}`
211
219
  ),
212
220
  doBindings: [], // Pages functions don't support internal Durable Objects
213
221
  plugins: [...plugins, buildNotifierPlugin(onEnd)],
214
- isOutfile: true,
222
+ isOutfile: !outdir,
215
223
  serveAssetsFromWorker: false,
216
- disableModuleCollection: experimentalWorkerBundle ? false : true,
224
+ disableModuleCollection: false,
217
225
  rules: [],
218
226
  checkFetch: local,
219
227
  targetConsumer: local ? "dev" : "publish",
@@ -223,6 +231,58 @@ export function buildRawWorker({
223
231
  );
224
232
  }
225
233
 
234
+ export async function traverseAndBuildWorkerJSDirectory({
235
+ workerJSDirectory,
236
+ buildOutputDirectory,
237
+ d1Databases,
238
+ nodejsCompat,
239
+ }: {
240
+ workerJSDirectory: string;
241
+ buildOutputDirectory: string;
242
+ d1Databases?: string[];
243
+ nodejsCompat?: boolean;
244
+ }): Promise<BundleResult> {
245
+ const entrypoint = resolve(join(workerJSDirectory, "index.js"));
246
+
247
+ const traverseModuleGraphResult = await traverseModuleGraph(
248
+ {
249
+ file: entrypoint,
250
+ directory: resolve(workerJSDirectory),
251
+ format: "modules",
252
+ moduleRoot: resolve(workerJSDirectory),
253
+ },
254
+ [
255
+ {
256
+ type: "ESModule",
257
+ globs: ["**/*.js"],
258
+ },
259
+ ]
260
+ );
261
+
262
+ const outfile = join(tmpdir(), `./bundledWorker-${Math.random()}.mjs`);
263
+ const bundleResult = await buildRawWorker({
264
+ workerScriptPath: entrypoint,
265
+ bundle: false,
266
+ outfile,
267
+ directory: buildOutputDirectory,
268
+ local: false,
269
+ sourcemap: true,
270
+ watch: false,
271
+ onEnd: () => {},
272
+ betaD1Shims: d1Databases,
273
+ nodejsCompat,
274
+ });
275
+
276
+ return {
277
+ modules: traverseModuleGraphResult.modules,
278
+ dependencies: bundleResult.dependencies,
279
+ resolvedEntryPointPath: bundleResult.resolvedEntryPointPath,
280
+ bundleType: bundleResult.bundleType,
281
+ stop: bundleResult.stop,
282
+ sourceMapPath: bundleResult.sourceMapPath,
283
+ };
284
+ }
285
+
226
286
  /**
227
287
  * Creates an esbuild plugin that can notify Wrangler (via the `onEnd()`)
228
288
  * when the build completes.
@@ -277,12 +337,12 @@ const blockWorkerJsImports: Plugin = {
277
337
  };
278
338
  }
279
339
  // Otherwise, block any imports that the file is requesting
280
- logger.error(
340
+ throw new FatalError(
281
341
  "_worker.js is not being bundled by Wrangler but it is importing from another file.\n" +
282
342
  "This will throw an error if deployed.\n" +
283
- "You should bundle the Worker in a pre-build step, remove the import if it is unused, or ask Wrangler to bundle it by setting `--bundle`."
343
+ "You should bundle the Worker in a pre-build step, remove the import if it is unused, or ask Wrangler to bundle it by setting `--bundle`.",
344
+ 1
284
345
  );
285
- process.exit(1);
286
346
  });
287
347
  },
288
348
  };