wxt 0.14.4 → 0.14.6

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/cli.js CHANGED
@@ -5,7 +5,7 @@ import "./chunk-73I7FAJU.js";
5
5
  import cac from "cac";
6
6
 
7
7
  // package.json
8
- var version = "0.14.4";
8
+ var version = "0.14.6";
9
9
 
10
10
  // src/core/utils/fs.ts
11
11
  import fs from "fs-extra";
@@ -77,11 +77,27 @@ function every(array, predicate) {
77
77
  return false;
78
78
  return true;
79
79
  }
80
+ function some(array, predicate) {
81
+ for (let i = 0; i < array.length; i++)
82
+ if (predicate(array[i], i))
83
+ return true;
84
+ return false;
85
+ }
80
86
 
81
87
  // src/core/utils/building/detect-dev-changes.ts
82
- function detectDevChanges(changedFiles, currentOutput) {
83
- if (currentOutput == null)
84
- return { type: "no-change" };
88
+ function detectDevChanges(config, changedFiles, currentOutput) {
89
+ const isConfigChange = some(
90
+ changedFiles,
91
+ (file) => file === config.userConfigMetadata.configFile
92
+ );
93
+ if (isConfigChange)
94
+ return { type: "full-restart" };
95
+ const isRunnerChange = some(
96
+ changedFiles,
97
+ (file) => file === config.runnerConfig.configFile
98
+ );
99
+ if (isRunnerChange)
100
+ return { type: "browser-restart" };
85
101
  const changedSteps = new Set(
86
102
  changedFiles.flatMap(
87
103
  (changedFile) => findEffectedSteps(changedFile, currentOutput)
@@ -113,7 +129,7 @@ function detectDevChanges(changedFiles, currentOutput) {
113
129
  unchangedOutput.publicAssets.push(asset);
114
130
  }
115
131
  }
116
- const isOnlyHtmlChanges = changedFiles.length > 0 && every(changedFiles, ([_, file]) => file.endsWith(".html"));
132
+ const isOnlyHtmlChanges = changedFiles.length > 0 && every(changedFiles, (file) => file.endsWith(".html"));
117
133
  if (isOnlyHtmlChanges) {
118
134
  return {
119
135
  type: "html-reload",
@@ -141,7 +157,7 @@ function detectDevChanges(changedFiles, currentOutput) {
141
157
  }
142
158
  function findEffectedSteps(changedFile, currentOutput) {
143
159
  const changes = [];
144
- const changedPath = normalizePath(changedFile[1]);
160
+ const changedPath = normalizePath(changedFile);
145
161
  const isChunkEffected = (chunk) => (
146
162
  // If it's an HTML file with the same path, is is effected because HTML files need to be pre-rendered
147
163
  // fileName is normalized, relative bundle path
@@ -1489,6 +1505,9 @@ async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
1489
1505
  async listen() {
1490
1506
  await viteServer.listen(info.port);
1491
1507
  },
1508
+ async close() {
1509
+ await viteServer.close();
1510
+ },
1492
1511
  transformHtml(...args) {
1493
1512
  return viteServer.transformIndexHtml(...args);
1494
1513
  },
@@ -1554,6 +1573,7 @@ async function getInternalConfig(inlineConfig, command, server) {
1554
1573
  const typesDir = path3.resolve(wxtDir, "types");
1555
1574
  const outBaseDir = path3.resolve(root, mergedConfig.outDir ?? ".output");
1556
1575
  const outDir = path3.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
1576
+ const reloadCommand = mergedConfig.dev?.reloadCommand ?? "Alt+R";
1557
1577
  const runnerConfig = await loadConfig({
1558
1578
  name: "web-ext",
1559
1579
  cwd: root,
@@ -1606,7 +1626,10 @@ async function getInternalConfig(inlineConfig, command, server) {
1606
1626
  experimental: {
1607
1627
  includeBrowserPolyfill: mergedConfig.experimental?.includeBrowserPolyfill ?? true
1608
1628
  },
1609
- server
1629
+ server,
1630
+ dev: {
1631
+ reloadCommand
1632
+ }
1610
1633
  };
1611
1634
  const builder = await createViteBuilder(
1612
1635
  inlineConfig,
@@ -1673,7 +1696,11 @@ function mergeInlineConfig(inlineConfig, userConfig) {
1673
1696
  ...inlineConfig.experimental
1674
1697
  },
1675
1698
  vite: void 0,
1676
- transformManifest: void 0
1699
+ transformManifest: void 0,
1700
+ dev: {
1701
+ ...userConfig.dev,
1702
+ ...inlineConfig.dev
1703
+ }
1677
1704
  };
1678
1705
  }
1679
1706
  function resolveInternalZipConfig(root, mergedConfig) {
@@ -2089,6 +2116,7 @@ async function writeManifest(manifest, output, config) {
2089
2116
  });
2090
2117
  }
2091
2118
  async function generateManifest(entrypoints, buildOutput, config) {
2119
+ const warnings = [];
2092
2120
  const pkg = await getPackageJson(config);
2093
2121
  let versionName = config.manifest.version_name ?? config.manifest.version ?? pkg?.version;
2094
2122
  if (versionName == null) {
@@ -2106,21 +2134,26 @@ async function generateManifest(entrypoints, buildOutput, config) {
2106
2134
  short_name: pkg?.shortName,
2107
2135
  icons: discoverIcons(buildOutput)
2108
2136
  };
2109
- if (config.command === "serve") {
2110
- baseManifest.commands = {
2111
- "wxt:reload-extension": {
2112
- description: "Reload the extension during development",
2113
- suggested_key: {
2114
- default: "Alt+R"
2115
- }
2116
- }
2117
- };
2118
- }
2119
2137
  const userManifest = config.manifest;
2120
2138
  const manifest = defu3(
2121
2139
  userManifest,
2122
2140
  baseManifest
2123
2141
  );
2142
+ if (config.command === "serve" && config.dev.reloadCommand) {
2143
+ if (manifest.commands && Object.keys(manifest.commands).length >= 4) {
2144
+ warnings.push([
2145
+ "Extension already has 4 registered commands, WXT's reload command is disabled"
2146
+ ]);
2147
+ } else {
2148
+ manifest.commands ??= {};
2149
+ manifest.commands["wxt:reload-extension"] = {
2150
+ description: "Reload the extension during development",
2151
+ suggested_key: {
2152
+ default: config.dev.reloadCommand
2153
+ }
2154
+ };
2155
+ }
2156
+ }
2124
2157
  manifest.version = version2;
2125
2158
  manifest.version_name = // Firefox doesn't support version_name
2126
2159
  config.browser === "firefox" || versionName === version2 ? void 0 : versionName;
@@ -2139,7 +2172,10 @@ async function generateManifest(entrypoints, buildOutput, config) {
2139
2172
  "Manifest 'version' is missing. Either:\n1. Add a version in your <rootDir>/package.json\n2. Pass the version via the manifest option in your wxt.config.ts"
2140
2173
  );
2141
2174
  }
2142
- return finalManifest;
2175
+ return {
2176
+ manifest: finalManifest,
2177
+ warnings
2178
+ };
2143
2179
  }
2144
2180
  function simplifyVersion(versionName) {
2145
2181
  const version2 = /^((0|[1-9][0-9]{0,8})([.](0|[1-9][0-9]{0,8})){0,3}).*$/.exec(
@@ -2500,11 +2536,7 @@ async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput
2500
2536
  steps: [...existingOutput.steps, ...newOutput.steps],
2501
2537
  publicAssets: [...existingOutput.publicAssets, ...newOutput.publicAssets]
2502
2538
  };
2503
- const newManifest = await generateManifest(
2504
- allEntrypoints,
2505
- mergedOutput,
2506
- config
2507
- );
2539
+ const { manifest: newManifest, warnings: manifestWarnings } = await generateManifest(allEntrypoints, mergedOutput, config);
2508
2540
  const finalOutput = {
2509
2541
  manifest: newManifest,
2510
2542
  ...newOutput
@@ -2520,11 +2552,76 @@ async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput
2520
2552
  ...finalOutput.publicAssets
2521
2553
  ]
2522
2554
  },
2523
- manifest: newManifest
2555
+ manifest: newManifest,
2556
+ warnings: manifestWarnings
2524
2557
  };
2525
2558
  }
2526
2559
 
2527
2560
  // src/core/utils/building/internal-build.ts
2561
+ import managePath from "manage-path";
2562
+ import { resolve as resolve13, relative as relative6 } from "node:path";
2563
+
2564
+ // src/core/utils/validation.ts
2565
+ function validateEntrypoints(entrypoints) {
2566
+ const errors = entrypoints.flatMap((entrypoint) => {
2567
+ switch (entrypoint.type) {
2568
+ case "content-script":
2569
+ return validateContentScriptEntrypoint(entrypoint);
2570
+ default:
2571
+ return validateBaseEntrypoint(entrypoint);
2572
+ }
2573
+ });
2574
+ let errorCount = 0;
2575
+ let warningCount = 0;
2576
+ for (const err of errors) {
2577
+ if (err.type === "warning")
2578
+ warningCount++;
2579
+ else
2580
+ errorCount++;
2581
+ }
2582
+ return {
2583
+ errors,
2584
+ errorCount,
2585
+ warningCount
2586
+ };
2587
+ }
2588
+ function validateContentScriptEntrypoint(definition) {
2589
+ const errors = validateBaseEntrypoint(definition);
2590
+ if (definition.options.matches == null) {
2591
+ errors.push({
2592
+ type: "error",
2593
+ message: "`matches` is required",
2594
+ value: definition.options.matches,
2595
+ entrypoint: definition
2596
+ });
2597
+ }
2598
+ return errors;
2599
+ }
2600
+ function validateBaseEntrypoint(definition) {
2601
+ const errors = [];
2602
+ if (definition.options.exclude != null && !Array.isArray(definition.options.exclude)) {
2603
+ errors.push({
2604
+ type: "error",
2605
+ message: "`exclude` must be an array of browser names",
2606
+ value: definition.options.exclude,
2607
+ entrypoint: definition
2608
+ });
2609
+ }
2610
+ if (definition.options.include != null && !Array.isArray(definition.options.include)) {
2611
+ errors.push({
2612
+ type: "error",
2613
+ message: "`include` must be an array of browser names",
2614
+ value: definition.options.include,
2615
+ entrypoint: definition
2616
+ });
2617
+ }
2618
+ return errors;
2619
+ }
2620
+ var ValidationError = class extends Error {
2621
+ };
2622
+
2623
+ // src/core/utils/building/internal-build.ts
2624
+ import consola3 from "consola";
2528
2625
  async function internalBuild(config) {
2529
2626
  const verb = config.command === "serve" ? "Pre-rendering" : "Building";
2530
2627
  const target = `${config.browser}-mv${config.manifestVersion}`;
@@ -2538,14 +2635,31 @@ async function internalBuild(config) {
2538
2635
  await fs12.ensureDir(config.outDir);
2539
2636
  const entrypoints = await findEntrypoints(config);
2540
2637
  config.logger.debug("Detected entrypoints:", entrypoints);
2638
+ const validationResults = validateEntrypoints(entrypoints);
2639
+ if (validationResults.errorCount + validationResults.warningCount > 0) {
2640
+ printValidationResults(config, validationResults);
2641
+ }
2642
+ if (validationResults.errorCount > 0) {
2643
+ throw new ValidationError(`Entrypoint validation failed`, {
2644
+ cause: validationResults
2645
+ });
2646
+ }
2541
2647
  const groups = groupEntrypoints(entrypoints);
2542
- const { output } = await rebuild(config, entrypoints, groups, void 0);
2648
+ const { output, warnings } = await rebuild(
2649
+ config,
2650
+ entrypoints,
2651
+ groups,
2652
+ void 0
2653
+ );
2543
2654
  await printBuildSummary(
2544
2655
  config.logger.success,
2545
2656
  `Built extension in ${formatDuration(Date.now() - startTime)}`,
2546
2657
  output,
2547
2658
  config
2548
2659
  );
2660
+ for (const warning of warnings) {
2661
+ config.logger.warn(...warning);
2662
+ }
2549
2663
  if (config.analysis.enabled) {
2550
2664
  await combineAnalysisStats(config);
2551
2665
  config.logger.info(
@@ -2562,11 +2676,35 @@ async function combineAnalysisStats(config) {
2562
2676
  absolute: true
2563
2677
  });
2564
2678
  const absolutePaths = unixFiles.map(unnormalizePath);
2679
+ const alterPath = managePath(process.env);
2680
+ alterPath.push(resolve13(config.root, "node_modules/wxt/node_modules/.bin"));
2565
2681
  await execaCommand(
2566
2682
  `rollup-plugin-visualizer ${absolutePaths.join(" ")} --template ${config.analysis.template}`,
2567
2683
  { cwd: config.root, stdio: "inherit" }
2568
2684
  );
2569
2685
  }
2686
+ function printValidationResults(config, { errorCount, errors, warningCount }) {
2687
+ (errorCount > 0 ? config.logger.error : config.logger.warn)(
2688
+ `Entrypoint validation failed: ${errorCount} error${errorCount === 1 ? "" : "s"}, ${warningCount} warning${warningCount === 1 ? "" : "s"}`
2689
+ );
2690
+ const cwd = process.cwd();
2691
+ const entrypointErrors = errors.reduce((map, error) => {
2692
+ const entryErrors = map.get(error.entrypoint) ?? [];
2693
+ entryErrors.push(error);
2694
+ map.set(error.entrypoint, entryErrors);
2695
+ return map;
2696
+ }, /* @__PURE__ */ new Map());
2697
+ Array.from(entrypointErrors.entries()).forEach(([entrypoint, errors2]) => {
2698
+ consola3.log(relative6(cwd, entrypoint.inputPath));
2699
+ console.log();
2700
+ errors2.forEach((err) => {
2701
+ const type = err.type === "error" ? pc5.red("ERROR") : pc5.yellow("WARN");
2702
+ const recieved = pc5.dim(`(recieved: ${JSON.stringify(err.value)})`);
2703
+ consola3.log(` - ${type} ${err.message} ${recieved}`);
2704
+ });
2705
+ console.log();
2706
+ });
2707
+ }
2570
2708
 
2571
2709
  // src/core/build.ts
2572
2710
  async function build(config) {
@@ -2578,17 +2716,17 @@ async function build(config) {
2578
2716
  import path5 from "node:path";
2579
2717
  import glob4 from "fast-glob";
2580
2718
  import fs13 from "fs-extra";
2581
- import { consola as consola3 } from "consola";
2719
+ import { consola as consola4 } from "consola";
2582
2720
  import pc6 from "picocolors";
2583
2721
  async function clean(root = process.cwd()) {
2584
- consola3.info("Cleaning Project");
2722
+ consola4.info("Cleaning Project");
2585
2723
  const tempDirs = [
2586
2724
  "node_modules/.vite",
2587
2725
  "node_modules/.cache",
2588
2726
  "**/.wxt",
2589
2727
  ".output/*"
2590
2728
  ];
2591
- consola3.debug("Looking for:", tempDirs.map(pc6.cyan).join(", "));
2729
+ consola4.debug("Looking for:", tempDirs.map(pc6.cyan).join(", "));
2592
2730
  const directories = await glob4(tempDirs, {
2593
2731
  cwd: path5.resolve(root),
2594
2732
  absolute: true,
@@ -2596,26 +2734,26 @@ async function clean(root = process.cwd()) {
2596
2734
  deep: 2
2597
2735
  });
2598
2736
  if (directories.length === 0) {
2599
- consola3.debug("No generated files found.");
2737
+ consola4.debug("No generated files found.");
2600
2738
  return;
2601
2739
  }
2602
- consola3.debug(
2740
+ consola4.debug(
2603
2741
  "Found:",
2604
2742
  directories.map((dir) => pc6.cyan(path5.relative(root, dir))).join(", ")
2605
2743
  );
2606
2744
  for (const directory of directories) {
2607
2745
  await fs13.rm(directory, { force: true, recursive: true });
2608
- consola3.debug("Deleted " + pc6.cyan(path5.relative(root, directory)));
2746
+ consola4.debug("Deleted " + pc6.cyan(path5.relative(root, directory)));
2609
2747
  }
2610
2748
  }
2611
2749
 
2612
2750
  // src/core/runners/wsl.ts
2613
- import { relative as relative6 } from "node:path";
2751
+ import { relative as relative7 } from "node:path";
2614
2752
  function createWslRunner() {
2615
2753
  return {
2616
2754
  async openBrowser(config) {
2617
2755
  config.logger.warn(
2618
- `Cannot open browser when using WSL. Load "${relative6(
2756
+ `Cannot open browser when using WSL. Load "${relative7(
2619
2757
  process.cwd(),
2620
2758
  config.outDir
2621
2759
  )}" as an unpacked extension manually`
@@ -2631,7 +2769,7 @@ function createWebExtRunner() {
2631
2769
  let runner;
2632
2770
  return {
2633
2771
  async openBrowser(config) {
2634
- config.logger.info("Opening browser...");
2772
+ const startTime = Date.now();
2635
2773
  if (config.browser === "firefox" && config.manifestVersion === 3) {
2636
2774
  throw Error(
2637
2775
  "Dev mode does not support Firefox MV3. For alternatives, see https://github.com/wxt-dev/wxt/issues/230#issuecomment-1806881653"
@@ -2676,7 +2814,8 @@ function createWebExtRunner() {
2676
2814
  config.logger.debug("web-ext options:", options);
2677
2815
  const webExt = await import("web-ext-run");
2678
2816
  runner = await webExt.default.cmd.run(finalConfig, options);
2679
- config.logger.success("Opened!");
2817
+ const duration = Date.now() - startTime;
2818
+ config.logger.success(`Opened browser in ${formatDuration(duration)}`);
2680
2819
  },
2681
2820
  async closeBrowser() {
2682
2821
  return await runner?.exit();
@@ -2687,12 +2826,12 @@ var WARN_LOG_LEVEL = 40;
2687
2826
  var ERROR_LOG_LEVEL = 50;
2688
2827
 
2689
2828
  // src/core/runners/safari.ts
2690
- import { relative as relative7 } from "node:path";
2829
+ import { relative as relative8 } from "node:path";
2691
2830
  function createSafariRunner() {
2692
2831
  return {
2693
2832
  async openBrowser(config) {
2694
2833
  config.logger.warn(
2695
- `Cannot Safari using web-ext. Load "${relative7(
2834
+ `Cannot Safari using web-ext. Load "${relative8(
2696
2835
  process.cwd(),
2697
2836
  config.outDir
2698
2837
  )}" as an unpacked extension manually`
@@ -2704,12 +2843,12 @@ function createSafariRunner() {
2704
2843
  }
2705
2844
 
2706
2845
  // src/core/runners/manual.ts
2707
- import { relative as relative8 } from "node:path";
2846
+ import { relative as relative9 } from "node:path";
2708
2847
  function createManualRunner() {
2709
2848
  return {
2710
2849
  async openBrowser(config) {
2711
2850
  config.logger.info(
2712
- `Load "${relative8(
2851
+ `Load "${relative9(
2713
2852
  process.cwd(),
2714
2853
  config.outDir
2715
2854
  )}" as an unpacked extension manually`
@@ -2738,10 +2877,10 @@ async function createExtensionRunner(config) {
2738
2877
  }
2739
2878
 
2740
2879
  // src/core/create-server.ts
2741
- import { consola as consola4 } from "consola";
2880
+ import { consola as consola5 } from "consola";
2742
2881
  import { Mutex } from "async-mutex";
2743
2882
  import pc7 from "picocolors";
2744
- import { relative as relative9 } from "node:path";
2883
+ import { relative as relative10 } from "node:path";
2745
2884
  async function createServer(inlineConfig) {
2746
2885
  const port = await getPort();
2747
2886
  const hostname = "localhost";
@@ -2751,19 +2890,36 @@ async function createServer(inlineConfig) {
2751
2890
  hostname,
2752
2891
  origin
2753
2892
  };
2893
+ const buildAndOpenBrowser = async () => {
2894
+ server.currentOutput = await internalBuild(config);
2895
+ await runner.openBrowser(config);
2896
+ };
2897
+ const closeAndRecreateRunner = async () => {
2898
+ await runner.closeBrowser();
2899
+ config = await getLatestConfig();
2900
+ runner = await createExtensionRunner(config);
2901
+ };
2754
2902
  const server = {
2755
2903
  ...serverInfo,
2756
- watcher: void 0,
2757
- // Filled out later down below
2758
- ws: void 0,
2759
- // Filled out later down below
2904
+ get watcher() {
2905
+ return builderServer.watcher;
2906
+ },
2907
+ get ws() {
2908
+ return builderServer.ws;
2909
+ },
2760
2910
  currentOutput: void 0,
2761
- // Filled out later down below
2762
2911
  async start() {
2763
2912
  await builderServer.listen();
2764
2913
  config.logger.success(`Started dev server @ ${serverInfo.origin}`);
2765
- server.currentOutput = await internalBuild(config);
2766
- await runner.openBrowser(config);
2914
+ await buildAndOpenBrowser();
2915
+ },
2916
+ async stop() {
2917
+ await runner.closeBrowser();
2918
+ await builderServer.close();
2919
+ },
2920
+ async restart() {
2921
+ await closeAndRecreateRunner();
2922
+ await buildAndOpenBrowser();
2767
2923
  },
2768
2924
  transformHtml(url, html, originalUrl) {
2769
2925
  return builderServer.transformHtml(url, html, originalUrl);
@@ -2776,17 +2932,21 @@ async function createServer(inlineConfig) {
2776
2932
  },
2777
2933
  reloadExtension() {
2778
2934
  server.ws.send("wxt:reload-extension");
2935
+ },
2936
+ async restartBrowser() {
2937
+ await closeAndRecreateRunner();
2938
+ await runner.openBrowser(config);
2779
2939
  }
2780
2940
  };
2781
2941
  const getLatestConfig = () => getInternalConfig(inlineConfig ?? {}, "serve", server);
2782
2942
  let config = await getLatestConfig();
2783
- const [runner, builderServer] = await Promise.all([
2943
+ let [runner, builderServer] = await Promise.all([
2784
2944
  createExtensionRunner(config),
2785
2945
  config.builder.createServer(server)
2786
2946
  ]);
2787
- server.watcher = builderServer.watcher;
2788
- server.ws = builderServer.ws;
2789
2947
  server.ws.on("wxt:background-initialized", () => {
2948
+ if (server.currentOutput == null)
2949
+ return;
2790
2950
  reloadContentScripts(server.currentOutput.steps, config, server);
2791
2951
  });
2792
2952
  const reloadOnChange = createFileReloader({
@@ -2814,18 +2974,34 @@ function createFileReloader(options) {
2814
2974
  return;
2815
2975
  changeQueue.push([event, path7]);
2816
2976
  await fileChangedMutex.runExclusive(async () => {
2817
- const fileChanges = changeQueue.splice(0, changeQueue.length);
2977
+ if (server.currentOutput == null)
2978
+ return;
2979
+ const fileChanges = changeQueue.splice(0, changeQueue.length).map(([_, file]) => file);
2818
2980
  if (fileChanges.length === 0)
2819
2981
  return;
2820
- const changes = detectDevChanges(fileChanges, server.currentOutput);
2982
+ const changes = detectDevChanges(
2983
+ config,
2984
+ fileChanges,
2985
+ server.currentOutput
2986
+ );
2821
2987
  if (changes.type === "no-change")
2822
2988
  return;
2989
+ if (changes.type === "full-restart") {
2990
+ config.logger.info("Config changed, restarting server...");
2991
+ server.restart();
2992
+ return;
2993
+ }
2994
+ if (changes.type === "browser-restart") {
2995
+ config.logger.info("Runner config changed, restarting browser...");
2996
+ server.restartBrowser();
2997
+ return;
2998
+ }
2823
2999
  config.logger.info(
2824
- `Changed: ${Array.from(new Set(fileChanges.map((change) => change[1]))).map((file) => pc7.dim(relative9(config.root, file))).join(", ")}`
3000
+ `Changed: ${Array.from(new Set(fileChanges)).map((file) => pc7.dim(relative10(config.root, file))).join(", ")}`
2825
3001
  );
2826
3002
  const rebuiltNames = changes.rebuildGroups.flat().map((entry) => {
2827
3003
  return pc7.cyan(
2828
- relative9(config.outDir, getEntrypointOutputFile(entry, ""))
3004
+ relative10(config.outDir, getEntrypointOutputFile(entry, ""))
2829
3005
  );
2830
3006
  }).join(pc7.dim(", "));
2831
3007
  const allEntrypoints = await findEntrypoints(config);
@@ -2848,13 +3024,15 @@ function createFileReloader(options) {
2848
3024
  reloadContentScripts(changes.changedSteps, config, server);
2849
3025
  break;
2850
3026
  }
2851
- consola4.success(`Reloaded: ${rebuiltNames}`);
3027
+ consola5.success(`Reloaded: ${rebuiltNames}`);
2852
3028
  });
2853
3029
  };
2854
3030
  }
2855
3031
  function reloadContentScripts(steps, config, server) {
2856
3032
  if (config.manifestVersion === 3) {
2857
3033
  steps.forEach((step) => {
3034
+ if (server.currentOutput == null)
3035
+ return;
2858
3036
  const entry = step.entrypoints;
2859
3037
  if (Array.isArray(entry) || entry.type !== "content-script")
2860
3038
  return;
@@ -2891,13 +3069,13 @@ function reloadHtmlPages(groups, server, config) {
2891
3069
 
2892
3070
  // src/core/initialize.ts
2893
3071
  import prompts from "prompts";
2894
- import { consola as consola5 } from "consola";
3072
+ import { consola as consola6 } from "consola";
2895
3073
  import { downloadTemplate } from "giget";
2896
3074
  import fs14 from "fs-extra";
2897
3075
  import path6 from "node:path";
2898
3076
  import pc8 from "picocolors";
2899
3077
  async function initialize(options) {
2900
- consola5.info("Initalizing new project");
3078
+ consola6.info("Initalizing new project");
2901
3079
  const templates = await listTemplates();
2902
3080
  const defaultTemplate = templates.find(
2903
3081
  (template) => template.name === options.template?.toLowerCase().trim()
@@ -2944,15 +3122,15 @@ async function initialize(options) {
2944
3122
  await cloneProject(input);
2945
3123
  const cdPath = path6.relative(process.cwd(), path6.resolve(input.directory));
2946
3124
  console.log();
2947
- consola5.log(
3125
+ consola6.log(
2948
3126
  `\u2728 WXT project created with the ${TEMPLATE_COLORS[input.template.name]?.(input.template.name) ?? input.template.name} template.`
2949
3127
  );
2950
3128
  console.log();
2951
- consola5.log("Next steps:");
3129
+ consola6.log("Next steps:");
2952
3130
  let step = 0;
2953
3131
  if (cdPath !== "")
2954
- consola5.log(` ${++step}.`, pc8.cyan(`cd ${cdPath}`));
2955
- consola5.log(` ${++step}.`, pc8.cyan(`${input.packageManager} install`));
3132
+ consola6.log(` ${++step}.`, pc8.cyan(`cd ${cdPath}`));
3133
+ consola6.log(` ${++step}.`, pc8.cyan(`${input.packageManager} install`));
2956
3134
  console.log();
2957
3135
  }
2958
3136
  async function listTemplates() {
@@ -2997,7 +3175,7 @@ async function cloneProject({
2997
3175
  path6.join(directory, "_gitignore"),
2998
3176
  path6.join(directory, ".gitignore")
2999
3177
  ).catch(
3000
- (err) => consola5.warn("Failed to move _gitignore to .gitignore:", err)
3178
+ (err) => consola6.warn("Failed to move _gitignore to .gitignore:", err)
3001
3179
  );
3002
3180
  spinner.succeed();
3003
3181
  } catch (err) {
@@ -3028,7 +3206,7 @@ async function prepare(config) {
3028
3206
 
3029
3207
  // src/core/zip.ts
3030
3208
  import zipdir from "zip-dir";
3031
- import { dirname as dirname5, relative as relative10, resolve as resolve13 } from "node:path";
3209
+ import { dirname as dirname5, relative as relative11, resolve as resolve14 } from "node:path";
3032
3210
  import fs15 from "fs-extra";
3033
3211
  import { minimatch as minimatch2 } from "minimatch";
3034
3212
  async function zip(config) {
@@ -3046,7 +3224,7 @@ async function zip(config) {
3046
3224
  ).replaceAll("{{manifestVersion}}", `mv${internalConfig.manifestVersion}`);
3047
3225
  await fs15.ensureDir(internalConfig.outBaseDir);
3048
3226
  const outZipFilename = applyTemplate(internalConfig.zip.artifactTemplate);
3049
- const outZipPath = resolve13(internalConfig.outBaseDir, outZipFilename);
3227
+ const outZipPath = resolve14(internalConfig.outBaseDir, outZipFilename);
3050
3228
  await zipdir(internalConfig.outDir, {
3051
3229
  saveTo: outZipPath
3052
3230
  });
@@ -3055,14 +3233,14 @@ async function zip(config) {
3055
3233
  const sourcesZipFilename = applyTemplate(
3056
3234
  internalConfig.zip.sourcesTemplate
3057
3235
  );
3058
- const sourcesZipPath = resolve13(
3236
+ const sourcesZipPath = resolve14(
3059
3237
  internalConfig.outBaseDir,
3060
3238
  sourcesZipFilename
3061
3239
  );
3062
3240
  await zipdir(internalConfig.zip.sourcesRoot, {
3063
3241
  saveTo: sourcesZipPath,
3064
3242
  filter(path7) {
3065
- const relativePath = relative10(internalConfig.zip.sourcesRoot, path7);
3243
+ const relativePath = relative11(internalConfig.zip.sourcesRoot, path7);
3066
3244
  const matchedPattern = internalConfig.zip.ignoredSources.find(
3067
3245
  (pattern) => minimatch2(relativePath, pattern)
3068
3246
  );
@@ -3081,7 +3259,7 @@ async function zip(config) {
3081
3259
  }
3082
3260
 
3083
3261
  // src/cli.ts
3084
- import consola6, { LogLevels as LogLevels2 } from "consola";
3262
+ import consola7, { LogLevels as LogLevels2 } from "consola";
3085
3263
  process.env.VITE_CJS_IGNORE_WARNING = "true";
3086
3264
  var cli = cac("wxt");
3087
3265
  cli.help();
@@ -3171,21 +3349,24 @@ function wrapAction(cb, options) {
3171
3349
  return async (...args) => {
3172
3350
  const isDebug = !!args.find((arg) => arg?.debug);
3173
3351
  if (isDebug) {
3174
- consola6.level = LogLevels2.debug;
3352
+ consola7.level = LogLevels2.debug;
3175
3353
  }
3176
3354
  const startTime = Date.now();
3177
3355
  try {
3178
3356
  printHeader();
3179
3357
  const status = await cb(...args);
3180
3358
  if (!status?.isOngoing && !options?.disableFinishedLog)
3181
- consola6.success(
3359
+ consola7.success(
3182
3360
  `Finished in ${formatDuration(Date.now() - startTime)}`
3183
3361
  );
3184
3362
  } catch (err) {
3185
- consola6.fail(
3363
+ consola7.fail(
3186
3364
  `Command failed after ${formatDuration(Date.now() - startTime)}`
3187
3365
  );
3188
- consola6.error(err);
3366
+ if (err instanceof ValidationError) {
3367
+ } else {
3368
+ consola7.error(err);
3369
+ }
3189
3370
  process.exit(1);
3190
3371
  }
3191
3372
  };