@cloudflare/vite-plugin 0.0.0-9b86dba81 → 0.0.0-9c844f771

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # `@cloudflare/vite-plugin`
2
2
 
3
- [Intro](#intro) | [Quick start](#quick-start) | [Tutorial](#tutorial) | [API](#api) | [Cloudflare environments](#cloudflare-environments) | [Migrating from `wrangler dev`](#migrating-from-wrangler-dev)
3
+ [Intro](#intro) | [Quick start](#quick-start) | [Tutorial](#tutorial) | [API](#api) | [Cloudflare environments](#cloudflare-environments) | [Debugging](#debugging) | [Migrating from `wrangler dev`](#migrating-from-wrangler-dev)
4
4
 
5
5
  ## Intro
6
6
 
@@ -374,6 +374,10 @@ It accepts an optional `PluginConfig` parameter.
374
374
  All requests are routed through your entry Worker.
375
375
  During the build, each Worker is output to a separate subdirectory of `dist`.
376
376
 
377
+ - `inspectorPort?: number | false`
378
+
379
+ Optional inspector port to use for debugging your workers, for more details on debugging see the [devtools section](#devtools). Can be set to `false` to disable the debugging inspector altogether. Defaults to `9229`.
380
+
377
381
  > [!NOTE]
378
382
  > When running `wrangler deploy`, only your main (entry) Worker will be deployed.
379
383
  > If using multiple Workers, each must be deployed individually.
@@ -482,6 +486,62 @@ Secrets can be provided to your Worker in local development using a [`.dev.vars`
482
486
  > [!NOTE]
483
487
  > The `vite build` command copies the relevant `.dev.vars[.env-name]` file to the output directory. This is only used when running `vite preview` and is not deployed with your Worker.
484
488
 
489
+ ## Debugging
490
+
491
+ The Cloudflare Vite plugin allows you to conveniently debug your Worker code during local development.
492
+
493
+ By default the inspector port used by the plugin is `9229`, which can be customized by providing a different port to the plugin's `inspectorPort` option.
494
+
495
+ There are two recommended ways of doing so, which we'll explore in this section.
496
+
497
+ ### Devtools
498
+
499
+ When running `vite dev` or `vite preview` a `/__debug` route in your local server will be made available which gives you access to [Cloudflare's implementation](/packages/chrome-devtools-patches) of [Chrome's DevTools](https://developer.chrome.com/docs/devtools/overview).
500
+
501
+ Navigating to this route will open a devtools tab for each of the workers in your application (Note: in case of multiple workers you might need to allow your browser to open pop-ups).
502
+
503
+ Once the tab or tabs are open, you can make a request to your application and start debugging your workers' code.
504
+
505
+ Note: If you're not interested in debugging all your workers you can close the tabs of the workers you don't want to debug.
506
+
507
+ ### VS Code
508
+
509
+ To setup VS Code for breakpoint debugging for your application, you will need to create a `.vscode/launch.json` file that contains a configuration following this structure:
510
+
511
+ ```json
512
+ {
513
+ "configurations": [
514
+ {
515
+ "name": "<NAME_OF_WORKER>",
516
+ "type": "node",
517
+ "request": "attach",
518
+ "websocketAddress": "ws://localhost:9229/<NAME_OF_WORKER>",
519
+ "resolveSourceMapLocations": null,
520
+ "attachExistingChildren": false,
521
+ "autoAttachChildProcesses": false,
522
+ "sourceMaps": true
523
+ }
524
+ ],
525
+ "compounds": [
526
+ {
527
+ "name": "Debug All Workers",
528
+ "configurations": ["<NAME_OF_WORKER>"],
529
+ "stopAll": true
530
+ }
531
+ ]
532
+ }
533
+ ```
534
+
535
+ Where, `<NAME_OF_WORKER>` indicates the name of your worker as specified in your Wrangler configuration.
536
+
537
+ Note: if you customized your `inspectorPort` you need to use that port in the `websocketAddress` field.
538
+
539
+ If you have more than one worker you need add a configuration in the `configurations` field for each one and then include the configuration name in the `configurations` array in the compound configuration.
540
+
541
+ Once your `launch.json` file is ready, after running `vite dev` or `vite preview` you can select **Debug All Workers** at the top of the **Run & Debug** panel to attach debuggers to all the various Workers. Then you can add breakpoints to your code and start debugging.
542
+
543
+ Note: You can also manually select the configurations to run (e.g. **Debug Worker1**) to filter which workers you want to debug.
544
+
485
545
  ## Migrating from `wrangler dev`
486
546
 
487
547
  Migrating from `wrangler dev` is a simple process and you can follow the instructions in the [Quick start](#quick-start) to get started.
@@ -2487,6 +2487,13 @@ var CustomAssetWorker = class extends fr {
2487
2487
  const exists = await response.json();
2488
2488
  return exists ? pathname : null;
2489
2489
  }
2490
+ async unstable_canFetch(request) {
2491
+ const secFetchMode = request.headers.get("X-Mf-Sec-Fetch-Mode");
2492
+ if (secFetchMode) {
2493
+ request.headers.set("Sec-Fetch-Mode", secFetchMode);
2494
+ }
2495
+ return await super.unstable_canFetch(request);
2496
+ }
2490
2497
  };
2491
2498
  export {
2492
2499
  CustomAssetWorker as default
package/dist/index.d.ts CHANGED
@@ -17,6 +17,7 @@ interface AuxiliaryWorkerConfig extends BaseWorkerConfig {
17
17
  interface PluginConfig extends EntryWorkerConfig {
18
18
  auxiliaryWorkers?: AuxiliaryWorkerConfig[];
19
19
  persistState?: PersistState;
20
+ inspectorPort?: number | false;
20
21
  }
21
22
 
22
23
  /**
@@ -28,4 +29,4 @@ interface PluginConfig extends EntryWorkerConfig {
28
29
  */
29
30
  declare function cloudflare(pluginConfig?: PluginConfig): vite.Plugin[];
30
31
 
31
- export { cloudflare };
32
+ export { type PluginConfig, cloudflare };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- import assert7 from "node:assert";
2
+ import assert8 from "node:assert";
3
3
  import * as fs5 from "node:fs";
4
4
  import * as fsp2 from "node:fs/promises";
5
5
  import { builtinModules as builtinModules2 } from "node:module";
@@ -1083,6 +1083,7 @@ var ADDITIONAL_MODULE_TYPES = [
1083
1083
  "Data",
1084
1084
  "Text"
1085
1085
  ];
1086
+ var DEFAULT_INSPECTOR_PORT = 9229;
1086
1087
 
1087
1088
  // src/additional-modules.ts
1088
1089
  var moduleRules = [
@@ -8154,6 +8155,10 @@ function getRouterWorker(miniflare) {
8154
8155
  return miniflare.getWorker(ROUTER_WORKER_NAME);
8155
8156
  }
8156
8157
  function toMiniflareRequest(request) {
8158
+ const secFetchMode = request.headers.get("Sec-Fetch-Mode");
8159
+ if (secFetchMode) {
8160
+ request.headers.set("X-Mf-Sec-Fetch-Mode", secFetchMode);
8161
+ }
8157
8162
  return new MiniflareRequest(request.url, {
8158
8163
  method: request.method,
8159
8164
  headers: [["accept-encoding", "identity"], ...request.headers],
@@ -8341,15 +8346,65 @@ function initRunners(resolvedPluginConfig, viteDevServer, miniflare) {
8341
8346
  );
8342
8347
  }
8343
8348
 
8344
- // src/deploy-config.ts
8349
+ // src/debugging.ts
8345
8350
  import assert4 from "node:assert";
8351
+ import colors from "picocolors";
8352
+ var debuggingPath = "/__debug";
8353
+ function addDebugToVitePrintUrls(server) {
8354
+ const originalPrintUrls = server.printUrls;
8355
+ server.printUrls = () => {
8356
+ originalPrintUrls();
8357
+ const localUrl = server.resolvedUrls?.local[0];
8358
+ if (localUrl) {
8359
+ const { protocol, hostname, port } = new URL(localUrl);
8360
+ const colorDebugUrl = (url) => colors.dim(
8361
+ colors.yellow(
8362
+ url.replace(/:(\d+)\//, (_, port2) => `:${colors.bold(port2)}/`)
8363
+ )
8364
+ );
8365
+ server.config.logger.info(
8366
+ ` ${colors.green("\u279C")} ${colors.bold("Debug")}: ${colorDebugUrl(`${protocol}//${hostname}:${port}${debuggingPath}`)}`
8367
+ );
8368
+ }
8369
+ };
8370
+ }
8371
+ function getDebugPathHtml(workerNames, inspectorPort) {
8372
+ assert4(workerNames.length >= 1, "no workers present to debug");
8373
+ const workerDevtoolsUrls = workerNames.map((workerName) => {
8374
+ const localHost = `localhost:${inspectorPort}/${workerName}`;
8375
+ const searchParams = new URLSearchParams({
8376
+ theme: "systemPreferred",
8377
+ debugger: "true",
8378
+ ws: localHost,
8379
+ domain: workerName
8380
+ });
8381
+ const devtoolsFrontendUrl = `https://devtools.devprod.cloudflare.dev/js_app?${searchParams}`;
8382
+ return devtoolsFrontendUrl;
8383
+ });
8384
+ return `
8385
+ <script>
8386
+ const workerUrls = ${JSON.stringify(workerDevtoolsUrls)};
8387
+ const [firstUrl, ...rest] = workerUrls;
8388
+ for (const workerUrl of rest) {
8389
+ // open new tabs for the devtools of the various workers
8390
+ window.open(workerUrl);
8391
+ }
8392
+ // redirect the current tab to the devtools of the first worker
8393
+ window.location.replace(firstUrl);
8394
+ </script>
8395
+ `;
8396
+ }
8397
+
8398
+ // src/deploy-config.ts
8399
+ import assert5 from "node:assert";
8346
8400
  import * as fs2 from "node:fs";
8347
8401
  import * as path3 from "node:path";
8348
8402
  import "vite";
8403
+ import { unstable_readConfig } from "wrangler";
8349
8404
  function getDeployConfigPath(root) {
8350
8405
  return path3.resolve(root, ".wrangler", "deploy", "config.json");
8351
8406
  }
8352
- function getWorkerConfigPaths(root) {
8407
+ function getWorkerConfigs(root) {
8353
8408
  const deployConfigPath = getDeployConfigPath(root);
8354
8409
  const deployConfig = JSON.parse(
8355
8410
  fs2.readFileSync(deployConfigPath, "utf-8")
@@ -8357,9 +8412,13 @@ function getWorkerConfigPaths(root) {
8357
8412
  return [
8358
8413
  { configPath: deployConfig.configPath },
8359
8414
  ...deployConfig.auxiliaryWorkers
8360
- ].map(
8361
- ({ configPath }) => path3.resolve(path3.dirname(deployConfigPath), configPath)
8362
- );
8415
+ ].map(({ configPath }) => {
8416
+ const resolvedConfigPath = path3.resolve(
8417
+ path3.dirname(deployConfigPath),
8418
+ configPath
8419
+ );
8420
+ return unstable_readConfig({ config: resolvedConfigPath });
8421
+ });
8363
8422
  }
8364
8423
  function getRelativePathToWorkerConfig(deployConfigDirectory, root, outputDirectory) {
8365
8424
  return path3.relative(
@@ -8373,7 +8432,7 @@ function writeDeployConfig(resolvedPluginConfig, resolvedViteConfig) {
8373
8432
  fs2.mkdirSync(deployConfigDirectory, { recursive: true });
8374
8433
  if (resolvedPluginConfig.type === "assets-only") {
8375
8434
  const clientOutputDirectory = resolvedViteConfig.environments.client?.build.outDir;
8376
- assert4(
8435
+ assert5(
8377
8436
  clientOutputDirectory,
8378
8437
  "Unexpected error: client environment output directory is undefined"
8379
8438
  );
@@ -8391,7 +8450,7 @@ function writeDeployConfig(resolvedPluginConfig, resolvedViteConfig) {
8391
8450
  const auxiliaryWorkers = [];
8392
8451
  for (const environmentName of Object.keys(resolvedPluginConfig.workers)) {
8393
8452
  const outputDirectory = resolvedViteConfig.environments[environmentName]?.build.outDir;
8394
- assert4(
8453
+ assert5(
8395
8454
  outputDirectory,
8396
8455
  `Unexpected error: ${environmentName} environment output directory is undefined`
8397
8456
  );
@@ -8406,7 +8465,7 @@ function writeDeployConfig(resolvedPluginConfig, resolvedViteConfig) {
8406
8465
  auxiliaryWorkers.push({ configPath });
8407
8466
  }
8408
8467
  }
8409
- assert4(
8468
+ assert5(
8410
8469
  entryWorkerConfigPath,
8411
8470
  `Unexpected error: entryWorkerConfigPath is undefined`
8412
8471
  );
@@ -8419,7 +8478,7 @@ function writeDeployConfig(resolvedPluginConfig, resolvedViteConfig) {
8419
8478
  }
8420
8479
 
8421
8480
  // src/miniflare-options.ts
8422
- import assert5 from "node:assert";
8481
+ import assert6 from "node:assert";
8423
8482
  import * as fs3 from "node:fs";
8424
8483
  import * as fsp from "node:fs/promises";
8425
8484
  import * as path4 from "node:path";
@@ -8433,8 +8492,7 @@ import {
8433
8492
  import { globSync } from "tinyglobby";
8434
8493
  import "vite";
8435
8494
  import {
8436
- unstable_getMiniflareWorkerOptions,
8437
- unstable_readConfig
8495
+ unstable_getMiniflareWorkerOptions
8438
8496
  } from "wrangler";
8439
8497
  function getPersistence(root, persistState) {
8440
8498
  if (persistState === false) {
@@ -8467,7 +8525,7 @@ function getWorkerToWorkerEntrypointNamesMap(workers) {
8467
8525
  if (typeof value === "object" && "name" in value && value.entrypoint !== void 0 && value.entrypoint !== "default") {
8468
8526
  const targetWorkerName = value.name === kCurrentWorker ? worker.name : value.name;
8469
8527
  const entrypointNames = workerToWorkerEntrypointNamesMap.get(targetWorkerName);
8470
- assert5(entrypointNames, missingWorkerErrorMessage(targetWorkerName));
8528
+ assert6(entrypointNames, missingWorkerErrorMessage(targetWorkerName));
8471
8529
  entrypointNames.add(value.entrypoint);
8472
8530
  }
8473
8531
  }
@@ -8482,20 +8540,20 @@ function getWorkerToDurableObjectClassNamesMap(workers) {
8482
8540
  for (const value of Object.values(worker.durableObjects ?? {})) {
8483
8541
  if (typeof value === "string") {
8484
8542
  const classNames = workerToDurableObjectClassNamesMap.get(worker.name);
8485
- assert5(classNames, missingWorkerErrorMessage(worker.name));
8543
+ assert6(classNames, missingWorkerErrorMessage(worker.name));
8486
8544
  classNames.add(value);
8487
8545
  } else if (typeof value === "object") {
8488
8546
  if (value.scriptName) {
8489
8547
  const classNames = workerToDurableObjectClassNamesMap.get(
8490
8548
  value.scriptName
8491
8549
  );
8492
- assert5(classNames, missingWorkerErrorMessage(value.scriptName));
8550
+ assert6(classNames, missingWorkerErrorMessage(value.scriptName));
8493
8551
  classNames.add(value.className);
8494
8552
  } else {
8495
8553
  const classNames = workerToDurableObjectClassNamesMap.get(
8496
8554
  worker.name
8497
8555
  );
8498
- assert5(classNames, missingWorkerErrorMessage(worker.name));
8556
+ assert6(classNames, missingWorkerErrorMessage(worker.name));
8499
8557
  classNames.add(value.className);
8500
8558
  }
8501
8559
  }
@@ -8513,13 +8571,13 @@ function getWorkerToWorkflowEntrypointClassNamesMap(workers) {
8513
8571
  const classNames = workerToWorkflowEntrypointClassNamesMap.get(
8514
8572
  value.scriptName
8515
8573
  );
8516
- assert5(classNames, missingWorkerErrorMessage(value.scriptName));
8574
+ assert6(classNames, missingWorkerErrorMessage(value.scriptName));
8517
8575
  classNames.add(value.className);
8518
8576
  } else {
8519
8577
  const classNames = workerToWorkflowEntrypointClassNamesMap.get(
8520
8578
  worker.name
8521
8579
  );
8522
- assert5(classNames, missingWorkerErrorMessage(worker.name));
8580
+ assert6(classNames, missingWorkerErrorMessage(worker.name));
8523
8581
  classNames.add(value.className);
8524
8582
  }
8525
8583
  }
@@ -8541,6 +8599,13 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
8541
8599
  const resolvedViteConfig = viteDevServer.config;
8542
8600
  const entryWorkerConfig = getEntryWorkerConfig(resolvedPluginConfig);
8543
8601
  const assetsConfig = resolvedPluginConfig.type === "assets-only" ? resolvedPluginConfig.config.assets : entryWorkerConfig?.assets;
8602
+ const compatibilityOptions = resolvedPluginConfig.type === "assets-only" ? {
8603
+ compatibility_date: resolvedPluginConfig.config.compatibility_date,
8604
+ compatibility_flags: resolvedPluginConfig.config.compatibility_flags
8605
+ } : {
8606
+ ...entryWorkerConfig?.compatibility_date ? { compatibility_date: entryWorkerConfig?.compatibility_date } : {},
8607
+ ...entryWorkerConfig?.compatibility_flags ? { compatibility_flags: entryWorkerConfig?.compatibility_flags } : {}
8608
+ };
8544
8609
  const assetWorkers = [
8545
8610
  {
8546
8611
  name: ROUTER_WORKER_NAME,
@@ -8580,6 +8645,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
8580
8645
  ],
8581
8646
  bindings: {
8582
8647
  CONFIG: {
8648
+ ...compatibilityOptions,
8583
8649
  ...assetsConfig?.html_handling ? { html_handling: assetsConfig.html_handling } : {},
8584
8650
  ...assetsConfig?.not_found_handling ? { not_found_handling: assetsConfig.not_found_handling } : {}
8585
8651
  }
@@ -8628,6 +8694,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
8628
8694
  worker: {
8629
8695
  ...workerOptions,
8630
8696
  name: workerOptions.name ?? workerConfig.name,
8697
+ unsafeInspectorProxy: resolvedPluginConfig.inspectorPort !== false,
8631
8698
  modulesRoot: miniflareModulesRoot,
8632
8699
  unsafeEvalBinding: "__VITE_UNSAFE_EVAL__",
8633
8700
  serviceBindings: {
@@ -8638,7 +8705,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
8638
8705
  __VITE_INVOKE_MODULE__: async (request) => {
8639
8706
  const payload = await request.json();
8640
8707
  const invokePayloadData = payload.data;
8641
- assert5(
8708
+ assert6(
8642
8709
  invokePayloadData.name === "fetchModule",
8643
8710
  `Invalid invoke event: ${invokePayloadData.name}`
8644
8711
  );
@@ -8669,6 +8736,8 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
8669
8736
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
8670
8737
  return {
8671
8738
  log: logger,
8739
+ inspectorPort: resolvedPluginConfig.inspectorPort || void 0,
8740
+ unsafeInspectorProxy: resolvedPluginConfig.inspectorPort !== false,
8672
8741
  handleRuntimeStdio(stdout, stderr) {
8673
8742
  const decoder = new TextDecoder();
8674
8743
  stdout.forEach((data2) => logger.info(decoder.decode(data2)));
@@ -8691,7 +8760,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
8691
8760
  const workerEntrypointNames = workerToWorkerEntrypointNamesMap.get(
8692
8761
  workerOptions.name
8693
8762
  );
8694
- assert5(
8763
+ assert6(
8695
8764
  workerEntrypointNames,
8696
8765
  `WorkerEntrypoint names not found for worker ${workerOptions.name}`
8697
8766
  );
@@ -8703,7 +8772,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
8703
8772
  const durableObjectClassNames = workerToDurableObjectClassNamesMap.get(
8704
8773
  workerOptions.name
8705
8774
  );
8706
- assert5(
8775
+ assert6(
8707
8776
  durableObjectClassNames,
8708
8777
  `DurableObject class names not found for worker ${workerOptions.name}`
8709
8778
  );
@@ -8713,7 +8782,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
8713
8782
  );
8714
8783
  }
8715
8784
  const workflowEntrypointClassNames = workerToWorkflowEntrypointClassNamesMap.get(workerOptions.name);
8716
- assert5(
8785
+ assert6(
8717
8786
  workflowEntrypointClassNames,
8718
8787
  `WorkflowEntrypoint class names not found for worker: ${workerOptions.name}`
8719
8788
  );
@@ -8745,18 +8814,18 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
8745
8814
  async unsafeModuleFallbackService(request) {
8746
8815
  const url = new URL(request.url);
8747
8816
  const rawSpecifier = url.searchParams.get("rawSpecifier");
8748
- assert5(
8817
+ assert6(
8749
8818
  rawSpecifier,
8750
8819
  `Unexpected error: no specifier in request to module fallback service.`
8751
8820
  );
8752
8821
  const match = additionalModuleRE.exec(rawSpecifier);
8753
- assert5(match, `Unexpected error: no match for module: ${rawSpecifier}.`);
8822
+ assert6(match, `Unexpected error: no match for module: ${rawSpecifier}.`);
8754
8823
  const [full, moduleType, modulePath] = match;
8755
- assert5(
8824
+ assert6(
8756
8825
  moduleType,
8757
8826
  `Unexpected error: module type not found in reference: ${full}.`
8758
8827
  );
8759
- assert5(
8828
+ assert6(
8760
8829
  modulePath,
8761
8830
  `Unexpected error: module path not found in reference: ${full}.`
8762
8831
  );
@@ -8786,7 +8855,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
8786
8855
  };
8787
8856
  }
8788
8857
  function getPreviewModules(main, modulesRules) {
8789
- assert5(modulesRules, `Unexpected error: 'modulesRules' is undefined`);
8858
+ assert6(modulesRules, `Unexpected error: 'modulesRules' is undefined`);
8790
8859
  const rootPath = path4.dirname(main);
8791
8860
  const entryPath = path4.basename(main);
8792
8861
  return {
@@ -8805,12 +8874,8 @@ function getPreviewModules(main, modulesRules) {
8805
8874
  ]
8806
8875
  };
8807
8876
  }
8808
- function getPreviewMiniflareOptions(vitePreviewServer, persistState) {
8877
+ function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, inspectorPort = DEFAULT_INSPECTOR_PORT) {
8809
8878
  const resolvedViteConfig = vitePreviewServer.config;
8810
- const configPaths = getWorkerConfigPaths(resolvedViteConfig.root);
8811
- const workerConfigs = configPaths.map(
8812
- (configPath) => unstable_readConfig({ config: configPath })
8813
- );
8814
8879
  const workers = workerConfigs.flatMap((config) => {
8815
8880
  const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(config);
8816
8881
  const { externalWorkers } = miniflareWorkerOptions;
@@ -8819,6 +8884,7 @@ function getPreviewMiniflareOptions(vitePreviewServer, persistState) {
8819
8884
  {
8820
8885
  ...workerOptions,
8821
8886
  name: workerOptions.name ?? config.name,
8887
+ unsafeInspectorProxy: inspectorPort !== false,
8822
8888
  ...miniflareWorkerOptions.main ? getPreviewModules(miniflareWorkerOptions.main, modulesRules) : { modules: true, script: "" }
8823
8889
  },
8824
8890
  ...externalWorkers
@@ -8827,6 +8893,8 @@ function getPreviewMiniflareOptions(vitePreviewServer, persistState) {
8827
8893
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
8828
8894
  return {
8829
8895
  log: logger,
8896
+ inspectorPort: inspectorPort || void 0,
8897
+ unsafeInspectorProxy: inspectorPort !== false,
8830
8898
  handleRuntimeStdio(stdout, stderr) {
8831
8899
  const decoder = new TextDecoder();
8832
8900
  stdout.forEach((data2) => logger.info(decoder.decode(data2)));
@@ -8872,14 +8940,14 @@ function miniflareLogLevelFromViteLogLevel(level = "info") {
8872
8940
  }
8873
8941
 
8874
8942
  // src/plugin-config.ts
8875
- import assert6 from "node:assert";
8943
+ import assert7 from "node:assert";
8876
8944
  import * as path6 from "node:path";
8877
8945
  import * as vite5 from "vite";
8878
8946
 
8879
8947
  // src/workers-configs.ts
8880
8948
  import * as fs4 from "node:fs";
8881
8949
  import * as path5 from "node:path";
8882
- import { unstable_readConfig as unstable_readConfig2 } from "wrangler";
8950
+ import { unstable_readConfig as unstable_readConfig3 } from "wrangler";
8883
8951
  var nonApplicableWorkerConfigs = {
8884
8952
  /**
8885
8953
  * Object containing configs that have a vite replacement, the object's field contain details about the config's replacement
@@ -8930,7 +8998,7 @@ function readWorkerConfig(configPath, env2) {
8930
8998
  replacedByVite: /* @__PURE__ */ new Set(),
8931
8999
  notRelevant: /* @__PURE__ */ new Set()
8932
9000
  };
8933
- const config = unstable_readConfig2({ config: configPath, env: env2 }, {});
9001
+ const config = unstable_readConfig3({ config: configPath, env: env2 }, {});
8934
9002
  const raw = structuredClone(config);
8935
9003
  nullableNonApplicable.forEach((prop) => {
8936
9004
  if (config[prop] !== void 0) {
@@ -9101,6 +9169,7 @@ function workerNameToEnvironmentName(workerName) {
9101
9169
  function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
9102
9170
  const configPaths = /* @__PURE__ */ new Set();
9103
9171
  const persistState = pluginConfig.persistState ?? true;
9172
+ const inspectorPort = pluginConfig.inspectorPort ?? DEFAULT_INSPECTOR_PORT;
9104
9173
  const root = userConfig.root ? path6.resolve(userConfig.root) : process.cwd();
9105
9174
  const { CLOUDFLARE_ENV: cloudflareEnv } = vite5.loadEnv(
9106
9175
  viteEnv.mode,
@@ -9123,6 +9192,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
9123
9192
  type: "assets-only",
9124
9193
  config: entryWorkerResolvedConfig.config,
9125
9194
  configPaths,
9195
+ inspectorPort,
9126
9196
  persistState,
9127
9197
  rawConfigs: {
9128
9198
  entryWorker: entryWorkerResolvedConfig
@@ -9145,7 +9215,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
9145
9215
  }
9146
9216
  );
9147
9217
  auxiliaryWorkersResolvedConfigs.push(workerResolvedConfig);
9148
- assert6(
9218
+ assert7(
9149
9219
  workerResolvedConfig.type === "worker",
9150
9220
  "Unexpected error: received AssetsOnlyResult with auxiliary workers."
9151
9221
  );
@@ -9162,6 +9232,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
9162
9232
  type: "workers",
9163
9233
  configPaths,
9164
9234
  persistState,
9235
+ inspectorPort,
9165
9236
  workers,
9166
9237
  entryWorkerEnvironmentName,
9167
9238
  rawConfigs: {
@@ -9276,7 +9347,7 @@ function cloudflare2(pluginConfig = {}) {
9276
9347
  resolvedPluginConfig.workers
9277
9348
  ).map((environmentName) => {
9278
9349
  const environment = builder.environments[environmentName];
9279
- assert7(
9350
+ assert8(
9280
9351
  environment,
9281
9352
  `${environmentName} environment not found`
9282
9353
  );
@@ -9317,7 +9388,7 @@ function cloudflare2(pluginConfig = {}) {
9317
9388
  if (isEntryWorker && hasClientBuild) {
9318
9389
  const workerOutputDirectory = this.environment.config.build.outDir;
9319
9390
  const clientOutputDirectory = resolvedViteConfig.environments.client?.build.outDir;
9320
- assert7(
9391
+ assert8(
9321
9392
  clientOutputDirectory,
9322
9393
  "Unexpected error: client output directory is undefined"
9323
9394
  );
@@ -9392,7 +9463,7 @@ function cloudflare2(pluginConfig = {}) {
9392
9463
  }
9393
9464
  },
9394
9465
  async configureServer(viteDevServer) {
9395
- assert7(
9466
+ assert8(
9396
9467
  viteDevServer.httpServer,
9397
9468
  "Unexpected error: No Vite HTTP server"
9398
9469
  );
@@ -9417,10 +9488,13 @@ function cloudflare2(pluginConfig = {}) {
9417
9488
  };
9418
9489
  },
9419
9490
  configurePreviewServer(vitePreviewServer) {
9491
+ const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
9420
9492
  const miniflare2 = new Miniflare(
9421
9493
  getPreviewMiniflareOptions(
9422
9494
  vitePreviewServer,
9423
- pluginConfig.persistState ?? true
9495
+ workerConfigs,
9496
+ pluginConfig.persistState ?? true,
9497
+ pluginConfig.inspectorPort
9424
9498
  )
9425
9499
  );
9426
9500
  const middleware = createMiddleware(
@@ -9437,6 +9511,25 @@ function cloudflare2(pluginConfig = {}) {
9437
9511
  });
9438
9512
  }
9439
9513
  },
9514
+ // Plugin to support `.wasm?init` extension
9515
+ {
9516
+ name: "vite-plugin-cloudflare:wasm-helper",
9517
+ enforce: "pre",
9518
+ applyToEnvironment(environment) {
9519
+ return getWorkerConfig2(environment.name) !== void 0;
9520
+ },
9521
+ load(id) {
9522
+ if (!id.endsWith(".wasm?init")) {
9523
+ return;
9524
+ }
9525
+ return `
9526
+ import wasm from "${cleanUrl(id)}";
9527
+ export default function(opts = {}) {
9528
+ return WebAssembly.instantiate(wasm, opts);
9529
+ }
9530
+ `;
9531
+ }
9532
+ },
9440
9533
  // Plugin to support additional modules
9441
9534
  {
9442
9535
  name: "vite-plugin-cloudflare:additional-modules",
@@ -9476,7 +9569,7 @@ function cloudflare2(pluginConfig = {}) {
9476
9569
  for (const match of matches) {
9477
9570
  magicString ??= new MagicString(code);
9478
9571
  const [full, _, modulePath] = match;
9479
- assert7(
9572
+ assert8(
9480
9573
  modulePath,
9481
9574
  `Unexpected error: module path not found in reference ${full}.`
9482
9575
  );
@@ -9559,7 +9652,7 @@ function cloudflare2(pluginConfig = {}) {
9559
9652
  return this.resolve(source, importer, options);
9560
9653
  }
9561
9654
  if (this.environment.mode === "dev") {
9562
- assert7(
9655
+ assert8(
9563
9656
  this.environment.depsOptimizer,
9564
9657
  "depsOptimizer is required in dev mode"
9565
9658
  );
@@ -9573,16 +9666,63 @@ function cloudflare2(pluginConfig = {}) {
9573
9666
  },
9574
9667
  async transform(code, id) {
9575
9668
  const workerConfig = getWorkerConfig2(this.environment.name);
9576
- assert7(workerConfig, "Expected a worker config");
9669
+ assert8(workerConfig, "Expected a worker config");
9577
9670
  const resolvedId = await this.resolve(workerConfig.main);
9578
9671
  if (id === resolvedId?.id) {
9579
9672
  return injectGlobalCode(id, code);
9580
9673
  }
9581
9674
  }
9675
+ },
9676
+ // Plugin that provides an __debug path for debugging the Cloudflare Workers.
9677
+ {
9678
+ name: "vite-plugin-cloudflare:debug",
9679
+ // Note: this plugin needs to run before the main vite-plugin-cloudflare so that
9680
+ // the preview middleware here can take precedence
9681
+ enforce: "pre",
9682
+ configureServer(viteDevServer) {
9683
+ if (resolvedPluginConfig.type === "workers" && resolvedPluginConfig.inspectorPort !== false) {
9684
+ addDebugToVitePrintUrls(viteDevServer);
9685
+ }
9686
+ const workerNames = resolvedPluginConfig.type === "assets-only" ? [] : Object.values(resolvedPluginConfig.workers).map(
9687
+ (worker) => worker.name
9688
+ );
9689
+ viteDevServer.middlewares.use((req, res, next) => {
9690
+ if (req.url === debuggingPath && resolvedPluginConfig.inspectorPort !== false) {
9691
+ const html = getDebugPathHtml(
9692
+ workerNames,
9693
+ resolvedPluginConfig.inspectorPort
9694
+ );
9695
+ res.setHeader("Content-Type", "text/html");
9696
+ return res.end(html);
9697
+ }
9698
+ next();
9699
+ });
9700
+ },
9701
+ configurePreviewServer(vitePreviewServer) {
9702
+ const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
9703
+ if (workerConfigs.length >= 1 && pluginConfig.inspectorPort !== false) {
9704
+ addDebugToVitePrintUrls(vitePreviewServer);
9705
+ }
9706
+ const workerNames = workerConfigs.map((worker) => {
9707
+ assert8(worker.name);
9708
+ return worker.name;
9709
+ });
9710
+ vitePreviewServer.middlewares.use((req, res, next) => {
9711
+ if (req.url === debuggingPath && pluginConfig.inspectorPort !== false) {
9712
+ const html = getDebugPathHtml(
9713
+ workerNames,
9714
+ pluginConfig.inspectorPort ?? DEFAULT_INSPECTOR_PORT
9715
+ );
9716
+ res.setHeader("Content-Type", "text/html");
9717
+ return res.end(html);
9718
+ }
9719
+ next();
9720
+ });
9721
+ }
9582
9722
  }
9583
9723
  ];
9584
9724
  function getWorkerConfig2(environmentName) {
9585
- assert7(resolvedPluginConfig, "Expected resolvedPluginConfig to be defined");
9725
+ assert8(resolvedPluginConfig, "Expected resolvedPluginConfig to be defined");
9586
9726
  return resolvedPluginConfig.type !== "assets-only" ? resolvedPluginConfig.workers[environmentName] : void 0;
9587
9727
  }
9588
9728
  }
@@ -1417,6 +1417,15 @@ async function createModuleRunner(env, webSocket, viteRoot) {
1417
1417
  }
1418
1418
  },
1419
1419
  async runExternalModule(filepath) {
1420
+ if (filepath === "cloudflare:workers") {
1421
+ const originalCloudflareWorkersModule = await import("cloudflare:workers");
1422
+ return Object.seal({
1423
+ ...originalCloudflareWorkersModule,
1424
+ env: stripInternalEnv(
1425
+ originalCloudflareWorkersModule.env
1426
+ )
1427
+ });
1428
+ }
1420
1429
  if (!additionalModuleRE.test(filepath) && filepath.includes("/node_modules") && !filepath.includes("/node_modules/.vite")) {
1421
1430
  throw new Error(
1422
1431
  `[Error] Trying to import non-prebundled module (only prebundled modules are allowed): ${filepath}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudflare/vite-plugin",
3
- "version": "0.0.0-9b86dba81",
3
+ "version": "0.0.0-9c844f771",
4
4
  "description": "Cloudflare plugin for Vite",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -34,15 +34,16 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@hattip/adapter-node": "^0.0.49",
37
+ "picocolors": "^1.1.1",
37
38
  "tinyglobby": "^0.2.12",
38
39
  "unenv": "2.0.0-rc.15",
39
40
  "ws": "8.18.0",
40
- "@cloudflare/unenv-preset": "0.0.0-9b86dba81",
41
- "miniflare": "0.0.0-9b86dba81",
42
- "wrangler": "0.0.0-9b86dba81"
41
+ "@cloudflare/unenv-preset": "0.0.0-9c844f771",
42
+ "miniflare": "0.0.0-9c844f771",
43
+ "wrangler": "0.0.0-9c844f771"
43
44
  },
44
45
  "devDependencies": {
45
- "@cloudflare/workers-types": "^4.20250319.0",
46
+ "@cloudflare/workers-types": "^4.20250321.0",
46
47
  "@types/node": "^22.10.1",
47
48
  "@types/ws": "^8.5.13",
48
49
  "magic-string": "^0.30.12",
@@ -52,8 +53,8 @@
52
53
  "undici": "^5.28.5",
53
54
  "vite": "^6.1.0",
54
55
  "vitest": "~3.0.8",
56
+ "@cloudflare/workers-shared": "0.0.0-9c844f771",
55
57
  "@cloudflare/mock-npm-registry": "0.0.0",
56
- "@cloudflare/workers-shared": "0.0.0-9b86dba81",
57
58
  "@cloudflare/workers-tsconfig": "0.0.0"
58
59
  },
59
60
  "peerDependencies": {