wxt 0.2.4 → 0.3.0

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.d.ts CHANGED
@@ -15,14 +15,14 @@ interface InlineConfig {
15
15
  * directory.
16
16
  *
17
17
  * @default
18
- * "<root>"
18
+ * "<rootDir>"
19
19
  */
20
20
  srcDir?: string;
21
21
  /**
22
22
  * Directory containing files that will be copied to the output directory as-is.
23
23
  *
24
24
  * @default
25
- * "<srcDir>/publicDir"
25
+ * "<rootDir>/publicDir"
26
26
  */
27
27
  publicDir?: string;
28
28
  /**
@@ -404,7 +404,7 @@ interface ExtensionRunnerConfig {
404
404
 
405
405
  type EntrypointGroup = Entrypoint | Entrypoint[];
406
406
 
407
- var version = "0.2.4";
407
+ var version = "0.3.0";
408
408
 
409
409
  declare function defineConfig(config: UserConfig): UserConfig;
410
410
 
@@ -414,6 +414,10 @@ declare function defineRunnerConfig(config: ExtensionRunnerConfig): ExtensionRun
414
414
  * Bundles the extension for production. Returns a promise of the build result.
415
415
  */
416
416
  declare function build(config: InlineConfig): Promise<BuildOutput>;
417
+ /**
418
+ * Creates a dev server, pre-builds all the files that need to exist to load the extension, and open
419
+ * the browser with the extension installed.
420
+ */
417
421
  declare function createServer(config?: InlineConfig): Promise<WxtDevServer>;
418
422
 
419
423
  export { BackgroundEntrypoint, BackgroundScriptDefintition, BaseEntrypoint, BuildOutput, BuildStepOutput, ConfigEnv, ContentScriptDefinition, ContentScriptEntrypoint, Entrypoint, ExtensionRunnerConfig, GenericEntrypoint, InlineConfig, Logger, OnContentScriptStopped, OptionsEntrypoint, PopupEntrypoint, TargetBrowser, TargetManifestVersion, UserConfig, UserManifest, UserManifestFn, WxtDevServer, WxtInlineViteConfig, build, createServer, defineConfig, defineRunnerConfig, version };
package/dist/index.js CHANGED
@@ -1,20 +1,34 @@
1
1
  // src/core/utils/getInternalConfig.ts
2
2
  import path2, { resolve as resolve6 } from "node:path";
3
- import * as vite from "vite";
3
+ import * as vite2 from "vite";
4
4
  import { consola } from "consola";
5
5
 
6
6
  // src/core/utils/entrypoints.ts
7
7
  import path, { relative, resolve } from "node:path";
8
+
9
+ // src/core/utils/paths.ts
10
+ import nodePath from "node:path";
11
+ import * as vite from "vite";
12
+ function normalizePath2(path5) {
13
+ return vite.normalizePath(path5);
14
+ }
15
+ function unnormalizePath(path5) {
16
+ return nodePath.normalize(path5);
17
+ }
18
+
19
+ // src/core/utils/entrypoints.ts
8
20
  function getEntrypointName(entrypointsDir, inputPath) {
9
21
  const relativePath = path.relative(entrypointsDir, inputPath);
10
- const name = relativePath.split(/[\.\/]/, 2)[0];
22
+ const name = relativePath.split(/[\.\/\\]/, 2)[0];
11
23
  return name;
12
24
  }
13
25
  function getEntrypointOutputFile(entrypoint, ext) {
14
26
  return resolve(entrypoint.outputDir, `${entrypoint.name}${ext}`);
15
27
  }
16
28
  function getEntrypointBundlePath(entrypoint, outDir, ext) {
17
- return relative(outDir, getEntrypointOutputFile(entrypoint, ext));
29
+ return normalizePath2(
30
+ relative(outDir, getEntrypointOutputFile(entrypoint, ext))
31
+ );
18
32
  }
19
33
 
20
34
  // src/core/vite-plugins/devHtmlPrerender.ts
@@ -176,7 +190,7 @@ function multipageMove(entrypoints, config) {
176
190
  async writeBundle(_, bundle) {
177
191
  for (const oldBundlePath in bundle) {
178
192
  const entrypoint = entrypoints.find(
179
- (entry) => !!entry.inputPath.endsWith(oldBundlePath)
193
+ (entry) => !!normalizePath2(entry.inputPath).endsWith(oldBundlePath)
180
194
  );
181
195
  if (entrypoint == null) {
182
196
  config.logger.debug("No entrypoint found for", oldBundlePath);
@@ -217,13 +231,10 @@ import { mergeConfig } from "vite";
217
231
  function getUnimportOptions(config) {
218
232
  const defaultOptions = {
219
233
  debugLog: config.logger.debug,
220
- imports: [
221
- { name: "*", as: "browser", from: "webextension-polyfill" },
222
- { name: "defineConfig", from: "wxt" }
223
- ],
224
- presets: [{ package: "wxt/client" }],
234
+ imports: [{ name: "defineConfig", from: "wxt" }],
235
+ presets: [{ package: "wxt/client" }, { package: "wxt/browser" }],
225
236
  warn: config.logger.warn,
226
- dirs: ["components", "composables", "hooks", "utils"]
237
+ dirs: ["./components/*", "./composables/*", "./hooks/*", "./utils/*"]
227
238
  };
228
239
  return mergeConfig(
229
240
  defaultOptions,
@@ -269,7 +280,7 @@ function virtualEntrypoin(type, config) {
269
280
  const index = id.indexOf(virtualId);
270
281
  if (index === -1)
271
282
  return;
272
- const inputPath = id.substring(index + virtualId.length);
283
+ const inputPath = normalizePath2(id.substring(index + virtualId.length));
273
284
  return resolvedVirtualId + inputPath;
274
285
  },
275
286
  async load(id) {
@@ -297,6 +308,26 @@ function tsconfigPaths(config) {
297
308
  });
298
309
  }
299
310
 
311
+ // src/core/vite-plugins/noopBackground.ts
312
+ function noopBackground() {
313
+ const virtualModuleId = VIRTUAL_NOOP_BACKGROUND_MODULE_ID;
314
+ const resolvedVirtualModuleId = "\0" + virtualModuleId;
315
+ return {
316
+ name: "wxt:noop-background",
317
+ resolveId(id) {
318
+ if (id === virtualModuleId)
319
+ return resolvedVirtualModuleId;
320
+ },
321
+ load(id) {
322
+ if (id === resolvedVirtualModuleId) {
323
+ return `import { defineBackground } from 'wxt/client';
324
+ export default defineBackground(() => void 0)`;
325
+ }
326
+ }
327
+ };
328
+ }
329
+ var VIRTUAL_NOOP_BACKGROUND_MODULE_ID = "virtual:user-background";
330
+
300
331
  // src/core/utils/createFsCache.ts
301
332
  import fs3, { ensureDir as ensureDir2 } from "fs-extra";
302
333
  import { dirname as dirname3, resolve as resolve5 } from "path";
@@ -330,7 +361,7 @@ function getGlobals(config) {
330
361
  {
331
362
  name: "__BROWSER__",
332
363
  value: config.browser,
333
- type: `"chromium" | "firefox"`
364
+ type: `string`
334
365
  },
335
366
  {
336
367
  name: "__IS_CHROME__",
@@ -406,7 +437,7 @@ async function getInternalConfig(config, command) {
406
437
  });
407
438
  userConfig = loaded.config ?? {};
408
439
  }
409
- const merged = vite.mergeConfig(
440
+ const merged = vite2.mergeConfig(
410
441
  baseConfig,
411
442
  userConfig
412
443
  );
@@ -415,13 +446,13 @@ async function getInternalConfig(config, command) {
415
446
  srcDir,
416
447
  userConfig.entrypointsDir ?? "entrypoints"
417
448
  );
418
- const publicDir = resolve6(srcDir, userConfig.publicDir ?? "public");
449
+ const publicDir = resolve6(root, userConfig.publicDir ?? "public");
419
450
  const wxtDir = resolve6(srcDir, ".wxt");
420
451
  const typesDir = resolve6(wxtDir, "types");
421
452
  const env = { mode, browser, manifestVersion, command };
422
453
  const userManifest = await resolveManifestConfig(env, userConfig.manifest);
423
454
  const inlineManifest = await resolveManifestConfig(env, config.manifest);
424
- const manifest = vite.mergeConfig(userManifest, inlineManifest);
455
+ const manifest = vite2.mergeConfig(userManifest, inlineManifest);
425
456
  const finalConfig = {
426
457
  ...merged,
427
458
  srcDir,
@@ -470,6 +501,7 @@ async function getInternalConfig(config, command) {
470
501
  );
471
502
  finalConfig.vite.plugins.push(devServerGlobals(finalConfig));
472
503
  finalConfig.vite.plugins.push(tsconfigPaths(finalConfig));
504
+ finalConfig.vite.plugins.push(noopBackground());
473
505
  finalConfig.vite.define ??= {};
474
506
  getGlobals(finalConfig).forEach((global) => {
475
507
  finalConfig.vite.define[global.name] = JSON.stringify(global.value);
@@ -482,7 +514,7 @@ async function resolveManifestConfig(env, manifest) {
482
514
 
483
515
  // src/index.ts
484
516
  import pc3 from "picocolors";
485
- import * as vite5 from "vite";
517
+ import * as vite6 from "vite";
486
518
 
487
519
  // src/core/utils/arrays.ts
488
520
  function every(array, predicate) {
@@ -555,11 +587,12 @@ function detectDevChanges(changedFiles, currentOutput) {
555
587
  }
556
588
  function findEffectedSteps(changedFile, currentOutput) {
557
589
  const changes = [];
558
- const changedPath = changedFile[1];
590
+ const changedPath = normalizePath2(changedFile[1]);
559
591
  const isChunkEffected = (chunk) => (
560
592
  // If it's an HTML file with the same path, is is effected because HTML files need to be pre-rendered
561
- // TODO: use bundle path to support `<name>/index.html`?
593
+ // fileName is normalized, relative bundle path
562
594
  chunk.type === "asset" && changedPath.endsWith(chunk.fileName) || // If it's a chunk that depends on the changed file, it is effected
595
+ // moduleIds are absolute, normalized paths
563
596
  chunk.type === "chunk" && chunk.moduleIds.includes(changedPath)
564
597
  );
565
598
  for (const step of currentOutput.steps) {
@@ -581,7 +614,7 @@ import { consola as consola2 } from "consola";
581
614
  import { relative as relative5 } from "node:path";
582
615
 
583
616
  // src/core/build/buildEntrypoints.ts
584
- import * as vite2 from "vite";
617
+ import * as vite3 from "vite";
585
618
 
586
619
  // src/core/utils/removeEmptyDirs.ts
587
620
  import fs4 from "fs-extra";
@@ -602,9 +635,20 @@ async function removeEmptyDirs(dir) {
602
635
  }
603
636
 
604
637
  // src/core/build/buildEntrypoints.ts
605
- import glob from "fast-glob";
606
- import fs5 from "fs-extra";
638
+ import fs6 from "fs-extra";
607
639
  import { dirname as dirname4, resolve as resolve7 } from "path";
640
+
641
+ // src/core/utils/public.ts
642
+ import fs5 from "fs-extra";
643
+ import glob from "fast-glob";
644
+ async function getPublicFiles(config) {
645
+ if (!await fs5.exists(config.publicDir))
646
+ return [];
647
+ const files = await glob("**/*", { cwd: config.publicDir });
648
+ return files.map(unnormalizePath);
649
+ }
650
+
651
+ // src/core/build/buildEntrypoints.ts
608
652
  async function buildEntrypoints(groups, config) {
609
653
  const steps = [];
610
654
  for (const group of groups) {
@@ -643,11 +687,11 @@ async function buildSingleEntrypoint(entrypoint, config) {
643
687
  }
644
688
  }
645
689
  };
646
- const entryConfig = vite2.mergeConfig(
690
+ const entryConfig = vite3.mergeConfig(
647
691
  libMode,
648
692
  config.vite
649
693
  );
650
- const result = await vite2.build(entryConfig);
694
+ const result = await vite3.build(entryConfig);
651
695
  return {
652
696
  entrypoints: entrypoint,
653
697
  chunks: getBuildOutputChunks(result)
@@ -673,11 +717,11 @@ async function buildMultipleEntrypoints(entrypoints, config) {
673
717
  }
674
718
  }
675
719
  };
676
- const entryConfig = vite2.mergeConfig(
720
+ const entryConfig = vite3.mergeConfig(
677
721
  multiPage,
678
722
  config.vite
679
723
  );
680
- const result = await vite2.build(entryConfig);
724
+ const result = await vite3.build(entryConfig);
681
725
  return {
682
726
  entrypoints,
683
727
  chunks: getBuildOutputChunks(result)
@@ -691,21 +735,21 @@ function getBuildOutputChunks(result) {
691
735
  return result.output;
692
736
  }
693
737
  async function copyPublicDirectory(config) {
738
+ const files = await getPublicFiles(config);
739
+ if (files.length === 0)
740
+ return [];
694
741
  const publicAssets = [];
695
- if (!await fs5.exists(config.publicDir))
696
- return publicAssets;
697
- const files = await glob("**/*", { cwd: config.publicDir });
698
742
  for (const file of files) {
699
743
  const srcPath = resolve7(config.publicDir, file);
700
744
  const outPath = resolve7(config.outDir, file);
701
- await fs5.ensureDir(dirname4(outPath));
702
- await fs5.copyFile(srcPath, outPath);
745
+ await fs6.ensureDir(dirname4(outPath));
746
+ await fs6.copyFile(srcPath, outPath);
703
747
  publicAssets.push({
704
748
  type: "asset",
705
749
  fileName: file,
706
750
  name: file,
707
751
  needsCodeReference: false,
708
- source: await fs5.readFile(srcPath)
752
+ source: await fs6.readFile(srcPath)
709
753
  });
710
754
  }
711
755
  return publicAssets;
@@ -713,7 +757,7 @@ async function copyPublicDirectory(config) {
713
757
 
714
758
  // src/core/build/findEntrypoints.ts
715
759
  import { relative as relative3, resolve as resolve9 } from "path";
716
- import fs7 from "fs-extra";
760
+ import fs8 from "fs-extra";
717
761
  import picomatch from "picomatch";
718
762
  import { parseHTML as parseHTML2 } from "linkedom";
719
763
  import JSON5 from "json5";
@@ -721,20 +765,30 @@ import JSON5 from "json5";
721
765
  // src/core/utils/importTsFile.ts
722
766
  import createJITI from "jiti";
723
767
  import { createUnimport as createUnimport2 } from "unimport";
724
- import fs6 from "fs-extra";
768
+ import fs7 from "fs-extra";
725
769
  import { resolve as resolve8 } from "path";
726
770
  import transform from "jiti/dist/babel";
771
+
772
+ // src/core/utils/strings.ts
773
+ function removeImportStatements(text) {
774
+ return text.replace(
775
+ /(import\s?[{\w][\s\S]*?from\s?["'][\s\S]*?["'];?|import\s?["'][\s\S]*?["'];?)/gm,
776
+ ""
777
+ );
778
+ }
779
+
780
+ // src/core/utils/importTsFile.ts
727
781
  async function importTsFile(path5, config) {
728
782
  config.logger.debug("Loading file metadata:", path5);
783
+ const normalPath = normalizePath2(path5);
729
784
  const unimport2 = createUnimport2({
730
785
  ...getUnimportOptions(config),
731
786
  // Only allow specific imports, not all from the project
732
- imports: [{ name: "*", as: "browser", from: "webextension-polyfill" }],
733
787
  dirs: []
734
788
  });
735
789
  await unimport2.init();
736
- const text = await fs6.readFile(path5, "utf-8");
737
- const textNoImports = text.replace(/import.*[\n;]/gm, "");
790
+ const text = await fs7.readFile(path5, "utf-8");
791
+ const textNoImports = removeImportStatements(text);
738
792
  const { code } = await unimport2.injectImports(textNoImports);
739
793
  config.logger.debug(
740
794
  ["Text:", text, "No imports:", textNoImports, "Code:", code].join("\n")
@@ -750,7 +804,7 @@ async function importTsFile(path5, config) {
750
804
  )
751
805
  },
752
806
  transform(opts) {
753
- if (opts.filename === path5)
807
+ if (opts.filename === normalPath)
754
808
  return transform({ ...opts, source: code });
755
809
  else
756
810
  return transform(opts);
@@ -774,6 +828,7 @@ async function findEntrypoints(config) {
774
828
  const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
775
829
  const existingNames = {};
776
830
  const entrypoints = [];
831
+ let hasBackground = false;
777
832
  await Promise.all(
778
833
  relativePaths.map(async (relativePath) => {
779
834
  const path5 = resolve9(config.entrypointsDir, relativePath);
@@ -803,6 +858,7 @@ ${JSON.stringify(
803
858
  break;
804
859
  case "background":
805
860
  entrypoint = await getBackgroundEntrypoint(config, path5);
861
+ hasBackground = true;
806
862
  break;
807
863
  case "content-script":
808
864
  entrypoint = await getContentScriptEntrypoint(
@@ -832,11 +888,16 @@ ${JSON.stringify(
832
888
  existingNames[entrypoint.name] = entrypoint;
833
889
  })
834
890
  );
891
+ if (config.command === "serve" && !hasBackground) {
892
+ entrypoints.push(
893
+ await getBackgroundEntrypoint(config, VIRTUAL_NOOP_BACKGROUND_MODULE_ID)
894
+ );
895
+ }
835
896
  return entrypoints;
836
897
  }
837
898
  async function getPopupEntrypoint(config, path5) {
838
899
  const options = {};
839
- const content = await fs7.readFile(path5, "utf-8");
900
+ const content = await fs8.readFile(path5, "utf-8");
840
901
  const { document } = parseHTML2(content);
841
902
  const title = document.querySelector("title");
842
903
  if (title != null)
@@ -866,7 +927,7 @@ async function getPopupEntrypoint(config, path5) {
866
927
  }
867
928
  async function getOptionsEntrypoint(config, path5) {
868
929
  const options = {};
869
- const content = await fs7.readFile(path5, "utf-8");
930
+ const content = await fs8.readFile(path5, "utf-8");
870
931
  const { document } = parseHTML2(content);
871
932
  const openInTabContent = document.querySelector("meta[name='manifest.open_in_tab']")?.getAttribute("content");
872
933
  if (openInTabContent) {
@@ -889,9 +950,17 @@ async function getOptionsEntrypoint(config, path5) {
889
950
  };
890
951
  }
891
952
  async function getBackgroundEntrypoint(config, path5) {
892
- const { main: _, ...options } = await importTsFile(path5, config);
893
- if (options == null) {
894
- throw Error("Background script does not have a default export");
953
+ let options = {};
954
+ if (path5 !== VIRTUAL_NOOP_BACKGROUND_MODULE_ID) {
955
+ const defaultExport = await importTsFile(
956
+ path5,
957
+ config
958
+ );
959
+ if (defaultExport == null) {
960
+ throw Error("Background script does not have a default export");
961
+ }
962
+ const { main: _, ...moduleOptions } = defaultExport;
963
+ options = moduleOptions;
895
964
  }
896
965
  return {
897
966
  type: "background",
@@ -935,6 +1004,7 @@ var PATH_GLOB_TO_TYPE_MAP = {
935
1004
  "devtools.html": "devtools",
936
1005
  "devtools/index.html": "devtools",
937
1006
  "background.ts": "background",
1007
+ [VIRTUAL_NOOP_BACKGROUND_MODULE_ID]: "background",
938
1008
  "content.ts?(x)": "content-script",
939
1009
  "content/index.ts?(x)": "content-script",
940
1010
  "*.content.ts?(x)": "content-script",
@@ -952,10 +1022,10 @@ var PATH_GLOB_TO_TYPE_MAP = {
952
1022
 
953
1023
  // src/core/build/generateTypesDir.ts
954
1024
  import { createUnimport as createUnimport3 } from "unimport";
955
- import fs8 from "fs-extra";
1025
+ import fs9 from "fs-extra";
956
1026
  import { relative as relative4, resolve as resolve10 } from "path";
957
1027
  async function generateTypesDir(entrypoints, config) {
958
- await fs8.ensureDir(config.typesDir);
1028
+ await fs9.ensureDir(config.typesDir);
959
1029
  const references = [];
960
1030
  references.push(await writeImportsDeclarationFile(config));
961
1031
  references.push(await writePathsDeclarationFile(entrypoints, config));
@@ -967,7 +1037,7 @@ async function writeImportsDeclarationFile(config) {
967
1037
  const filePath = resolve10(config.typesDir, "imports.d.ts");
968
1038
  const unimport2 = createUnimport3(getUnimportOptions(config));
969
1039
  await unimport2.scanImportsFromDir(void 0, { cwd: config.srcDir });
970
- await fs8.writeFile(
1040
+ await fs9.writeFile(
971
1041
  filePath,
972
1042
  ["// Generated by wxt", await unimport2.generateTypeDeclarations()].join(
973
1043
  "\n"
@@ -977,28 +1047,34 @@ async function writeImportsDeclarationFile(config) {
977
1047
  }
978
1048
  async function writePathsDeclarationFile(entrypoints, config) {
979
1049
  const filePath = resolve10(config.typesDir, "paths.d.ts");
980
- const unions = entrypoints.map((entry) => {
981
- const path5 = getEntrypointBundlePath(
1050
+ const unions = entrypoints.map(
1051
+ (entry) => getEntrypointBundlePath(
982
1052
  entry,
983
1053
  config.outDir,
984
1054
  entry.inputPath.endsWith(".html") ? ".html" : ".js"
985
- );
986
- return ` | "/${path5}"`;
987
- }).sort();
988
- await fs8.writeFile(
1055
+ )
1056
+ ).concat(await getPublicFiles(config)).map(normalizePath2).map((path5) => ` | "/${path5}"`).sort().join("\n");
1057
+ const template = `// Generated by wxt
1058
+ import "wxt/browser";
1059
+
1060
+ declare module "wxt/browser" {
1061
+ type PublicPath =
1062
+ {{ union }}
1063
+ export interface ProjectRuntime extends Runtime.Static {
1064
+ getURL(path: PublicPath): string;
1065
+ }
1066
+ }
1067
+ `;
1068
+ await fs9.writeFile(
989
1069
  filePath,
990
- [
991
- "// Generated by wxt",
992
- "type EntrypointPath =",
993
- ...unions.length === 0 ? [" never"] : unions
994
- ].join("\n") + "\n"
1070
+ template.replace("{{ union }}", unions || " | never")
995
1071
  );
996
1072
  return filePath;
997
1073
  }
998
1074
  async function writeGlobalsDeclarationFile(config) {
999
1075
  const filePath = resolve10(config.typesDir, "globals.d.ts");
1000
1076
  const globals = getGlobals(config);
1001
- await fs8.writeFile(
1077
+ await fs9.writeFile(
1002
1078
  filePath,
1003
1079
  [
1004
1080
  "// Generated by wxt",
@@ -1014,13 +1090,13 @@ async function writeGlobalsDeclarationFile(config) {
1014
1090
  async function writeMainDeclarationFile(references, config) {
1015
1091
  const dir = config.wxtDir;
1016
1092
  const filePath = resolve10(dir, "wxt.d.ts");
1017
- await fs8.writeFile(
1093
+ await fs9.writeFile(
1018
1094
  filePath,
1019
1095
  [
1020
1096
  "// Generated by wxt",
1021
1097
  `/// <reference types="vite/client" />`,
1022
1098
  ...references.map(
1023
- (ref) => `/// <reference types="./${relative4(dir, ref)}" />`
1099
+ (ref) => `/// <reference types="./${normalizePath2(relative4(dir, ref))}" />`
1024
1100
  )
1025
1101
  ].join("\n") + "\n"
1026
1102
  );
@@ -1028,7 +1104,7 @@ async function writeMainDeclarationFile(references, config) {
1028
1104
  }
1029
1105
  async function writeTsConfigFile(mainReference, config) {
1030
1106
  const dir = config.wxtDir;
1031
- await fs8.writeFile(
1107
+ await fs9.writeFile(
1032
1108
  resolve10(dir, "tsconfig.json"),
1033
1109
  `{
1034
1110
  "compilerOptions": {
@@ -1039,37 +1115,32 @@ async function writeTsConfigFile(mainReference, config) {
1039
1115
  "esModuleInterop": true,
1040
1116
  "forceConsistentCasingInFileNames": true,
1041
1117
  "resolveJsonModule": true,
1042
-
1043
- /* Type Checking */
1044
1118
  "strict": true,
1045
-
1046
- /* Completeness */
1119
+ "lib": ["DOM", "WebWorker"],
1047
1120
  "skipLibCheck": true,
1048
-
1049
- /* Aliases */
1050
- "baseUrl": "${relative4(dir, config.root)}",
1121
+ "baseUrl": "${normalizePath2(relative4(dir, config.root))}",
1051
1122
  "paths": {
1052
1123
  "@@": ["."],
1053
1124
  "@@/*": ["./*"],
1054
1125
  "~~": ["."],
1055
1126
  "~~/*": ["./*"],
1056
- "@": ["${relative4(config.root, config.srcDir)}"],
1057
- "@/*": ["${relative4(config.root, config.srcDir)}/*"],
1058
- "~": ["${relative4(config.root, config.srcDir)}"],
1059
- "~/*": ["${relative4(config.root, config.srcDir)}/*"]
1127
+ "@": ["${normalizePath2(relative4(config.root, config.srcDir))}"],
1128
+ "@/*": ["${normalizePath2(relative4(config.root, config.srcDir))}/*"],
1129
+ "~": ["${normalizePath2(relative4(config.root, config.srcDir))}"],
1130
+ "~/*": ["${normalizePath2(relative4(config.root, config.srcDir))}/*"]
1060
1131
  }
1061
1132
  },
1062
1133
  "include": [
1063
- "${relative4(dir, config.root)}/**/*",
1064
- "./${relative4(dir, mainReference)}"
1134
+ "${normalizePath2(relative4(dir, config.root))}/**/*",
1135
+ "./${normalizePath2(relative4(dir, mainReference))}"
1065
1136
  ],
1066
- "exclude": ["${relative4(dir, config.outBaseDir)}"]
1137
+ "exclude": ["${normalizePath2(relative4(dir, config.outBaseDir))}"]
1067
1138
  }`
1068
1139
  );
1069
1140
  }
1070
1141
 
1071
1142
  // src/core/utils/manifest.ts
1072
- import fs10 from "fs-extra";
1143
+ import fs11 from "fs-extra";
1073
1144
  import { resolve as resolve12 } from "path";
1074
1145
 
1075
1146
  // src/core/utils/ContentSecurityPolicy.ts
@@ -1155,11 +1226,11 @@ function mapWxtOptionsToContentScript(options) {
1155
1226
 
1156
1227
  // src/core/utils/package.ts
1157
1228
  import { resolve as resolve11 } from "node:path";
1158
- import fs9 from "fs-extra";
1229
+ import fs10 from "fs-extra";
1159
1230
  async function getPackageJson(config) {
1160
1231
  const file = resolve11(config.root, "package.json");
1161
1232
  try {
1162
- return await fs9.readJson(file);
1233
+ return await fs10.readJson(file);
1163
1234
  } catch (err) {
1164
1235
  config.logger.debug(
1165
1236
  `Failed to read package.json at: ${file}. Returning undefined.`
@@ -1171,8 +1242,8 @@ async function getPackageJson(config) {
1171
1242
  // src/core/utils/manifest.ts
1172
1243
  async function writeManifest(manifest, output, config) {
1173
1244
  const str = config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
1174
- await fs10.ensureDir(config.outDir);
1175
- await fs10.writeFile(resolve12(config.outDir, "manifest.json"), str, "utf-8");
1245
+ await fs11.ensureDir(config.outDir);
1246
+ await fs11.writeFile(resolve12(config.outDir, "manifest.json"), str, "utf-8");
1176
1247
  output.publicAssets.unshift({
1177
1248
  type: "asset",
1178
1249
  fileName: "manifest.json",
@@ -1453,8 +1524,8 @@ function addHostPermission(manifest, hostPermission) {
1453
1524
 
1454
1525
  // src/core/build.ts
1455
1526
  import pc2 from "picocolors";
1456
- import * as vite3 from "vite";
1457
- import fs12 from "fs-extra";
1527
+ import * as vite4 from "vite";
1528
+ import fs13 from "fs-extra";
1458
1529
 
1459
1530
  // src/core/utils/groupEntrypoints.ts
1460
1531
  function groupEntrypoints(entrypoints) {
@@ -1507,7 +1578,7 @@ import { resolve as resolve13 } from "path";
1507
1578
  // src/core/log/printFileList.ts
1508
1579
  import path4 from "node:path";
1509
1580
  import pc from "picocolors";
1510
- import fs11 from "fs-extra";
1581
+ import fs12 from "fs-extra";
1511
1582
  import { filesize } from "filesize";
1512
1583
 
1513
1584
  // src/core/log/printTable.ts
@@ -1547,7 +1618,7 @@ async function printFileList(log, baseDir, files) {
1547
1618
  ];
1548
1619
  const prefix = i === files.length - 1 ? " \u2514\u2500" : " \u251C\u2500";
1549
1620
  const color = getChunkColor(file);
1550
- const stats = await fs11.lstat(file);
1621
+ const stats = await fs12.lstat(file);
1551
1622
  totalSize += stats.size;
1552
1623
  const size = String(filesize(stats.size));
1553
1624
  return [
@@ -1607,15 +1678,15 @@ async function buildInternal(config) {
1607
1678
  const target = `${config.browser}-mv${config.manifestVersion}`;
1608
1679
  config.logger.info(
1609
1680
  `${verb} ${pc2.cyan(target)} for ${pc2.cyan(config.mode)} with ${pc2.green(
1610
- `Vite ${vite3.version}`
1681
+ `Vite ${vite4.version}`
1611
1682
  )}`
1612
1683
  );
1613
1684
  const startTime = Date.now();
1614
- await fs12.rm(config.outDir, { recursive: true, force: true });
1615
- await fs12.ensureDir(config.outDir);
1685
+ await fs13.rm(config.outDir, { recursive: true, force: true });
1686
+ await fs13.ensureDir(config.outDir);
1616
1687
  const entrypoints = await findEntrypoints(config);
1617
1688
  const groups = groupEntrypoints(entrypoints);
1618
- const { output } = await rebuild(config, groups);
1689
+ const { output } = await rebuild(config, groups, void 0);
1619
1690
  config.logger.success(
1620
1691
  `Built extension in ${formatDuration(Date.now() - startTime)}`
1621
1692
  );
@@ -1627,7 +1698,11 @@ async function rebuild(config, entrypointGroups, existingOutput = {
1627
1698
  publicAssets: []
1628
1699
  }) {
1629
1700
  const allEntrypoints = await findEntrypoints(config);
1630
- await generateTypesDir(allEntrypoints, config);
1701
+ await generateTypesDir(allEntrypoints, config).catch((err) => {
1702
+ config.logger.warn("Failed to update .wxt directory:", err);
1703
+ if (config.command === "build")
1704
+ throw err;
1705
+ });
1631
1706
  const newOutput = await buildEntrypoints(entrypointGroups, config);
1632
1707
  const mergedOutput = {
1633
1708
  steps: [...existingOutput.steps, ...newOutput.steps],
@@ -1657,7 +1732,7 @@ async function rebuild(config, entrypointGroups, existingOutput = {
1657
1732
  }
1658
1733
 
1659
1734
  // src/core/server.ts
1660
- import * as vite4 from "vite";
1735
+ import * as vite5 from "vite";
1661
1736
 
1662
1737
  // src/core/runners/createWebExtRunner.ts
1663
1738
  function createWebExtRunner() {
@@ -1736,8 +1811,8 @@ async function getServerInfo() {
1736
1811
  }
1737
1812
  async function setupServer(serverInfo, config) {
1738
1813
  const runner = createWebExtRunner();
1739
- const viteServer = await vite4.createServer(
1740
- vite4.mergeConfig(serverInfo, config.vite)
1814
+ const viteServer = await vite5.createServer(
1815
+ vite5.mergeConfig(serverInfo, config.vite)
1741
1816
  );
1742
1817
  const start = async () => {
1743
1818
  await viteServer.listen(server.port);
@@ -1803,7 +1878,7 @@ function reloadHtmlPages(groups, server, config) {
1803
1878
  }
1804
1879
 
1805
1880
  // package.json
1806
- var version2 = "0.2.4";
1881
+ var version2 = "0.3.0";
1807
1882
 
1808
1883
  // src/core/utils/defineConfig.ts
1809
1884
  function defineConfig(config) {
@@ -1823,7 +1898,7 @@ async function build2(config) {
1823
1898
  async function createServer2(config) {
1824
1899
  const serverInfo = await getServerInfo();
1825
1900
  const getLatestInternalConfig = () => {
1826
- const viteConfig = vite5.mergeConfig(
1901
+ const viteConfig = vite6.mergeConfig(
1827
1902
  serverInfo.viteServerConfig,
1828
1903
  config?.vite ?? {}
1829
1904
  );
@@ -1843,6 +1918,8 @@ async function createServer2(config) {
1843
1918
  changeQueue.push([event, path5]);
1844
1919
  await fileChangedMutex.runExclusive(async () => {
1845
1920
  const fileChanges = changeQueue.splice(0, changeQueue.length);
1921
+ if (fileChanges.length === 0)
1922
+ return;
1846
1923
  const changes = detectDevChanges(fileChanges, server.currentOutput);
1847
1924
  if (changes.type === "no-change")
1848
1925
  return;