@cloudflare/vite-plugin 0.0.0-665ebd857 → 0.0.0-69864b416

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 assert8 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
492
  import { createMiddleware } from "@hattip/adapter-node";
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 colors2 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) {
@@ -13034,6 +13046,9 @@ var postfixRE = /[?#].*$/;
13034
13046
  function cleanUrl(url) {
13035
13047
  return url.replace(postfixRE, "");
13036
13048
  }
13049
+ function getFirstAvailablePort(start) {
13050
+ return getPort({ port: portNumbers(start, 65535) });
13051
+ }
13037
13052
 
13038
13053
  // src/cloudflare-environment.ts
13039
13054
  var webSocketUndefinedError = "The WebSocket is undefined";
@@ -13444,7 +13459,7 @@ function getEntryWorkerConfig(resolvedPluginConfig) {
13444
13459
  }
13445
13460
  return resolvedPluginConfig.workers[resolvedPluginConfig.entryWorkerEnvironmentName];
13446
13461
  }
13447
- function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
13462
+ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer, inspectorPort) {
13448
13463
  const resolvedViteConfig = viteDevServer.config;
13449
13464
  const entryWorkerConfig = getEntryWorkerConfig(resolvedPluginConfig);
13450
13465
  const assetsConfig = getAssetsConfig(
@@ -13536,7 +13551,7 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
13536
13551
  worker: {
13537
13552
  ...workerOptions,
13538
13553
  name: workerOptions.name ?? workerConfig.name,
13539
- unsafeInspectorProxy: resolvedPluginConfig.inspectorPort !== false,
13554
+ unsafeInspectorProxy: inspectorPort !== false,
13540
13555
  modulesRoot: miniflareModulesRoot,
13541
13556
  unsafeEvalBinding: "__VITE_UNSAFE_EVAL__",
13542
13557
  serviceBindings: {
@@ -13578,8 +13593,8 @@ function getDevMiniflareOptions(resolvedPluginConfig, viteDevServer) {
13578
13593
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
13579
13594
  return {
13580
13595
  log: logger,
13581
- inspectorPort: resolvedPluginConfig.inspectorPort || void 0,
13582
- unsafeInspectorProxy: resolvedPluginConfig.inspectorPort !== false,
13596
+ inspectorPort: inspectorPort === false ? void 0 : inspectorPort,
13597
+ unsafeInspectorProxy: inspectorPort !== false,
13583
13598
  handleRuntimeStdio(stdout, stderr) {
13584
13599
  const decoder = new TextDecoder();
13585
13600
  stdout.forEach((data2) => logger.info(decoder.decode(data2)));
@@ -13716,7 +13731,7 @@ function getPreviewModules(main, modulesRules) {
13716
13731
  ]
13717
13732
  };
13718
13733
  }
13719
- function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, inspectorPort = DEFAULT_INSPECTOR_PORT) {
13734
+ function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistState, inspectorPort) {
13720
13735
  const resolvedViteConfig = vitePreviewServer.config;
13721
13736
  const workers = workerConfigs.flatMap((config) => {
13722
13737
  const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions(config);
@@ -13735,7 +13750,7 @@ function getPreviewMiniflareOptions(vitePreviewServer, workerConfigs, persistSta
13735
13750
  const logger = new ViteMiniflareLogger(resolvedViteConfig);
13736
13751
  return {
13737
13752
  log: logger,
13738
- inspectorPort: inspectorPort || void 0,
13753
+ inspectorPort: inspectorPort === false ? void 0 : inspectorPort,
13739
13754
  unsafeInspectorProxy: inspectorPort !== false,
13740
13755
  handleRuntimeStdio(stdout, stderr) {
13741
13756
  const decoder = new TextDecoder();
@@ -13785,11 +13800,12 @@ function miniflareLogLevelFromViteLogLevel(level = "info") {
13785
13800
  }
13786
13801
 
13787
13802
  // src/plugin-config.ts
13788
- import assert7 from "node:assert";
13803
+ import assert8 from "node:assert";
13789
13804
  import * as path8 from "node:path";
13790
13805
  import * as vite6 from "vite";
13791
13806
 
13792
13807
  // src/workers-configs.ts
13808
+ import assert7 from "node:assert";
13793
13809
  import * as fs4 from "node:fs";
13794
13810
  import * as path7 from "node:path";
13795
13811
  import { unstable_readConfig as unstable_readConfig2 } from "wrangler";
@@ -13823,8 +13839,7 @@ var nonApplicableWorkerConfigs = {
13823
13839
  "preserve_file_names",
13824
13840
  "rules",
13825
13841
  "site",
13826
- "tsconfig",
13827
- "upload_source_maps"
13842
+ "tsconfig"
13828
13843
  ]
13829
13844
  };
13830
13845
  var nullableNonApplicable = [
@@ -13835,8 +13850,7 @@ var nullableNonApplicable = [
13835
13850
  "no_bundle",
13836
13851
  "preserve_file_names",
13837
13852
  "site",
13838
- "tsconfig",
13839
- "upload_source_maps"
13853
+ "tsconfig"
13840
13854
  ];
13841
13855
  function readWorkerConfig(configPath, env2) {
13842
13856
  const nonApplicable = {
@@ -13998,14 +14012,52 @@ function getWorkerConfig(configPath, env2, opts) {
13998
14012
  nonApplicable
13999
14013
  };
14000
14014
  }
14015
+ function getValidatedWranglerConfigPath(root, requestedConfigPath, isForAuxiliaryWorker = false) {
14016
+ if (requestedConfigPath) {
14017
+ const configPath2 = path7.resolve(root, requestedConfigPath);
14018
+ const forAuxiliaryWorkerErrorMessage = isForAuxiliaryWorker ? " requested for one of your auxiliary workers" : "";
14019
+ const errorMessagePrefix = `The provided configPath (${configPath2})${forAuxiliaryWorkerErrorMessage}`;
14020
+ const fileExtension = path7.extname(configPath2).slice(1);
14021
+ if (!allowedWranglerConfigExtensions.includes(fileExtension)) {
14022
+ const foundExtensionMessage = !fileExtension ? "no extension found" : `"${fileExtension}" found`;
14023
+ throw new Error(
14024
+ `${errorMessagePrefix} doesn't point to a file with the correct file extension. It should point to a jsonc, json or toml file (${foundExtensionMessage} instead)`
14025
+ );
14026
+ }
14027
+ const mainStat = fs4.statSync(configPath2, { throwIfNoEntry: false });
14028
+ if (!mainStat) {
14029
+ throw new Error(
14030
+ `${errorMessagePrefix} doesn't point to an existing file`
14031
+ );
14032
+ }
14033
+ if (mainStat.isDirectory()) {
14034
+ throw new Error(
14035
+ `${errorMessagePrefix} points to a directory. It should point to a file.`
14036
+ );
14037
+ }
14038
+ return configPath2;
14039
+ }
14040
+ assert7(
14041
+ isForAuxiliaryWorker === false,
14042
+ "Unexpected Error: trying to find the wrangler config for an auxiliary worker"
14043
+ );
14044
+ const configPath = findWranglerConfig(root);
14045
+ if (!configPath) {
14046
+ throw new Error(
14047
+ `No config file found in the ${root} directory. Please add a wrangler.(jsonc|json|toml) file.`
14048
+ );
14049
+ }
14050
+ return configPath;
14051
+ }
14001
14052
  function findWranglerConfig(root) {
14002
- for (const extension of ["json", "jsonc", "toml"]) {
14053
+ for (const extension of allowedWranglerConfigExtensions) {
14003
14054
  const configPath = path7.join(root, `wrangler.${extension}`);
14004
14055
  if (fs4.existsSync(configPath)) {
14005
14056
  return configPath;
14006
14057
  }
14007
14058
  }
14008
14059
  }
14060
+ var allowedWranglerConfigExtensions = ["jsonc", "json", "toml"];
14009
14061
 
14010
14062
  // src/plugin-config.ts
14011
14063
  function workerNameToEnvironmentName(workerName) {
@@ -14014,7 +14066,6 @@ function workerNameToEnvironmentName(workerName) {
14014
14066
  function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14015
14067
  const configPaths = /* @__PURE__ */ new Set();
14016
14068
  const persistState = pluginConfig.persistState ?? true;
14017
- const inspectorPort = pluginConfig.inspectorPort ?? DEFAULT_INSPECTOR_PORT;
14018
14069
  const experimental = pluginConfig.experimental ?? {};
14019
14070
  const root = userConfig.root ? path8.resolve(userConfig.root) : process.cwd();
14020
14071
  const { CLOUDFLARE_ENV: cloudflareEnv } = vite6.loadEnv(
@@ -14023,22 +14074,23 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14023
14074
  /* prefixes */
14024
14075
  ""
14025
14076
  );
14026
- const configPath = pluginConfig.configPath ? path8.resolve(root, pluginConfig.configPath) : findWranglerConfig(root);
14027
- if (!configPath) {
14028
- throw new Error(
14029
- `Config not found. Have you created a wrangler.json(c) or wrangler.toml file?`
14030
- );
14031
- }
14032
- const entryWorkerResolvedConfig = getWorkerConfig(configPath, cloudflareEnv, {
14033
- visitedConfigPaths: configPaths,
14034
- isEntryWorker: true
14035
- });
14077
+ const entryWorkerConfigPath = getValidatedWranglerConfigPath(
14078
+ root,
14079
+ pluginConfig.configPath
14080
+ );
14081
+ const entryWorkerResolvedConfig = getWorkerConfig(
14082
+ entryWorkerConfigPath,
14083
+ cloudflareEnv,
14084
+ {
14085
+ visitedConfigPaths: configPaths,
14086
+ isEntryWorker: true
14087
+ }
14088
+ );
14036
14089
  if (entryWorkerResolvedConfig.type === "assets-only") {
14037
14090
  return {
14038
14091
  type: "assets-only",
14039
14092
  config: entryWorkerResolvedConfig.config,
14040
14093
  configPaths,
14041
- inspectorPort,
14042
14094
  persistState,
14043
14095
  rawConfigs: {
14044
14096
  entryWorker: entryWorkerResolvedConfig
@@ -14054,15 +14106,20 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14054
14106
  };
14055
14107
  const auxiliaryWorkersResolvedConfigs = [];
14056
14108
  for (const auxiliaryWorker of pluginConfig.auxiliaryWorkers ?? []) {
14109
+ const workerConfigPath = getValidatedWranglerConfigPath(
14110
+ root,
14111
+ auxiliaryWorker.configPath,
14112
+ true
14113
+ );
14057
14114
  const workerResolvedConfig = getWorkerConfig(
14058
- path8.resolve(root, auxiliaryWorker.configPath),
14115
+ workerConfigPath,
14059
14116
  cloudflareEnv,
14060
14117
  {
14061
14118
  visitedConfigPaths: configPaths
14062
14119
  }
14063
14120
  );
14064
14121
  auxiliaryWorkersResolvedConfigs.push(workerResolvedConfig);
14065
- assert7(
14122
+ assert8(
14066
14123
  workerResolvedConfig.type === "worker",
14067
14124
  "Unexpected error: received AssetsOnlyResult with auxiliary workers."
14068
14125
  );
@@ -14079,7 +14136,6 @@ function resolvePluginConfig(pluginConfig, userConfig, viteEnv) {
14079
14136
  type: "workers",
14080
14137
  configPaths,
14081
14138
  persistState,
14082
- inspectorPort,
14083
14139
  workers,
14084
14140
  entryWorkerEnvironmentName,
14085
14141
  rawConfigs: {
@@ -14127,6 +14183,57 @@ function handleWebSocket(httpServer, getFetcher) {
14127
14183
  );
14128
14184
  }
14129
14185
 
14186
+ // src/worker-environments-validation.ts
14187
+ import assert9 from "node:assert";
14188
+ function validateWorkerEnvironmentsResolvedConfigs(resolvedPluginConfig, resolvedViteConfig) {
14189
+ const workersEnvironmentNames = Object.keys(resolvedPluginConfig.workers);
14190
+ const disallowedEnvsConfigs = /* @__PURE__ */ new Map();
14191
+ for (const envName of workersEnvironmentNames) {
14192
+ const workerEnvConfig = resolvedViteConfig.environments[envName];
14193
+ assert9(workerEnvConfig, `Missing environment config for "${envName}"`);
14194
+ const { optimizeDeps, resolve: resolve7 } = workerEnvConfig;
14195
+ const disallowedConfig = {};
14196
+ const disallowedOptimizeDepsExcludeEntries = (optimizeDeps.exclude ?? []).filter((entry) => {
14197
+ if (cloudflareBuiltInModules.includes(entry)) {
14198
+ return false;
14199
+ }
14200
+ if (isNodeAlsModule(entry) && isNodeAls(resolvedPluginConfig.workers[envName])) {
14201
+ return false;
14202
+ }
14203
+ if (NODEJS_MODULES_RE.test(entry) && isNodeCompat(resolvedPluginConfig.workers[envName])) {
14204
+ return false;
14205
+ }
14206
+ return true;
14207
+ });
14208
+ if (disallowedOptimizeDepsExcludeEntries.length > 0) {
14209
+ disallowedConfig.optimizeDepsExclude = disallowedOptimizeDepsExcludeEntries;
14210
+ }
14211
+ if (resolve7.external === true || resolve7.external.length > 0) {
14212
+ disallowedConfig.resolveExternal = resolve7.external;
14213
+ }
14214
+ if (Object.keys(disallowedConfig).length > 0) {
14215
+ disallowedEnvsConfigs.set(envName, disallowedConfig);
14216
+ }
14217
+ }
14218
+ if (disallowedEnvsConfigs.size > 0) {
14219
+ const errorMessage = `The following environment configurations are incompatible with the Cloudflare Vite plugin:
14220
+ ${[
14221
+ ...disallowedEnvsConfigs
14222
+ ].map(
14223
+ ([envName, disallowedConfig]) => [
14224
+ disallowedConfig.optimizeDepsExclude ? ` - "${envName}" environment: \`optimizeDeps.exclude\`: ${JSON.stringify(disallowedConfig.optimizeDepsExclude)}
14225
+ ` : null,
14226
+ disallowedConfig.resolveExternal ? ` - "${envName}" environment: \`resolve.external\`: ${JSON.stringify(disallowedConfig.resolveExternal)}
14227
+ ` : null
14228
+ ].join("")
14229
+ ).join(
14230
+ ""
14231
+ )}To resolve this issue, avoid setting \`optimizeDeps.exclude\` and \`resolve.external\` in your Cloudflare Worker environments.
14232
+ `;
14233
+ throw new Error(errorMessage);
14234
+ }
14235
+ }
14236
+
14130
14237
  // src/index.ts
14131
14238
  var workersConfigsWarningShown = false;
14132
14239
  var miniflare;
@@ -14197,7 +14304,7 @@ function cloudflare2(pluginConfig = {}) {
14197
14304
  resolvedPluginConfig.workers
14198
14305
  ).map((environmentName) => {
14199
14306
  const environment = builder.environments[environmentName];
14200
- assert8(
14307
+ assert10(
14201
14308
  environment,
14202
14309
  `${environmentName} environment not found`
14203
14310
  );
@@ -14218,6 +14325,12 @@ function cloudflare2(pluginConfig = {}) {
14218
14325
  },
14219
14326
  configResolved(config) {
14220
14327
  resolvedViteConfig = config;
14328
+ if (resolvedPluginConfig?.type === "workers") {
14329
+ validateWorkerEnvironmentsResolvedConfigs(
14330
+ resolvedPluginConfig,
14331
+ resolvedViteConfig
14332
+ );
14333
+ }
14221
14334
  },
14222
14335
  generateBundle(_, bundle) {
14223
14336
  let config;
@@ -14238,7 +14351,7 @@ function cloudflare2(pluginConfig = {}) {
14238
14351
  if (isEntryWorker && hasClientBuild) {
14239
14352
  const workerOutputDirectory = this.environment.config.build.outDir;
14240
14353
  const clientOutputDirectory = resolvedViteConfig.environments.client?.build.outDir;
14241
- assert8(
14354
+ assert10(
14242
14355
  clientOutputDirectory,
14243
14356
  "Unexpected error: client output directory is undefined"
14244
14357
  );
@@ -14302,36 +14415,46 @@ function cloudflare2(pluginConfig = {}) {
14302
14415
  }
14303
14416
  },
14304
14417
  hotUpdate(options) {
14305
- if (
14306
- // Vite normalizes `options.file` so we use `path.resolve` for Windows compatibility
14307
- resolvedPluginConfig.configPaths.has(path9.resolve(options.file)) || hasAssetsConfigChanged(
14308
- resolvedPluginConfig,
14309
- resolvedViteConfig,
14310
- options.file
14311
- )
14312
- ) {
14418
+ const changedFilePath = path9.resolve(options.file);
14419
+ if (resolvedPluginConfig.configPaths.has(changedFilePath) || hasDotDevDotVarsFileChanged(resolvedPluginConfig, changedFilePath) || hasAssetsConfigChanged(
14420
+ resolvedPluginConfig,
14421
+ resolvedViteConfig,
14422
+ changedFilePath
14423
+ )) {
14313
14424
  options.server.restart();
14314
14425
  return [];
14315
14426
  }
14316
14427
  },
14317
14428
  async configureServer(viteDevServer) {
14318
- assert8(
14429
+ assert10(
14319
14430
  viteDevServer.httpServer,
14320
14431
  "Unexpected error: No Vite HTTP server"
14321
14432
  );
14322
- if (miniflare) {
14323
- await miniflare.setOptions(
14324
- getDevMiniflareOptions(resolvedPluginConfig, viteDevServer)
14433
+ const inputInspectorPort = await getInputInspectorPortOption(
14434
+ pluginConfig,
14435
+ viteDevServer
14436
+ );
14437
+ if (!miniflare) {
14438
+ miniflare = new Miniflare(
14439
+ getDevMiniflareOptions(
14440
+ resolvedPluginConfig,
14441
+ viteDevServer,
14442
+ inputInspectorPort
14443
+ )
14325
14444
  );
14326
14445
  } else {
14327
- miniflare = new Miniflare(
14328
- getDevMiniflareOptions(resolvedPluginConfig, viteDevServer)
14446
+ await miniflare.setOptions(
14447
+ getDevMiniflareOptions(
14448
+ resolvedPluginConfig,
14449
+ viteDevServer,
14450
+ inputInspectorPort
14451
+ )
14329
14452
  );
14330
14453
  }
14331
14454
  await initRunners(resolvedPluginConfig, viteDevServer, miniflare);
14332
14455
  const middleware = createMiddleware(
14333
14456
  async ({ request }) => {
14334
- assert8(miniflare, `Miniflare not defined`);
14457
+ assert10(miniflare, `Miniflare not defined`);
14335
14458
  const routerWorker = await getRouterWorker(miniflare);
14336
14459
  return routerWorker.fetch(toMiniflareRequest(request), {
14337
14460
  redirect: "manual"
@@ -14340,7 +14463,7 @@ function cloudflare2(pluginConfig = {}) {
14340
14463
  { alwaysCallNext: false }
14341
14464
  );
14342
14465
  handleWebSocket(viteDevServer.httpServer, async () => {
14343
- assert8(miniflare, `Miniflare not defined`);
14466
+ assert10(miniflare, `Miniflare not defined`);
14344
14467
  const routerWorker = await getRouterWorker(miniflare);
14345
14468
  return routerWorker.fetch;
14346
14469
  });
@@ -14350,14 +14473,18 @@ function cloudflare2(pluginConfig = {}) {
14350
14473
  });
14351
14474
  };
14352
14475
  },
14353
- configurePreviewServer(vitePreviewServer) {
14476
+ async configurePreviewServer(vitePreviewServer) {
14354
14477
  const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
14478
+ const inputInspectorPort = await getInputInspectorPortOption(
14479
+ pluginConfig,
14480
+ vitePreviewServer
14481
+ );
14355
14482
  const miniflare2 = new Miniflare(
14356
14483
  getPreviewMiniflareOptions(
14357
14484
  vitePreviewServer,
14358
14485
  workerConfigs,
14359
14486
  pluginConfig.persistState ?? true,
14360
- pluginConfig.inspectorPort
14487
+ inputInspectorPort
14361
14488
  )
14362
14489
  );
14363
14490
  const middleware = createMiddleware(
@@ -14436,7 +14563,7 @@ function cloudflare2(pluginConfig = {}) {
14436
14563
  for (const match of matches) {
14437
14564
  magicString ??= new MagicString(code);
14438
14565
  const [full, _, modulePath] = match;
14439
- assert8(
14566
+ assert10(
14440
14567
  modulePath,
14441
14568
  `Unexpected error: module path not found in reference ${full}.`
14442
14569
  );
@@ -14482,17 +14609,22 @@ function cloudflare2(pluginConfig = {}) {
14482
14609
  configEnvironment(name) {
14483
14610
  if (isNodeCompat(getWorkerConfig2(name))) {
14484
14611
  return {
14612
+ build: {
14613
+ rollupOptions: {
14614
+ plugins: [
14615
+ replace({
14616
+ "process.env.NODE_ENV": JSON.stringify(
14617
+ process.env.NODE_ENV ?? "production"
14618
+ ),
14619
+ preventAssignment: true
14620
+ })
14621
+ ]
14622
+ }
14623
+ },
14485
14624
  resolve: {
14486
14625
  builtins: [...nodeCompatExternals]
14487
14626
  },
14488
14627
  optimizeDeps: {
14489
- // This is a list of dependency entry-points that should be pre-bundled.
14490
- // In this case we provide a list of all the possible polyfills so that they are pre-bundled,
14491
- // ready ahead the first request to the dev server.
14492
- // Without this the dependency optimizer will try to bundle them on-the-fly in the middle of the first request,
14493
- // which can potentially cause problems if it leads to previous pre-bundling to become stale and needing to be reloaded.
14494
- // TODO: work out how to re-enable pre-bundling of these
14495
- // include: [...getNodeCompatEntries()],
14496
14628
  // This is a list of module specifiers that the dependency optimizer should not follow when doing import analysis.
14497
14629
  // 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.
14498
14630
  // Obviously we don't want/need the optimizer to try to process modules that are built-in;
@@ -14516,7 +14648,7 @@ function cloudflare2(pluginConfig = {}) {
14516
14648
  return this.resolve(source, importer, options);
14517
14649
  }
14518
14650
  if (this.environment.mode === "dev") {
14519
- assert8(
14651
+ assert10(
14520
14652
  this.environment.depsOptimizer,
14521
14653
  "depsOptimizer is required in dev mode"
14522
14654
  );
@@ -14530,11 +14662,54 @@ function cloudflare2(pluginConfig = {}) {
14530
14662
  },
14531
14663
  async transform(code, id) {
14532
14664
  const workerConfig = getWorkerConfig2(this.environment.name);
14533
- assert8(workerConfig, "Expected a worker config");
14665
+ if (!workerConfig) {
14666
+ return;
14667
+ }
14534
14668
  const resolvedId = await this.resolve(workerConfig.main);
14535
14669
  if (id === resolvedId?.id) {
14536
14670
  return injectGlobalCode(id, code);
14537
14671
  }
14672
+ },
14673
+ async configureServer(viteDevServer) {
14674
+ await Promise.all(
14675
+ Object.values(viteDevServer.environments).flatMap(
14676
+ async (environment) => {
14677
+ const workerConfig = getWorkerConfig2(environment.name);
14678
+ if (isNodeCompat(workerConfig)) {
14679
+ await environment.depsOptimizer?.init();
14680
+ return Array.from(nodeCompatEntries).map((entry) => {
14681
+ const result = resolveNodeJSImport(entry);
14682
+ if (result) {
14683
+ const registration = environment.depsOptimizer?.registerMissingImport(
14684
+ result.unresolved,
14685
+ result.resolved
14686
+ );
14687
+ return registration?.processing;
14688
+ }
14689
+ });
14690
+ }
14691
+ }
14692
+ )
14693
+ );
14694
+ }
14695
+ },
14696
+ // Plugin that handles Node.js Async Local Storage (ALS) compatibility support for Vite Environments that are hosted in Cloudflare Workers.
14697
+ {
14698
+ name: "vite-plugin-cloudflare:nodejs-als",
14699
+ apply(_config, env2) {
14700
+ return !env2.isPreview;
14701
+ },
14702
+ configEnvironment(name, config) {
14703
+ if (isNodeAls(getWorkerConfig2(name))) {
14704
+ return {
14705
+ resolve: {
14706
+ builtins: ["async_hooks", "node:async_hooks"]
14707
+ },
14708
+ optimizeDeps: {
14709
+ exclude: ["async_hooks", "node:async_hooks"]
14710
+ }
14711
+ };
14712
+ }
14538
14713
  }
14539
14714
  },
14540
14715
  // Plugin that provides an __debug path for debugging the Cloudflare Workers.
@@ -14544,39 +14719,35 @@ function cloudflare2(pluginConfig = {}) {
14544
14719
  // the preview middleware here can take precedence
14545
14720
  enforce: "pre",
14546
14721
  configureServer(viteDevServer) {
14547
- if (resolvedPluginConfig.type === "workers" && resolvedPluginConfig.inspectorPort !== false) {
14722
+ if (resolvedPluginConfig.type === "workers" && pluginConfig.inspectorPort !== false) {
14548
14723
  addDebugToVitePrintUrls(viteDevServer);
14549
14724
  }
14550
14725
  const workerNames = resolvedPluginConfig.type === "assets-only" ? [] : Object.values(resolvedPluginConfig.workers).map(
14551
14726
  (worker) => worker.name
14552
14727
  );
14553
- viteDevServer.middlewares.use((req, res, next) => {
14554
- if (req.url === debuggingPath && resolvedPluginConfig.inspectorPort !== false) {
14555
- const html = getDebugPathHtml(
14556
- workerNames,
14557
- resolvedPluginConfig.inspectorPort
14558
- );
14728
+ viteDevServer.middlewares.use(async (req, res, next) => {
14729
+ const resolvedInspectorPort = await getResolvedInspectorPort(pluginConfig);
14730
+ if (req.url === debuggingPath && resolvedInspectorPort) {
14731
+ const html = getDebugPathHtml(workerNames, resolvedInspectorPort);
14559
14732
  res.setHeader("Content-Type", "text/html");
14560
14733
  return res.end(html);
14561
14734
  }
14562
14735
  next();
14563
14736
  });
14564
14737
  },
14565
- configurePreviewServer(vitePreviewServer) {
14738
+ async configurePreviewServer(vitePreviewServer) {
14566
14739
  const workerConfigs = getWorkerConfigs(vitePreviewServer.config.root);
14567
14740
  if (workerConfigs.length >= 1 && pluginConfig.inspectorPort !== false) {
14568
14741
  addDebugToVitePrintUrls(vitePreviewServer);
14569
14742
  }
14570
14743
  const workerNames = workerConfigs.map((worker) => {
14571
- assert8(worker.name, "Expected the Worker to have a name");
14744
+ assert10(worker.name, "Expected the Worker to have a name");
14572
14745
  return worker.name;
14573
14746
  });
14574
- vitePreviewServer.middlewares.use((req, res, next) => {
14575
- if (req.url === debuggingPath && pluginConfig.inspectorPort !== false) {
14576
- const html = getDebugPathHtml(
14577
- workerNames,
14578
- pluginConfig.inspectorPort ?? DEFAULT_INSPECTOR_PORT
14579
- );
14747
+ vitePreviewServer.middlewares.use(async (req, res, next) => {
14748
+ const resolvedInspectorPort = await getResolvedInspectorPort(pluginConfig);
14749
+ if (req.url === debuggingPath && resolvedInspectorPort) {
14750
+ const html = getDebugPathHtml(workerNames, resolvedInspectorPort);
14580
14751
  res.setHeader("Content-Type", "text/html");
14581
14752
  return res.end(html);
14582
14753
  }
@@ -14590,6 +14761,9 @@ function cloudflare2(pluginConfig = {}) {
14590
14761
  apply(_config, env2) {
14591
14762
  return !env2.isPreview;
14592
14763
  },
14764
+ // We must ensure that the `resolveId` hook runs before the built-in ones.
14765
+ // Otherwise we never see the Node.js built-in imports since they get handled by default Vite behavior.
14766
+ enforce: "pre",
14593
14767
  configEnvironment(environmentName) {
14594
14768
  const workerConfig = getWorkerConfig2(environmentName);
14595
14769
  if (workerConfig && !isNodeCompat(workerConfig)) {
@@ -14603,21 +14777,14 @@ function cloudflare2(pluginConfig = {}) {
14603
14777
  build.onResolve(
14604
14778
  { filter: NODEJS_MODULES_RE },
14605
14779
  ({ path: path10, importer }) => {
14780
+ if (isNodeAls(workerConfig) && isNodeAlsModule(path10)) {
14781
+ return;
14782
+ }
14606
14783
  const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14607
- assert8(
14608
- nodeJsCompatWarnings,
14609
- `expected nodeJsCompatWarnings to be defined for Worker "${workerConfig.name}"`
14610
- );
14611
- nodeJsCompatWarnings.registerImport(path10, importer);
14784
+ nodeJsCompatWarnings?.registerImport(path10, importer);
14612
14785
  return { path: path10, external: true };
14613
14786
  }
14614
14787
  );
14615
- build.onEnd(() => {
14616
- const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14617
- if (nodeJsCompatWarnings) {
14618
- nodeJsCompatWarnings.renderWarnings();
14619
- }
14620
- });
14621
14788
  }
14622
14789
  }
14623
14790
  ]
@@ -14626,47 +14793,28 @@ function cloudflare2(pluginConfig = {}) {
14626
14793
  };
14627
14794
  }
14628
14795
  },
14629
- configureServer(viteDevServer) {
14630
- for (const environment of Object.values(viteDevServer.environments)) {
14631
- const workerConfig = getWorkerConfig2(environment.name);
14796
+ configResolved(resolvedViteConfig2) {
14797
+ for (const environmentName of Object.keys(
14798
+ resolvedViteConfig2.environments
14799
+ )) {
14800
+ const workerConfig = getWorkerConfig2(environmentName);
14632
14801
  if (workerConfig && !isNodeCompat(workerConfig)) {
14633
14802
  nodeJsCompatWarningsMap.set(
14634
14803
  workerConfig,
14635
- new NodeJsCompatWarnings(environment)
14804
+ new NodeJsCompatWarnings(environmentName, resolvedViteConfig2)
14636
14805
  );
14637
14806
  }
14638
14807
  }
14639
14808
  },
14640
- buildStart() {
14641
- const workerConfig = getWorkerConfig2(this.environment.name);
14642
- if (workerConfig && !isNodeCompat(workerConfig)) {
14643
- nodeJsCompatWarningsMap.set(
14644
- workerConfig,
14645
- new NodeJsCompatWarnings(this.environment)
14646
- );
14647
- }
14648
- },
14649
- buildEnd() {
14650
- const workerConfig = getWorkerConfig2(this.environment.name);
14651
- if (workerConfig && !isNodeCompat(workerConfig)) {
14652
- const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14653
- assert8(
14654
- nodeJsCompatWarnings,
14655
- `expected nodeJsCompatWarnings to be defined for Worker "${workerConfig.name}"`
14656
- );
14657
- nodeJsCompatWarnings.renderWarnings();
14658
- }
14659
- },
14660
- // We must ensure that the `resolveId` hook runs before the built-in ones otherwise we
14661
- // never see the Node.js built-in imports since they get handled by default Vite behavior.
14662
- enforce: "pre",
14663
14809
  async resolveId(source, importer) {
14664
14810
  const workerConfig = getWorkerConfig2(this.environment.name);
14665
14811
  if (workerConfig && !isNodeCompat(workerConfig)) {
14812
+ if (isNodeAls(workerConfig) && isNodeAlsModule(source)) {
14813
+ return;
14814
+ }
14666
14815
  const nodeJsCompatWarnings = nodeJsCompatWarningsMap.get(workerConfig);
14667
14816
  if (nodejsBuiltins.has(source)) {
14668
14817
  nodeJsCompatWarnings?.registerImport(source, importer);
14669
- nodeJsCompatWarnings?.renderWarningsOnIdle();
14670
14818
  return {
14671
14819
  id: source,
14672
14820
  external: true
@@ -14677,10 +14825,35 @@ function cloudflare2(pluginConfig = {}) {
14677
14825
  }
14678
14826
  ];
14679
14827
  function getWorkerConfig2(environmentName) {
14680
- assert8(resolvedPluginConfig, "Expected resolvedPluginConfig to be defined");
14828
+ assert10(resolvedPluginConfig, "Expected resolvedPluginConfig to be defined");
14681
14829
  return resolvedPluginConfig.type !== "assets-only" ? resolvedPluginConfig.workers[environmentName] : void 0;
14682
14830
  }
14683
14831
  }
14832
+ async function getInputInspectorPortOption(pluginConfig, viteServer) {
14833
+ if (pluginConfig.inspectorPort === void 0 || pluginConfig.inspectorPort === 0) {
14834
+ const resolvedInspectorPort = await getResolvedInspectorPort(pluginConfig);
14835
+ if (resolvedInspectorPort !== null) {
14836
+ return resolvedInspectorPort;
14837
+ }
14838
+ }
14839
+ const inputInspectorPort = pluginConfig.inspectorPort ?? await getFirstAvailablePort(DEFAULT_INSPECTOR_PORT);
14840
+ if (pluginConfig.inspectorPort === void 0 && inputInspectorPort !== DEFAULT_INSPECTOR_PORT) {
14841
+ viteServer.config.logger.warn(
14842
+ colors2.dim(
14843
+ `Default inspector port ${DEFAULT_INSPECTOR_PORT} not available, using ${inputInspectorPort} instead
14844
+ `
14845
+ )
14846
+ );
14847
+ }
14848
+ return inputInspectorPort;
14849
+ }
14850
+ async function getResolvedInspectorPort(pluginConfig) {
14851
+ if (miniflare && pluginConfig.inspectorPort !== false) {
14852
+ const miniflareInspectorUrl = await miniflare.getInspectorURL();
14853
+ return Number.parseInt(miniflareInspectorUrl.port);
14854
+ }
14855
+ return null;
14856
+ }
14684
14857
  function getDotDevDotVarsContent(configPath, cloudflareEnv) {
14685
14858
  const configDir = path9.dirname(configPath);
14686
14859
  const defaultDotDevDotVarsPath = `${configDir}/.dev.vars`;
@@ -14692,6 +14865,19 @@ function getDotDevDotVarsContent(configPath, cloudflareEnv) {
14692
14865
  }
14693
14866
  return null;
14694
14867
  }
14868
+ function hasDotDevDotVarsFileChanged(resolvedPluginConfig, changedFilePath) {
14869
+ return [...resolvedPluginConfig.configPaths].some((configPath) => {
14870
+ const dotDevDotVars = path9.join(path9.dirname(configPath), ".dev.vars");
14871
+ if (dotDevDotVars === changedFilePath) {
14872
+ return true;
14873
+ }
14874
+ if (resolvedPluginConfig.cloudflareEnv) {
14875
+ const dotDevDotVarsForEnv = `${dotDevDotVars}.${resolvedPluginConfig.cloudflareEnv}`;
14876
+ return dotDevDotVarsForEnv === changedFilePath;
14877
+ }
14878
+ return false;
14879
+ });
14880
+ }
14695
14881
  export {
14696
14882
  cloudflare2 as cloudflare
14697
14883
  };