@cloudflare/vite-plugin 0.0.0-23885f651 → 0.0.0-23975ad9e

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/dist/index.js CHANGED
@@ -485,11 +485,12 @@ var require_mime = __commonJS({
485
485
  });
486
486
 
487
487
  // src/index.ts
488
- import assert9 from "node:assert";
488
+ import assert10 from "node:assert";
489
489
  import * as fs5 from "node:fs";
490
490
  import * as fsp2 from "node:fs/promises";
491
491
  import * as path9 from "node:path";
492
- import { createMiddleware } from "@hattip/adapter-node";
492
+ import { createRequest, sendResponse } from "@mjackson/node-fetch-server";
493
+ import replace from "@rollup/plugin-replace";
493
494
 
494
495
  // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
495
496
  var comma = ",".charCodeAt(0);
@@ -1557,6 +1558,7 @@ var MagicString = class _MagicString {
1557
1558
 
1558
1559
  // src/index.ts
1559
1560
  import { Miniflare } from "miniflare";
1561
+ import colors3 from "picocolors";
1560
1562
  import * as vite7 from "vite";
1561
1563
 
1562
1564
  // src/constants.ts
@@ -5782,7 +5784,8 @@ var z = /* @__PURE__ */ Object.freeze({
5782
5784
  // ../workers-shared/utils/types.ts
5783
5785
  var InternalConfigSchema = z.object({
5784
5786
  account_id: z.number().optional(),
5785
- script_id: z.number().optional()
5787
+ script_id: z.number().optional(),
5788
+ debug: z.boolean().optional()
5786
5789
  });
5787
5790
  var RouterConfigSchema = z.object({
5788
5791
  invoke_user_worker_ahead_of_assets: z.boolean().optional(),
@@ -5830,14 +5833,14 @@ var AssetConfigSchema = z.object({
5830
5833
  });
5831
5834
 
5832
5835
  // src/asset-config.ts
5833
- function hasAssetsConfigChanged(resolvedPluginConfig, resolvedViteConfig, changedFile) {
5836
+ function hasAssetsConfigChanged(resolvedPluginConfig, resolvedViteConfig, changedFilePath) {
5834
5837
  if (!resolvedPluginConfig.experimental?.headersAndRedirectsDevModeSupport) {
5835
5838
  return false;
5836
5839
  }
5837
5840
  return [
5838
5841
  getRedirectsConfigPath(resolvedViteConfig),
5839
5842
  getHeadersConfigPath(resolvedViteConfig)
5840
- ].includes(path.resolve(changedFile));
5843
+ ].includes(changedFilePath);
5841
5844
  }
5842
5845
  function getAssetsConfig(resolvedPluginConfig, entryWorkerConfig, resolvedConfig) {
5843
5846
  const assetsConfig = resolvedPluginConfig.type === "assets-only" ? resolvedPluginConfig.config.assets : entryWorkerConfig?.assets;
@@ -12878,6 +12881,15 @@ function isNodeCompat(workerConfig) {
12878
12881
  }
12879
12882
  return false;
12880
12883
  }
12884
+ function isNodeAls(workerConfig) {
12885
+ return workerConfig !== void 0 && getNodeCompat(
12886
+ workerConfig.compatibility_date,
12887
+ workerConfig.compatibility_flags ?? []
12888
+ ).mode === "als";
12889
+ }
12890
+ function isNodeAlsModule(path10) {
12891
+ return /^(node:)?async_hooks$/.test(path10);
12892
+ }
12881
12893
  function injectGlobalCode(id, code) {
12882
12894
  const injectedCode = Object.entries(env.inject).map(([globalName, globalInject]) => {
12883
12895
  if (typeof globalInject === "string") {
@@ -12908,7 +12920,7 @@ globalThis.${globalName} = var_${globalName}.${exportName};
12908
12920
  }
12909
12921
  function resolveNodeJSImport(source) {
12910
12922
  const alias = env.alias[source];
12911
- if (alias) {
12923
+ if (alias && !nodeCompatExternals.has(alias)) {
12912
12924
  return {
12913
12925
  unresolved: alias,
12914
12926
  resolved: resolvePathSync(alias, { url: import.meta.url })
@@ -12939,8 +12951,9 @@ function getNodeCompatEntries() {
12939
12951
  return entries;
12940
12952
  }
12941
12953
  var NodeJsCompatWarnings = class {
12942
- constructor(environment) {
12943
- this.environment = environment;
12954
+ constructor(environmentName, resolvedViteConfig) {
12955
+ this.environmentName = environmentName;
12956
+ this.resolvedViteConfig = resolvedViteConfig;
12944
12957
  }
12945
12958
  sources = /* @__PURE__ */ new Map();
12946
12959
  timer;
@@ -12948,6 +12961,7 @@ var NodeJsCompatWarnings = class {
12948
12961
  const importers = this.sources.get(source) ?? /* @__PURE__ */ new Set();
12949
12962
  this.sources.set(source, importers);
12950
12963
  importers.add(importer);
12964
+ this.renderWarningsOnIdle();
12951
12965
  }
12952
12966
  renderWarningsOnIdle() {
12953
12967
  if (this.timer) {
@@ -12960,19 +12974,16 @@ var NodeJsCompatWarnings = class {
12960
12974
  }
12961
12975
  renderWarnings() {
12962
12976
  if (this.sources.size > 0) {
12963
- let message = `
12964
-
12965
- Unexpected Node.js imports for environment "${this.environment.name}". Do you need to enable the "nodejs_compat" compatibility flag?
12966
- Refer to https://developers.cloudflare.com/workers/runtime-apis/nodejs/ for more details.
12977
+ let message = `Unexpected Node.js imports for environment "${this.environmentName}". Do you need to enable the "nodejs_compat" compatibility flag? Refer to https://developers.cloudflare.com/workers/runtime-apis/nodejs/ for more details.
12967
12978
  `;
12968
12979
  this.sources.forEach((importers, source) => {
12969
12980
  importers.forEach((importer) => {
12970
- message += ` - "${source}" imported from "${path3.relative(this.environment.config.root, importer)}"
12981
+ message += ` - "${source}" imported from "${path3.relative(this.resolvedViteConfig.root, importer)}"
12971
12982
  `;
12972
12983
  });
12973
12984
  });
12974
- this.environment.logger.warn(message, {
12975
- environment: this.environment.name
12985
+ this.resolvedViteConfig.logger.warn(message, {
12986
+ timestamp: true
12976
12987
  });
12977
12988
  this.sources.clear();
12978
12989
  }
@@ -12992,6 +13003,7 @@ var VITE_DEV_METADATA_HEADER = "__VITE_DEV_METADATA__";
12992
13003
 
12993
13004
  // src/utils.ts
12994
13005
  import * as path4 from "node:path";
13006
+ import getPort, { portNumbers } from "get-port";
12995
13007
  import { Request as MiniflareRequest } from "miniflare";
12996
13008
  import "vite";
12997
13009
  function getOutputDirectory(userConfig, environmentName) {
@@ -13017,23 +13029,13 @@ function toMiniflareRequest(request) {
13017
13029
  duplex: "half"
13018
13030
  });
13019
13031
  }
13020
- function nodeHeadersToWebHeaders(nodeHeaders) {
13021
- const headers = new Headers();
13022
- for (const [key, value] of Object.entries(nodeHeaders)) {
13023
- if (typeof value === "string") {
13024
- headers.append(key, value);
13025
- } else if (Array.isArray(value)) {
13026
- for (const item of value) {
13027
- headers.append(key, item);
13028
- }
13029
- }
13030
- }
13031
- return headers;
13032
- }
13033
13032
  var postfixRE = /[?#].*$/;
13034
13033
  function cleanUrl(url) {
13035
13034
  return url.replace(postfixRE, "");
13036
13035
  }
13036
+ function getFirstAvailablePort(start) {
13037
+ return getPort({ port: portNumbers(start, 65535) });
13038
+ }
13037
13039
 
13038
13040
  // src/cloudflare-environment.ts
13039
13041
  var webSocketUndefinedError = "The WebSocket is undefined";
@@ -13340,6 +13342,7 @@ import {
13340
13342
  LogLevel,
13341
13343
  Response as MiniflareResponse
13342
13344
  } from "miniflare";
13345
+ import colors2 from "picocolors";
13343
13346
  import { globSync } from "tinyglobby";
13344
13347
  import "vite";
13345
13348
  import { unstable_getMiniflareWorkerOptions } from "wrangler";
@@ -13444,7 +13447,30 @@ function getEntryWorkerConfig(resolvedPluginConfig) {
13444
13447
  }
13445
13448
  return resolvedPluginConfig.workers[resolvedPluginConfig.entryWorkerEnvironmentName];
13446
13449
  }
13447
- function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
13450
+ function filterTails(tails, userWorkers, log) {
13451
+ return tails?.filter((tailService) => {
13452
+ let name;
13453
+ if (typeof tailService === "string") {
13454
+ name = tailService;
13455
+ } else if (typeof tailService === "object" && "name" in tailService && typeof tailService.name === "string") {
13456
+ name = tailService.name;
13457
+ } else {
13458
+ return true;
13459
+ }
13460
+ const found = userWorkers.some((w) => w.name === name);
13461
+ if (!found) {
13462
+ log(
13463
+ colors2.dim(
13464
+ colors2.yellow(
13465
+ `Tail consumer "${name}" was not found in your config. Make sure you add it if you'd like to simulate receiving tail events locally.`
13466
+ )
13467
+ )
13468
+ );
13469
+ }
13470
+ return found;
13471
+ });
13472
+ }
13473
+ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPort) {
13448
13474
  const resolvedViteConfig = viteDevServer.config;
13449
13475
  const entryWorkerConfig = getEntryWorkerConfig(resolvedPluginConfig);
13450
13476
  const assetsConfig = getAssetsConfig(
@@ -13536,7 +13562,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
13536
13562
  worker: {
13537
13563
  ...workerOptions,
13538
13564
  name: workerOptions.name ?? workerConfig.name,
13539
- unsafeInspectorProxy: resolvedPluginConfig.inspectorPort !== false,
13565
+ unsafeInspectorProxy: inspectorPort !== false,
13540
13566
  modulesRoot: miniflareModulesRoot,
13541
13567
  unsafeEvalBinding: "__VITE_UNSAFE_EVAL__",
13542
13568
  serviceBindings: {
@@ -13578,8 +13604,8 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
13578
13604
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
13579
13605
  return {
13580
13606
  log: logger,
13581
- inspectorPort: resolvedPluginConfig.inspectorPort || void 0,
13582
- unsafeInspectorProxy: resolvedPluginConfig.inspectorPort !== false,
13607
+ inspectorPort: inspectorPort === false ? void 0 : inspectorPort,
13608
+ unsafeInspectorProxy: inspectorPort !== false,
13583
13609
  handleRuntimeStdio(stdout, stderr) {
13584
13610
  const decoder = new TextDecoder();
13585
13611
  stdout.forEach((data2) => logger.info(decoder.decode(data2)));
@@ -13635,6 +13661,11 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
13635
13661
  }
13636
13662
  return {
13637
13663
  ...workerOptions,
13664
+ tails: filterTails(
13665
+ workerOptions.tails,
13666
+ userWorkers,
13667
+ viteDevServer.config.logger.warn
13668
+ ),
13638
13669
  modules: [
13639
13670
  {
13640
13671
  type: "ESModule",
@@ -13716,7 +13747,7 @@ function getPreviewModules(main, modulesRules) {
13716
13747
  ]
13717
13748
  };
13718
13749
  }
13719
- function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, inspectorPort = DEFAULT_INSPECTOR_PORT) {
13750
+ function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, inspectorPort) {
13720
13751
  const resolvedViteConfig = vitePreviewServer.config;
13721
13752
  const workers = workerConfigs.flatMap((config) => {
13722
13753
  const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(config);
@@ -13725,6 +13756,11 @@ function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistSta
13725
13756
  return [
13726
13757
  {
13727
13758
  ...workerOptions,
13759
+ tails: filterTails(
13760
+ workerOptions.tails,
13761
+ workerConfigs,
13762
+ vitePreviewServer.config.logger.warn
13763
+ ),
13728
13764
  name: workerOptions.name ?? config.name,
13729
13765
  unsafeInspectorProxy: inspectorPort !== false,
13730
13766
  ...miniflareWorkerOptions.main ? getPreviewModules(miniflareWorkerOptions.main, modulesRules) : { modules: true, script: "" }
@@ -13735,7 +13771,7 @@ function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistSta
13735
13771
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
13736
13772
  return {
13737
13773
  log: logger,
13738
- inspectorPort: inspectorPort || void 0,
13774
+ inspectorPort: inspectorPort === false ? void 0 : inspectorPort,
13739
13775
  unsafeInspectorProxy: inspectorPort !== false,
13740
13776
  handleRuntimeStdio(stdout, stderr) {
13741
13777
  const decoder = new TextDecoder();
@@ -13824,8 +13860,7 @@ var nonApplicableWorkerConfigs = {
13824
13860
  "preserve_file_names",
13825
13861
  "rules",
13826
13862
  "site",
13827
- "tsconfig",
13828
- "upload_source_maps"
13863
+ "tsconfig"
13829
13864
  ]
13830
13865
  };
13831
13866
  var nullableNonApplicable = [
@@ -13836,8 +13871,7 @@ var nullableNonApplicable = [
13836
13871
  "no_bundle",
13837
13872
  "preserve_file_names",
13838
13873
  "site",
13839
- "tsconfig",
13840
- "upload_source_maps"
13874
+ "tsconfig"
13841
13875
  ];
13842
13876
  function readWorkerConfig(configPath, env2) {
13843
13877
  const nonApplicable = {
@@ -14053,7 +14087,6 @@ function workerNameToEnvironmentName(workerName) {
14053
14087
  function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14054
14088
  const configPaths = /* @__PURE__ */ new Set();
14055
14089
  const persistState = pluginConfig.persistState ?? true;
14056
- const inspectorPort = pluginConfig.inspectorPort ?? DEFAULT_INSPECTOR_PORT;
14057
14090
  const experimental = pluginConfig.experimental ?? {};
14058
14091
  const root = userConfig.root ? path8.resolve(userConfig.root) : process.cwd();
14059
14092
  const { CLOUDFLARE_ENV: cloudflareEnv } = vite6.loadEnv(
@@ -14079,7 +14112,6 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14079
14112
  type: "assets-only",
14080
14113
  config: entryWorkerResolvedConfig.config,
14081
14114
  configPaths,
14082
- inspectorPort,
14083
14115
  persistState,
14084
14116
  rawConfigs: {
14085
14117
  entryWorker: entryWorkerResolvedConfig
@@ -14125,7 +14157,6 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14125
14157
  type: "workers",
14126
14158
  configPaths,
14127
14159
  persistState,
14128
- inspectorPort,
14129
14160
  workers,
14130
14161
  entryWorkerEnvironmentName,
14131
14162
  rawConfigs: {
@@ -14138,6 +14169,7 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14138
14169
  }
14139
14170
 
14140
14171
  // src/websockets.ts
14172
+ import { createHeaders } from "@mjackson/node-fetch-server";
14141
14173
  import { coupleWebSocket } from "miniflare";
14142
14174
  import { WebSocketServer } from "ws";
14143
14175
  function handleWebSocket(httpServer, getFetcher) {
@@ -14149,7 +14181,7 @@ function handleWebSocket(httpServer, getFetcher) {
14149
14181
  if (request.headers["sec-websocket-protocol"]?.startsWith("vite")) {
14150
14182
  return;
14151
14183
  }
14152
- const headers = nodeHeadersToWebHeaders(request.headers);
14184
+ const headers = createHeaders(request);
14153
14185
  const fetcher = await getFetcher();
14154
14186
  const response = await fetcher(url, {
14155
14187
  headers,
@@ -14173,6 +14205,57 @@ function handleWebSocket(httpServer, getFetcher) {
14173
14205
  );
14174
14206
  }
14175
14207
 
14208
+ // src/worker-environments-validation.ts
14209
+ import assert9 from "node:assert";
14210
+ function validateWorkerEnvironmentsResolvedConfigs(resolvedPluginConfig, resolvedViteConfig) {
14211
+ const workersEnvironmentNames = Object.keys(resolvedPluginConfig.workers);
14212
+ const disallowedEnvsConfigs = /* @__PURE__ */ new Map();
14213
+ for (const envName of workersEnvironmentNames) {
14214
+ const workerEnvConfig = resolvedViteConfig.environments[envName];
14215
+ assert9(workerEnvConfig, `Missing environment config for "${envName}"`);
14216
+ const { optimizeDeps, resolve: resolve7 } = workerEnvConfig;
14217
+ const disallowedConfig = {};
14218
+ const disallowedOptimizeDepsExcludeEntries = (optimizeDeps.exclude ?? []).filter((entry) => {
14219
+ if (cloudflareBuiltInModules.includes(entry)) {
14220
+ return false;
14221
+ }
14222
+ if (isNodeAlsModule(entry) && isNodeAls(resolvedPluginConfig.workers[envName])) {
14223
+ return false;
14224
+ }
14225
+ if (NODEJS_MODULES_RE.test(entry) && isNodeCompat(resolvedPluginConfig.workers[envName])) {
14226
+ return false;
14227
+ }
14228
+ return true;
14229
+ });
14230
+ if (disallowedOptimizeDepsExcludeEntries.length > 0) {
14231
+ disallowedConfig.optimizeDepsExclude = disallowedOptimizeDepsExcludeEntries;
14232
+ }
14233
+ if (resolve7.external === true || resolve7.external.length > 0) {
14234
+ disallowedConfig.resolveExternal = resolve7.external;
14235
+ }
14236
+ if (Object.keys(disallowedConfig).length > 0) {
14237
+ disallowedEnvsConfigs.set(envName, disallowedConfig);
14238
+ }
14239
+ }
14240
+ if (disallowedEnvsConfigs.size > 0) {
14241
+ const errorMessage = `The following environment configurations are incompatible with the Cloudflare Vite plugin:
14242
+ ${[
14243
+ ...disallowedEnvsConfigs
14244
+ ].map(
14245
+ ([envName, disallowedConfig]) => [
14246
+ disallowedConfig.optimizeDepsExclude ? ` - "${envName}" environment: \`optimizeDeps.exclude\`: ${JSON.stringify(disallowedConfig.optimizeDepsExclude)}
14247
+ ` : null,
14248
+ disallowedConfig.resolveExternal ? ` - "${envName}" environment: \`resolve.external\`: ${JSON.stringify(disallowedConfig.resolveExternal)}
14249
+ ` : null
14250
+ ].join("")
14251
+ ).join(
14252
+ ""
14253
+ )}To resolve this issue, avoid setting \`optimizeDeps.exclude\` and \`resolve.external\` in your Cloudflare Worker environments.
14254
+ `;
14255
+ throw new Error(errorMessage);
14256
+ }
14257
+ }
14258
+
14176
14259
  // src/index.ts
14177
14260
  var workersConfigsWarningShown = false;
14178
14261
  var miniflare;
@@ -14243,7 +14326,7 @@ function cloudflare2(pluginConfig = {}) {
14243
14326
  resolvedPluginConfig.workers
14244
14327
  ).map((environmentName) => {
14245
14328
  const environment = builder.environments[environmentName];
14246
- assert9(
14329
+ assert10(
14247
14330
  environment,
14248
14331
  `${environmentName} environment not found`
14249
14332
  );
@@ -14264,6 +14347,12 @@ function cloudflare2(pluginConfig = {}) {
14264
14347
  },
14265
14348
  configResolved(config) {
14266
14349
  resolvedViteConfig = config;
14350
+ if (resolvedPluginConfig?.type === "workers") {
14351
+ validateWorkerEnvironmentsResolvedConfigs(
14352
+ resolvedPluginConfig,
14353
+ resolvedViteConfig
14354
+ );
14355
+ }
14267
14356
  },
14268
14357
  generateBundle(_, bundle) {
14269
14358
  let config;
@@ -14284,7 +14373,7 @@ function cloudflare2(pluginConfig = {}) {
14284
14373
  if (isEntryWorker && hasClientBuild) {
14285
14374
  const workerOutputDirectory = this.environment.config.build.outDir;
14286
14375
  const clientOutputDirectory = resolvedViteConfig.environments.client?.build.outDir;
14287
- assert9(
14376
+ assert10(
14288
14377
  clientOutputDirectory,
14289
14378
  "Unexpected error: client output directory is undefined"
14290
14379
  );
@@ -14348,78 +14437,100 @@ function cloudflare2(pluginConfig = {}) {
14348
14437
  }
14349
14438
  },
14350
14439
  hotUpdate(options) {
14351
- if (
14352
- // Vite normalizes `options.file` so we use `path.resolve` for Windows compatibility
14353
- resolvedPluginConfig.configPaths.has(path9.resolve(options.file)) || hasAssetsConfigChanged(
14354
- resolvedPluginConfig,
14355
- resolvedViteConfig,
14356
- options.file
14357
- )
14358
- ) {
14440
+ const changedFilePath = path9.resolve(options.file);
14441
+ if (resolvedPluginConfig.configPaths.has(changedFilePath) || hasDotDevDotVarsFileChanged(resolvedPluginConfig, changedFilePath) || hasAssetsConfigChanged(
14442
+ resolvedPluginConfig,
14443
+ resolvedViteConfig,
14444
+ changedFilePath
14445
+ )) {
14359
14446
  options.server.restart();
14360
14447
  return [];
14361
14448
  }
14362
14449
  },
14363
14450
  async configureServer(viteDevServer) {
14364
- assert9(
14365
- viteDevServer.httpServer,
14366
- "Unexpected error: No Vite HTTP server"
14451
+ const inputInspectorPort = await getInputInspectorPortOption(
14452
+ pluginConfig,
14453
+ viteDevServer
14367
14454
  );
14368
- if (miniflare) {
14369
- await miniflare.setOptions(
14370
- getDevMiniflareOptions(resolvedPluginConfig, viteDevServer)
14455
+ if (!miniflare) {
14456
+ miniflare = new Miniflare(
14457
+ getDevMiniflareOptions(
14458
+ resolvedPluginConfig,
14459
+ viteDevServer,
14460
+ inputInspectorPort
14461
+ )
14371
14462
  );
14372
14463
  } else {
14373
- miniflare = new Miniflare(
14374
- getDevMiniflareOptions(resolvedPluginConfig, viteDevServer)
14464
+ await miniflare.setOptions(
14465
+ getDevMiniflareOptions(
14466
+ resolvedPluginConfig,
14467
+ viteDevServer,
14468
+ inputInspectorPort
14469
+ )
14375
14470
  );
14376
14471
  }
14377
14472
  await initRunners(resolvedPluginConfig, viteDevServer, miniflare);
14378
- const middleware = createMiddleware(
14379
- async ({ request }) => {
14380
- assert9(miniflare, `Miniflare not defined`);
14473
+ if (viteDevServer.httpServer) {
14474
+ handleWebSocket(viteDevServer.httpServer, async () => {
14475
+ assert10(miniflare, `Miniflare not defined`);
14381
14476
  const routerWorker = await getRouterWorker(miniflare);
14382
- return routerWorker.fetch(toMiniflareRequest(request), {
14383
- redirect: "manual"
14384
- });
14385
- },
14386
- { alwaysCallNext: false }
14387
- );
14388
- handleWebSocket(viteDevServer.httpServer, async () => {
14389
- assert9(miniflare, `Miniflare not defined`);
14390
- const routerWorker = await getRouterWorker(miniflare);
14391
- return routerWorker.fetch;
14392
- });
14477
+ return routerWorker.fetch;
14478
+ });
14479
+ }
14393
14480
  return () => {
14394
- viteDevServer.middlewares.use((req, res, next) => {
14395
- middleware(req, res, next);
14481
+ viteDevServer.middlewares.use(async (req, res, next) => {
14482
+ try {
14483
+ assert10(miniflare, `Miniflare not defined`);
14484
+ const routerWorker = await getRouterWorker(miniflare);
14485
+ const request = createRequest(req, res);
14486
+ const response = await routerWorker.fetch(
14487
+ toMiniflareRequest(request),
14488
+ {
14489
+ redirect: "manual"
14490
+ }
14491
+ );
14492
+ if (req.httpVersionMajor === 2) {
14493
+ response.headers.delete("transfer-encoding");
14494
+ }
14495
+ await sendResponse(res, response);
14496
+ } catch (error) {
14497
+ next(error);
14498
+ }
14396
14499
  });
14397
14500
  };
14398
14501
  },
14399
- configurePreviewServer(vitePreviewServer) {
14502
+ async configurePreviewServer(vitePreviewServer) {
14400
14503
  const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
14504
+ const inputInspectorPort = await getInputInspectorPortOption(
14505
+ pluginConfig,
14506
+ vitePreviewServer
14507
+ );
14401
14508
  const miniflare2 = new Miniflare(
14402
14509
  getPreviewMiniflareOptions(
14403
14510
  vitePreviewServer,
14404
14511
  workerConfigs,
14405
14512
  pluginConfig.persistState ?? true,
14406
- pluginConfig.inspectorPort
14513
+ inputInspectorPort
14407
14514
  )
14408
14515
  );
14409
- const middleware = createMiddleware(
14410
- ({ request }) => {
14411
- return miniflare2.dispatchFetch(toMiniflareRequest(request), {
14412
- redirect: "manual"
14413
- });
14414
- },
14415
- { alwaysCallNext: false }
14416
- );
14417
14516
  handleWebSocket(
14418
14517
  vitePreviewServer.httpServer,
14419
14518
  () => miniflare2.dispatchFetch
14420
14519
  );
14421
- vitePreviewServer.middlewares.use((req, res, next) => {
14422
- middleware(req, res, next);
14520
+ vitePreviewServer.middlewares.use(async (req, res, next) => {
14521
+ try {
14522
+ const request = createRequest(req, res);
14523
+ const response = await miniflare2.dispatchFetch(
14524
+ toMiniflareRequest(request),
14525
+ { redirect: "manual" }
14526
+ );
14527
+ if (req.httpVersionMajor === 2) {
14528
+ response.headers.delete("transfer-encoding");
14529
+ }
14530
+ await sendResponse(res, response);
14531
+ } catch (error) {
14532
+ next(error);
14533
+ }
14423
14534
  });
14424
14535
  }
14425
14536
  },
@@ -14482,7 +14593,7 @@ function cloudflare2(pluginConfig = {}) {
14482
14593
  for (const match of matches) {
14483
14594
  magicString ??= new MagicString(code);
14484
14595
  const [full, _, modulePath] = match;
14485
- assert9(
14596
+ assert10(
14486
14597
  modulePath,
14487
14598
  `Unexpected error: module path not found in reference ${full}.`
14488
14599
  );
@@ -14528,17 +14639,22 @@ function cloudflare2(pluginConfig = {}) {
14528
14639
  configEnvironment(name) {
14529
14640
  if (isNodeCompat(getWorkerConfig2(name))) {
14530
14641
  return {
14642
+ build: {
14643
+ rollupOptions: {
14644
+ plugins: [
14645
+ replace({
14646
+ "process.env.NODE_ENV": JSON.stringify(
14647
+ process.env.NODE_ENV ?? "production"
14648
+ ),
14649
+ preventAssignment: true
14650
+ })
14651
+ ]
14652
+ }
14653
+ },
14531
14654
  resolve: {
14532
14655
  builtins: [...nodeCompatExternals]
14533
14656
  },
14534
14657
  optimizeDeps: {
14535
- // This is a list of dependency entry-points that should be pre-bundled.
14536
- // In this case we provide a list of all the possible polyfills so that they are pre-bundled,
14537
- // ready ahead the first request to the dev server.
14538
- // Without this the dependency optimizer will try to bundle them on-the-fly in the middle of the first request,
14539
- // which can potentially cause problems if it leads to previous pre-bundling to become stale and needing to be reloaded.
14540
- // TODO: work out how to re-enable pre-bundling of these
14541
- // include: [...getNodeCompatEntries()],
14542
14658
  // This is a list of module specifiers that the dependency optimizer should not follow when doing import analysis.
14543
14659
  // In this case we provide a list of all the Node.js modules, both those built-in to workerd and those that will be polyfilled.
14544
14660
  // Obviously we don't want/need the optimizer to try to process modules that are built-in;
@@ -14562,7 +14678,7 @@ function cloudflare2(pluginConfig = {}) {
14562
14678
  return this.resolve(source, importer, options);
14563
14679
  }
14564
14680
  if (this.environment.mode === "dev") {
14565
- assert9(
14681
+ assert10(
14566
14682
  this.environment.depsOptimizer,
14567
14683
  "depsOptimizer is required in dev mode"
14568
14684
  );
@@ -14576,11 +14692,54 @@ function cloudflare2(pluginConfig = {}) {
14576
14692
  },
14577
14693
  async transform(code, id) {
14578
14694
  const workerConfig = getWorkerConfig2(this.environment.name);
14579
- assert9(workerConfig, "Expected a worker config");
14695
+ if (!workerConfig) {
14696
+ return;
14697
+ }
14580
14698
  const resolvedId = await this.resolve(workerConfig.main);
14581
14699
  if (id === resolvedId?.id) {
14582
14700
  return injectGlobalCode(id, code);
14583
14701
  }
14702
+ },
14703
+ async configureServer(viteDevServer) {
14704
+ await Promise.all(
14705
+ Object.values(viteDevServer.environments).flatMap(
14706
+ async (environment) => {
14707
+ const workerConfig = getWorkerConfig2(environment.name);
14708
+ if (isNodeCompat(workerConfig)) {
14709
+ await environment.depsOptimizer?.init();
14710
+ return Array.from(nodeCompatEntries).map((entry) => {
14711
+ const result = resolveNodeJSImport(entry);
14712
+ if (result) {
14713
+ const registration = environment.depsOptimizer?.registerMissingImport(
14714
+ result.unresolved,
14715
+ result.resolved
14716
+ );
14717
+ return registration?.processing;
14718
+ }
14719
+ });
14720
+ }
14721
+ }
14722
+ )
14723
+ );
14724
+ }
14725
+ },
14726
+ // Plugin that handles Node.js Async Local Storage (ALS) compatibility support for Vite Environments that are hosted in Cloudflare Workers.
14727
+ {
14728
+ name: "vite-plugin-cloudflare:nodejs-als",
14729
+ apply(_config, env2) {
14730
+ return !env2.isPreview;
14731
+ },
14732
+ configEnvironment(name, config) {
14733
+ if (isNodeAls(getWorkerConfig2(name))) {
14734
+ return {
14735
+ resolve: {
14736
+ builtins: ["async_hooks", "node:async_hooks"]
14737
+ },
14738
+ optimizeDeps: {
14739
+ exclude: ["async_hooks", "node:async_hooks"]
14740
+ }
14741
+ };
14742
+ }
14584
14743
  }
14585
14744
  },
14586
14745
  // Plugin that provides an __debug path for debugging the Cloudflare Workers.
@@ -14590,39 +14749,35 @@ function cloudflare2(pluginConfig = {}) {
14590
14749
  // the preview middleware here can take precedence
14591
14750
  enforce: "pre",
14592
14751
  configureServer(viteDevServer) {
14593
- if (resolvedPluginConfig.type === "workers" && resolvedPluginConfig.inspectorPort !== false) {
14752
+ if (resolvedPluginConfig.type === "workers" && pluginConfig.inspectorPort !== false) {
14594
14753
  addDebugToVitePrintUrls(viteDevServer);
14595
14754
  }
14596
14755
  const workerNames = resolvedPluginConfig.type === "assets-only" ? [] : Object.values(resolvedPluginConfig.workers).map(
14597
14756
  (worker) => worker.name
14598
14757
  );
14599
- viteDevServer.middlewares.use((req, res, next) => {
14600
- if (req.url === debuggingPath && resolvedPluginConfig.inspectorPort !== false) {
14601
- const html = getDebugPathHtml(
14602
- workerNames,
14603
- resolvedPluginConfig.inspectorPort
14604
- );
14758
+ viteDevServer.middlewares.use(async (req, res, next) => {
14759
+ const resolvedInspectorPort = await getResolvedInspectorPort(pluginConfig);
14760
+ if (req.url === debuggingPath && resolvedInspectorPort) {
14761
+ const html = getDebugPathHtml(workerNames, resolvedInspectorPort);
14605
14762
  res.setHeader("Content-Type", "text/html");
14606
14763
  return res.end(html);
14607
14764
  }
14608
14765
  next();
14609
14766
  });
14610
14767
  },
14611
- configurePreviewServer(vitePreviewServer) {
14768
+ async configurePreviewServer(vitePreviewServer) {
14612
14769
  const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
14613
14770
  if (workerConfigs.length >= 1 && pluginConfig.inspectorPort !== false) {
14614
14771
  addDebugToVitePrintUrls(vitePreviewServer);
14615
14772
  }
14616
14773
  const workerNames = workerConfigs.map((worker) => {
14617
- assert9(worker.name, "Expected the Worker to have a name");
14774
+ assert10(worker.name, "Expected the Worker to have a name");
14618
14775
  return worker.name;
14619
14776
  });
14620
- vitePreviewServer.middlewares.use((req, res, next) => {
14621
- if (req.url === debuggingPath && pluginConfig.inspectorPort !== false) {
14622
- const html = getDebugPathHtml(
14623
- workerNames,
14624
- pluginConfig.inspectorPort ?? DEFAULT_INSPECTOR_PORT
14625
- );
14777
+ vitePreviewServer.middlewares.use(async (req, res, next) => {
14778
+ const resolvedInspectorPort = await getResolvedInspectorPort(pluginConfig);
14779
+ if (req.url === debuggingPath && resolvedInspectorPort) {
14780
+ const html = getDebugPathHtml(workerNames, resolvedInspectorPort);
14626
14781
  res.setHeader("Content-Type", "text/html");
14627
14782
  return res.end(html);
14628
14783
  }
@@ -14636,6 +14791,9 @@ function cloudflare2(pluginConfig = {}) {
14636
14791
  apply(_config, env2) {
14637
14792
  return !env2.isPreview;
14638
14793
  },
14794
+ // We must ensure that the `resolveId` hook runs before the built-in ones.
14795
+ // Otherwise we never see the Node.js built-in imports since they get handled by default Vite behavior.
14796
+ enforce: "pre",
14639
14797
  configEnvironment(environmentName) {
14640
14798
  const workerConfig = getWorkerConfig2(environmentName);
14641
14799
  if (workerConfig && !isNodeCompat(workerConfig)) {
@@ -14649,21 +14807,14 @@ function cloudflare2(pluginConfig = {}) {
14649
14807
  build.onResolve(
14650
14808
  { filter: NODEJS_MODULES_RE },
14651
14809
  ({ path: path10, importer }) => {
14810
+ if (isNodeAls(workerConfig) && isNodeAlsModule(path10)) {
14811
+ return;
14812
+ }
14652
14813
  const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14653
- assert9(
14654
- nodeJsCompatWarnings,
14655
- `expected nodeJsCompatWarnings to be defined for Worker "${workerConfig.name}"`
14656
- );
14657
- nodeJsCompatWarnings.registerImport(path10, importer);
14814
+ nodeJsCompatWarnings?.registerImport(path10, importer);
14658
14815
  return { path: path10, external: true };
14659
14816
  }
14660
14817
  );
14661
- build.onEnd(() => {
14662
- const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14663
- if (nodeJsCompatWarnings) {
14664
- nodeJsCompatWarnings.renderWarnings();
14665
- }
14666
- });
14667
14818
  }
14668
14819
  }
14669
14820
  ]
@@ -14672,47 +14823,28 @@ function cloudflare2(pluginConfig = {}) {
14672
14823
  };
14673
14824
  }
14674
14825
  },
14675
- configureServer(viteDevServer) {
14676
- for (const environment of Object.values(viteDevServer.environments)) {
14677
- const workerConfig = getWorkerConfig2(environment.name);
14826
+ configResolved(resolvedViteConfig2) {
14827
+ for (const environmentName of Object.keys(
14828
+ resolvedViteConfig2.environments
14829
+ )) {
14830
+ const workerConfig = getWorkerConfig2(environmentName);
14678
14831
  if (workerConfig && !isNodeCompat(workerConfig)) {
14679
14832
  nodeJsCompatWarningsMap.set(
14680
14833
  workerConfig,
14681
- new NodeJsCompatWarnings(environment)
14834
+ new NodeJsCompatWarnings(environmentName, resolvedViteConfig2)
14682
14835
  );
14683
14836
  }
14684
14837
  }
14685
14838
  },
14686
- buildStart() {
14687
- const workerConfig = getWorkerConfig2(this.environment.name);
14688
- if (workerConfig && !isNodeCompat(workerConfig)) {
14689
- nodeJsCompatWarningsMap.set(
14690
- workerConfig,
14691
- new NodeJsCompatWarnings(this.environment)
14692
- );
14693
- }
14694
- },
14695
- buildEnd() {
14696
- const workerConfig = getWorkerConfig2(this.environment.name);
14697
- if (workerConfig && !isNodeCompat(workerConfig)) {
14698
- const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14699
- assert9(
14700
- nodeJsCompatWarnings,
14701
- `expected nodeJsCompatWarnings to be defined for Worker "${workerConfig.name}"`
14702
- );
14703
- nodeJsCompatWarnings.renderWarnings();
14704
- }
14705
- },
14706
- // We must ensure that the `resolveId` hook runs before the built-in ones otherwise we
14707
- // never see the Node.js built-in imports since they get handled by default Vite behavior.
14708
- enforce: "pre",
14709
14839
  async resolveId(source, importer) {
14710
14840
  const workerConfig = getWorkerConfig2(this.environment.name);
14711
14841
  if (workerConfig && !isNodeCompat(workerConfig)) {
14842
+ if (isNodeAls(workerConfig) && isNodeAlsModule(source)) {
14843
+ return;
14844
+ }
14712
14845
  const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14713
14846
  if (nodejsBuiltins.has(source)) {
14714
14847
  nodeJsCompatWarnings?.registerImport(source, importer);
14715
- nodeJsCompatWarnings?.renderWarningsOnIdle();
14716
14848
  return {
14717
14849
  id: source,
14718
14850
  external: true
@@ -14723,10 +14855,35 @@ function cloudflare2(pluginConfig = {}) {
14723
14855
  }
14724
14856
  ];
14725
14857
  function getWorkerConfig2(environmentName) {
14726
- assert9(resolvedPluginConfig, "Expected resolvedPluginConfig to be defined");
14858
+ assert10(resolvedPluginConfig, "Expected resolvedPluginConfig to be defined");
14727
14859
  return resolvedPluginConfig.type !== "assets-only" ? resolvedPluginConfig.workers[environmentName] : void 0;
14728
14860
  }
14729
14861
  }
14862
+ async function getInputInspectorPortOption(pluginConfig, viteServer) {
14863
+ if (pluginConfig.inspectorPort === void 0 || pluginConfig.inspectorPort === 0) {
14864
+ const resolvedInspectorPort = await getResolvedInspectorPort(pluginConfig);
14865
+ if (resolvedInspectorPort !== null) {
14866
+ return resolvedInspectorPort;
14867
+ }
14868
+ }
14869
+ const inputInspectorPort = pluginConfig.inspectorPort ?? await getFirstAvailablePort(DEFAULT_INSPECTOR_PORT);
14870
+ if (pluginConfig.inspectorPort === void 0 && inputInspectorPort !== DEFAULT_INSPECTOR_PORT) {
14871
+ viteServer.config.logger.warn(
14872
+ colors3.dim(
14873
+ `Default inspector port ${DEFAULT_INSPECTOR_PORT} not available, using ${inputInspectorPort} instead
14874
+ `
14875
+ )
14876
+ );
14877
+ }
14878
+ return inputInspectorPort;
14879
+ }
14880
+ async function getResolvedInspectorPort(pluginConfig) {
14881
+ if (miniflare && pluginConfig.inspectorPort !== false) {
14882
+ const miniflareInspectorUrl = await miniflare.getInspectorURL();
14883
+ return Number.parseInt(miniflareInspectorUrl.port);
14884
+ }
14885
+ return null;
14886
+ }
14730
14887
  function getDotDevDotVarsContent(configPath, cloudflareEnv) {
14731
14888
  const configDir = path9.dirname(configPath);
14732
14889
  const defaultDotDevDotVarsPath = `${configDir}/.dev.vars`;
@@ -14738,6 +14895,19 @@ function getDotDevDotVarsContent(configPath, cloudflareEnv) {
14738
14895
  }
14739
14896
  return null;
14740
14897
  }
14898
+ function hasDotDevDotVarsFileChanged(resolvedPluginConfig, changedFilePath) {
14899
+ return [...resolvedPluginConfig.configPaths].some((configPath) => {
14900
+ const dotDevDotVars = path9.join(path9.dirname(configPath), ".dev.vars");
14901
+ if (dotDevDotVars === changedFilePath) {
14902
+ return true;
14903
+ }
14904
+ if (resolvedPluginConfig.cloudflareEnv) {
14905
+ const dotDevDotVarsForEnv = `${dotDevDotVars}.${resolvedPluginConfig.cloudflareEnv}`;
14906
+ return dotDevDotVarsForEnv === changedFilePath;
14907
+ }
14908
+ return false;
14909
+ });
14910
+ }
14741
14911
  export {
14742
14912
  cloudflare2 as cloudflare
14743
14913
  };