wxt 0.18.9 → 0.18.10

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.
@@ -3,6 +3,10 @@ import {
3
3
  some,
4
4
  toArray
5
5
  } from "./chunk-BERPNPEZ.js";
6
+ import {
7
+ addViteConfig,
8
+ defineWxtModule
9
+ } from "./chunk-6XSIWUWF.js";
6
10
  import {
7
11
  LogLevels,
8
12
  consola
@@ -12,7 +16,7 @@ import {
12
16
  } from "./chunk-QGM4M3NI.js";
13
17
 
14
18
  // package.json
15
- var version = "0.18.8";
19
+ var version = "0.18.9";
16
20
 
17
21
  // src/core/utils/paths.ts
18
22
  import systemPath from "node:path";
@@ -128,38 +132,6 @@ function download(config) {
128
132
  };
129
133
  }
130
134
 
131
- // src/core/builders/vite/plugins/unimport.ts
132
- import { createUnimport } from "unimport";
133
- import { extname } from "path";
134
- var ENABLED_EXTENSIONS = /* @__PURE__ */ new Set([
135
- ".js",
136
- ".jsx",
137
- ".ts",
138
- ".tsx",
139
- ".vue",
140
- ".svelte"
141
- ]);
142
- function unimport(config) {
143
- const options = config.imports;
144
- if (options === false) return [];
145
- const unimport2 = createUnimport(options);
146
- return {
147
- name: "wxt:unimport",
148
- async config() {
149
- await unimport2.scanImportsFromDir(void 0, { cwd: config.srcDir });
150
- },
151
- async transform(code, id) {
152
- if (id.includes("node_modules")) return;
153
- if (!ENABLED_EXTENSIONS.has(extname(id))) return;
154
- const injected = await unimport2.injectImports(code, id);
155
- return {
156
- code: injected.code,
157
- map: injected.s.generateMap({ hires: "boundary", source: id })
158
- };
159
- }
160
- };
161
- }
162
-
163
135
  // src/core/builders/vite/plugins/tsconfigPaths.ts
164
136
  function tsconfigPaths(config) {
165
137
  return {
@@ -428,7 +400,7 @@ function devServerGlobals(config, server) {
428
400
  }
429
401
 
430
402
  // src/core/builders/vite/plugins/multipageMove.ts
431
- import { dirname as dirname2, extname as extname2, resolve as resolve3, join } from "node:path";
403
+ import { dirname as dirname2, extname, resolve as resolve3, join } from "node:path";
432
404
  import fs, { ensureDir } from "fs-extra";
433
405
  function multipageMove(entrypoints, config) {
434
406
  return {
@@ -447,7 +419,7 @@ function multipageMove(entrypoints, config) {
447
419
  const newBundlePath = getEntrypointBundlePath(
448
420
  entrypoint,
449
421
  config.outDir,
450
- extname2(oldBundlePath)
422
+ extname(oldBundlePath)
451
423
  );
452
424
  if (newBundlePath === oldBundlePath) {
453
425
  config.logger.debug(
@@ -751,6 +723,86 @@ function removeProjectImportStatements(text) {
751
723
  ${noImports}`;
752
724
  }
753
725
 
726
+ // src/builtin-modules/unimport.ts
727
+ import { createUnimport } from "unimport";
728
+ import { extname as extname2 } from "node:path";
729
+ var unimport_default = defineWxtModule({
730
+ name: "wxt:built-in:unimport",
731
+ setup(wxt2) {
732
+ const options = wxt2.config.imports;
733
+ if (options === false) return;
734
+ let unimport;
735
+ wxt2.hooks.hook("ready", () => {
736
+ const addModuleImports = (module) => {
737
+ if (!module.imports) return;
738
+ options.imports ??= [];
739
+ options.imports.push(...module.imports);
740
+ };
741
+ wxt2.config.builtinModules.forEach(addModuleImports);
742
+ wxt2.config.userModules.forEach(addModuleImports);
743
+ });
744
+ wxt2.hooks.afterEach((event) => {
745
+ if (event.name === "ready") {
746
+ unimport = createUnimport(options);
747
+ }
748
+ });
749
+ wxt2.hooks.hook("prepare:types", async (_, entries) => {
750
+ await unimport.init();
751
+ entries.push(await getImportsDeclarationEntry(unimport));
752
+ if (!options.eslintrc.enabled) return;
753
+ entries.push(await getImportsEslintEntry(unimport, options));
754
+ });
755
+ addViteConfig(wxt2, () => ({
756
+ plugins: [vitePlugin(unimport)]
757
+ }));
758
+ }
759
+ });
760
+ function vitePlugin(unimport) {
761
+ const ENABLED_EXTENSIONS = /* @__PURE__ */ new Set([
762
+ ".js",
763
+ ".jsx",
764
+ ".ts",
765
+ ".tsx",
766
+ ".vue",
767
+ ".svelte"
768
+ ]);
769
+ return {
770
+ name: "wxt:unimport",
771
+ async transform(code, id) {
772
+ if (id.includes("node_modules")) return;
773
+ if (!ENABLED_EXTENSIONS.has(extname2(id))) return;
774
+ const injected = await unimport.injectImports(code, id);
775
+ return {
776
+ code: injected.code,
777
+ map: injected.s.generateMap({ hires: "boundary", source: id })
778
+ };
779
+ }
780
+ };
781
+ }
782
+ async function getImportsDeclarationEntry(unimport) {
783
+ await unimport.init();
784
+ return {
785
+ path: "types/imports.d.ts",
786
+ text: [
787
+ "// Generated by wxt",
788
+ await unimport.generateTypeDeclarations(),
789
+ ""
790
+ ].join("\n"),
791
+ tsReference: true
792
+ };
793
+ }
794
+ async function getImportsEslintEntry(unimport, options) {
795
+ const globals2 = {};
796
+ const eslintrc = { globals: globals2 };
797
+ (await unimport.getImports()).map((i) => i.as ?? i.name).filter(Boolean).sort().forEach((name) => {
798
+ eslintrc.globals[name] = options.eslintrc.globalsPropValue;
799
+ });
800
+ return {
801
+ path: options.eslintrc.filePath,
802
+ text: JSON.stringify(eslintrc, null, 2) + "\n"
803
+ };
804
+ }
805
+
754
806
  // src/core/utils/fs.ts
755
807
  import fs3 from "fs-extra";
756
808
  import glob from "fast-glob";
@@ -796,13 +848,17 @@ async function copyPublicDirectory() {
796
848
  await wxt.hooks.callHook("build:publicAssets", wxt, files);
797
849
  if (files.length === 0) return [];
798
850
  const publicAssets = [];
799
- for (const { absoluteSrc, relativeDest } of files) {
800
- const absoluteDest = resolve6(wxt.config.outDir, relativeDest);
851
+ for (const file of files) {
852
+ const absoluteDest = resolve6(wxt.config.outDir, file.relativeDest);
801
853
  await fs4.ensureDir(dirname3(absoluteDest));
802
- await fs4.copyFile(absoluteSrc, absoluteDest);
854
+ if ("absoluteSrc" in file) {
855
+ await fs4.copyFile(file.absoluteSrc, absoluteDest);
856
+ } else {
857
+ await fs4.writeFile(absoluteDest, file.contents, "utf8");
858
+ }
803
859
  publicAssets.push({
804
860
  type: "asset",
805
- fileName: relativeDest
861
+ fileName: file.relativeDest
806
862
  });
807
863
  }
808
864
  return publicAssets;
@@ -1281,9 +1337,8 @@ var PATH_GLOB_TO_TYPE_MAP = {
1281
1337
  var CONTENT_SCRIPT_OUT_DIR = "content-scripts";
1282
1338
 
1283
1339
  // src/core/utils/building/generate-wxt-dir.ts
1284
- import { createUnimport as createUnimport2 } from "unimport";
1285
1340
  import fs6 from "fs-extra";
1286
- import { relative as relative4, resolve as resolve8 } from "path";
1341
+ import { dirname as dirname4, relative as relative4, resolve as resolve8 } from "node:path";
1287
1342
  import path4 from "node:path";
1288
1343
 
1289
1344
  // src/core/utils/i18n.ts
@@ -1326,41 +1381,32 @@ function parseI18nMessages(messagesJson) {
1326
1381
  // src/core/utils/building/generate-wxt-dir.ts
1327
1382
  async function generateTypesDir(entrypoints) {
1328
1383
  await fs6.ensureDir(wxt.config.typesDir);
1329
- const references = [];
1330
- if (wxt.config.imports !== false) {
1331
- const unimport2 = createUnimport2(wxt.config.imports);
1332
- references.push(await writeImportsDeclarationFile(unimport2));
1333
- if (wxt.config.imports.eslintrc.enabled) {
1334
- await writeImportsEslintFile(unimport2, wxt.config.imports);
1335
- }
1336
- }
1337
- references.push(await writePathsDeclarationFile(entrypoints));
1338
- references.push(await writeI18nDeclarationFile());
1339
- references.push(await writeGlobalsDeclarationFile());
1340
- const mainReference = await writeMainDeclarationFile(references);
1341
- await writeTsConfigFile(mainReference);
1342
- }
1343
- async function writeImportsDeclarationFile(unimport2) {
1344
- const filePath = resolve8(wxt.config.typesDir, "imports.d.ts");
1345
- await unimport2.scanImportsFromDir(void 0, { cwd: wxt.config.srcDir });
1346
- await writeFileIfDifferent(
1347
- filePath,
1348
- ["// Generated by wxt", await unimport2.generateTypeDeclarations()].join(
1349
- "\n"
1350
- ) + "\n"
1351
- );
1352
- return filePath;
1353
- }
1354
- async function writeImportsEslintFile(unimport2, options) {
1355
- const globals2 = {};
1356
- const eslintrc = { globals: globals2 };
1357
- (await unimport2.getImports()).map((i) => i.as ?? i.name).filter(Boolean).sort().forEach((name) => {
1358
- eslintrc.globals[name] = options.eslintrc.globalsPropValue;
1384
+ const entries = [
1385
+ // Hard-coded entries
1386
+ { module: "wxt/vite-builder-env" }
1387
+ ];
1388
+ wxt.config.userModules.forEach((module) => {
1389
+ if (module.type === "node_module" && module.configKey != null)
1390
+ entries.push({ module: module.id });
1359
1391
  });
1360
- await fs6.writeJson(options.eslintrc.filePath, eslintrc, { spaces: 2 });
1392
+ entries.push(await getPathsDeclarationEntry(entrypoints));
1393
+ entries.push(await getI18nDeclarationEntry());
1394
+ entries.push(await getGlobalsDeclarationEntry());
1395
+ entries.push(await getTsConfigEntry());
1396
+ await wxt.hooks.callHook("prepare:types", wxt, entries);
1397
+ entries.push(getMainDeclarationEntry(entries));
1398
+ const absoluteFileEntries = entries.filter((entry) => "path" in entry).map((entry) => ({
1399
+ ...entry,
1400
+ path: resolve8(wxt.config.wxtDir, entry.path)
1401
+ }));
1402
+ await Promise.all(
1403
+ absoluteFileEntries.map(async (file) => {
1404
+ await fs6.ensureDir(dirname4(file.path));
1405
+ await writeFileIfDifferent(file.path, file.text);
1406
+ })
1407
+ );
1361
1408
  }
1362
- async function writePathsDeclarationFile(entrypoints) {
1363
- const filePath = resolve8(wxt.config.typesDir, "paths.d.ts");
1409
+ async function getPathsDeclarationEntry(entrypoints) {
1364
1410
  const unions = entrypoints.map(
1365
1411
  (entry) => getEntrypointBundlePath(
1366
1412
  entry,
@@ -1381,14 +1427,13 @@ declare module "wxt/browser" {
1381
1427
  }
1382
1428
  }
1383
1429
  `;
1384
- await writeFileIfDifferent(
1385
- filePath,
1386
- template.replace("{{ union }}", unions || " | never")
1387
- );
1388
- return filePath;
1430
+ return {
1431
+ path: "types/paths.d.ts",
1432
+ text: template.replace("{{ union }}", unions || " | never"),
1433
+ tsReference: true
1434
+ };
1389
1435
  }
1390
- async function writeI18nDeclarationFile() {
1391
- const filePath = resolve8(wxt.config.typesDir, "i18n.d.ts");
1436
+ async function getI18nDeclarationEntry() {
1392
1437
  const defaultLocale = wxt.config.manifest.default_locale;
1393
1438
  const template = `// Generated by wxt
1394
1439
  import "wxt/browser";
@@ -1434,18 +1479,17 @@ declare module "wxt/browser" {
1434
1479
  options?: GetMessageOptions,
1435
1480
  ): string;`;
1436
1481
  });
1437
- await writeFileIfDifferent(
1438
- filePath,
1439
- template.replace("{{ overrides }}", overrides.join("\n"))
1440
- );
1441
- return filePath;
1482
+ return {
1483
+ path: "types/i18n.d.ts",
1484
+ text: template.replace("{{ overrides }}", overrides.join("\n")),
1485
+ tsReference: true
1486
+ };
1442
1487
  }
1443
- async function writeGlobalsDeclarationFile() {
1444
- const filePath = resolve8(wxt.config.typesDir, "globals.d.ts");
1488
+ async function getGlobalsDeclarationEntry() {
1445
1489
  const globals2 = [...getGlobals(wxt.config), ...getEntrypointGlobals("")];
1446
- await writeFileIfDifferent(
1447
- filePath,
1448
- [
1490
+ return {
1491
+ path: "types/globals.d.ts",
1492
+ text: [
1449
1493
  "// Generated by wxt",
1450
1494
  "export {}",
1451
1495
  "interface ImportMetaEnv {",
@@ -1453,34 +1497,29 @@ async function writeGlobalsDeclarationFile() {
1453
1497
  "}",
1454
1498
  "interface ImportMeta {",
1455
1499
  " readonly env: ImportMetaEnv",
1456
- "}"
1457
- ].join("\n") + "\n"
1458
- );
1459
- return filePath;
1500
+ "}",
1501
+ ""
1502
+ ].join("\n"),
1503
+ tsReference: true
1504
+ };
1460
1505
  }
1461
- async function writeMainDeclarationFile(references) {
1462
- const dir = wxt.config.wxtDir;
1463
- const filePath = resolve8(dir, "wxt.d.ts");
1464
- await writeFileIfDifferent(
1465
- filePath,
1466
- [
1467
- "// Generated by wxt",
1468
- `/// <reference types="wxt/vite-builder-env" />`,
1469
- ...references.map(
1470
- (ref) => `/// <reference types="./${normalizePath(relative4(dir, ref))}" />`
1471
- ),
1472
- // Add references to modules installed from NPM to the TS project so
1473
- // their type augmentation can update InlineConfig correctly. Local
1474
- // modules defined in <root>/modules are already apart of the project, so
1475
- // we don't need to add them.
1476
- ...wxt.config.modules.filter(
1477
- (module) => module.type === "node_module" && module.configKey != null
1478
- ).map((module) => `/// <reference types="${module.id}" />`)
1479
- ].join("\n") + "\n"
1480
- );
1481
- return filePath;
1506
+ function getMainDeclarationEntry(references) {
1507
+ const lines = ["// Generated by wxt"];
1508
+ references.forEach((ref) => {
1509
+ if ("module" in ref) {
1510
+ return lines.push(`/// <reference types="${ref.module}" />`);
1511
+ } else if (ref.tsReference) {
1512
+ const absolutePath = resolve8(wxt.config.wxtDir, ref.path);
1513
+ const relativePath = relative4(wxt.config.wxtDir, absolutePath);
1514
+ lines.push(`/// <reference types="./${normalizePath(relativePath)}" />`);
1515
+ }
1516
+ });
1517
+ return {
1518
+ path: "wxt.d.ts",
1519
+ text: lines.join("\n") + "\n"
1520
+ };
1482
1521
  }
1483
- async function writeTsConfigFile(mainReference) {
1522
+ async function getTsConfigEntry() {
1484
1523
  const dir = wxt.config.wxtDir;
1485
1524
  const getTsconfigPath = (path8) => normalizePath(relative4(dir, path8));
1486
1525
  const paths = Object.entries(wxt.config.alias).flatMap(([alias, absolutePath]) => {
@@ -1490,9 +1529,7 @@ async function writeTsConfigFile(mainReference) {
1490
1529
  ` "${alias}/*": ["${aliasPath}/*"]`
1491
1530
  ];
1492
1531
  }).join(",\n");
1493
- await writeFileIfDifferent(
1494
- resolve8(dir, "tsconfig.json"),
1495
- `{
1532
+ const text = `{
1496
1533
  "compilerOptions": {
1497
1534
  "target": "ESNext",
1498
1535
  "module": "ESNext",
@@ -1509,11 +1546,14 @@ ${paths}
1509
1546
  },
1510
1547
  "include": [
1511
1548
  "${getTsconfigPath(wxt.config.root)}/**/*",
1512
- "./${getTsconfigPath(mainReference)}"
1549
+ "./wxt.d.ts"
1513
1550
  ],
1514
1551
  "exclude": ["${getTsconfigPath(wxt.config.outBaseDir)}"]
1515
- }`
1516
- );
1552
+ }`;
1553
+ return {
1554
+ path: "tsconfig.json",
1555
+ text
1556
+ };
1517
1557
  }
1518
1558
 
1519
1559
  // src/core/utils/building/resolve-config.ts
@@ -1522,13 +1562,13 @@ import path5 from "node:path";
1522
1562
 
1523
1563
  // src/core/utils/cache.ts
1524
1564
  import fs7, { ensureDir as ensureDir2 } from "fs-extra";
1525
- import { dirname as dirname4, resolve as resolve9 } from "path";
1565
+ import { dirname as dirname5, resolve as resolve9 } from "path";
1526
1566
  function createFsCache(wxtDir) {
1527
1567
  const getPath = (key) => resolve9(wxtDir, "cache", encodeURIComponent(key));
1528
1568
  return {
1529
1569
  async set(key, value) {
1530
1570
  const path8 = getPath(key);
1531
- await ensureDir2(dirname4(path8));
1571
+ await ensureDir2(dirname5(path8));
1532
1572
  await writeFileIfDifferent(path8, value);
1533
1573
  },
1534
1574
  async get(key) {
@@ -1569,6 +1609,11 @@ function isModuleInstalled(name) {
1569
1609
  // src/core/utils/building/resolve-config.ts
1570
1610
  import fs9 from "fs-extra";
1571
1611
  import glob3 from "fast-glob";
1612
+
1613
+ // src/builtin-modules/index.ts
1614
+ var builtinModules = [unimport_default];
1615
+
1616
+ // src/core/utils/building/resolve-config.ts
1572
1617
  async function resolveConfig(inlineConfig, command) {
1573
1618
  let userConfig = {};
1574
1619
  let userConfigMetadata;
@@ -1645,14 +1690,20 @@ async function resolveConfig(inlineConfig, command) {
1645
1690
  hostname: "localhost"
1646
1691
  };
1647
1692
  }
1648
- const modules = await resolveWxtModules(modulesDir, mergedConfig.modules);
1649
- const moduleOptions = modules.reduce((map, module) => {
1650
- if (module.configKey) {
1651
- map[module.configKey] = // @ts-expect-error
1652
- mergedConfig[module.configKey];
1653
- }
1654
- return map;
1655
- }, {});
1693
+ const userModules = await resolveWxtUserModules(
1694
+ modulesDir,
1695
+ mergedConfig.modules
1696
+ );
1697
+ const moduleOptions = userModules.reduce(
1698
+ (map, module) => {
1699
+ if (module.configKey) {
1700
+ map[module.configKey] = // @ts-expect-error
1701
+ mergedConfig[module.configKey];
1702
+ }
1703
+ return map;
1704
+ },
1705
+ {}
1706
+ );
1656
1707
  return {
1657
1708
  browser,
1658
1709
  command,
@@ -1662,7 +1713,7 @@ async function resolveConfig(inlineConfig, command) {
1662
1713
  filterEntrypoints,
1663
1714
  env,
1664
1715
  fsCache: createFsCache(wxtDir),
1665
- imports: await getUnimportOptions(wxtDir, logger, mergedConfig),
1716
+ imports: await getUnimportOptions(wxtDir, srcDir, logger, mergedConfig),
1666
1717
  logger,
1667
1718
  manifest: await resolveManifestConfig(env, mergedConfig.manifest),
1668
1719
  manifestVersion,
@@ -1691,7 +1742,8 @@ async function resolveConfig(inlineConfig, command) {
1691
1742
  },
1692
1743
  hooks: mergedConfig.hooks ?? {},
1693
1744
  vite: mergedConfig.vite ?? (() => ({})),
1694
- modules,
1745
+ builtinModules,
1746
+ userModules,
1695
1747
  plugins: [],
1696
1748
  ...moduleOptions
1697
1749
  };
@@ -1763,17 +1815,17 @@ function resolveAnalysisConfig(root, mergedConfig) {
1763
1815
  keepArtifacts: mergedConfig.analysis?.keepArtifacts ?? false
1764
1816
  };
1765
1817
  }
1766
- async function getUnimportOptions(wxtDir, logger, config) {
1818
+ async function getUnimportOptions(wxtDir, srcDir, logger, config) {
1767
1819
  if (config.imports === false) return false;
1768
- const enabledConfig = config.imports?.eslintrc?.enabled;
1769
- let enabled;
1770
- switch (enabledConfig) {
1820
+ const rawEslintEnabled = config.imports?.eslintrc?.enabled;
1821
+ let eslintEnabled;
1822
+ switch (rawEslintEnabled) {
1771
1823
  case void 0:
1772
1824
  case "auto":
1773
- enabled = await isModuleInstalled("eslint");
1825
+ eslintEnabled = await isModuleInstalled("eslint");
1774
1826
  break;
1775
1827
  default:
1776
- enabled = enabledConfig;
1828
+ eslintEnabled = rawEslintEnabled;
1777
1829
  }
1778
1830
  const defaultOptions = {
1779
1831
  debugLog: logger.debug,
@@ -1789,8 +1841,11 @@ async function getUnimportOptions(wxtDir, logger, config) {
1789
1841
  ],
1790
1842
  warn: logger.warn,
1791
1843
  dirs: ["components", "composables", "hooks", "utils"],
1844
+ dirsScanOptions: {
1845
+ cwd: srcDir
1846
+ },
1792
1847
  eslintrc: {
1793
- enabled,
1848
+ enabled: eslintEnabled,
1794
1849
  filePath: path5.resolve(wxtDir, "eslintrc-auto-import.json"),
1795
1850
  globalsPropValue: true
1796
1851
  }
@@ -1831,7 +1886,7 @@ async function mergeBuilderConfig(inlineConfig, userConfig) {
1831
1886
  }
1832
1887
  throw Error("Builder not found. Make sure vite is installed.");
1833
1888
  }
1834
- async function resolveWxtModules(modulesDir, modules = []) {
1889
+ async function resolveWxtUserModules(modulesDir, modules = []) {
1835
1890
  const npmModules = await Promise.all(
1836
1891
  modules.map(async (moduleId) => {
1837
1892
  const mod = await import(
@@ -1919,7 +1974,7 @@ var ENTRY_TYPE_TO_GROUP_MAP = {
1919
1974
 
1920
1975
  // src/core/utils/building/import-entrypoint.ts
1921
1976
  import createJITI from "jiti";
1922
- import { createUnimport as createUnimport3 } from "unimport";
1977
+ import { createUnimport as createUnimport2 } from "unimport";
1923
1978
  import fs10 from "fs-extra";
1924
1979
  import { relative as relative5, resolve as resolve11 } from "node:path";
1925
1980
  import { transformSync } from "esbuild";
@@ -1927,15 +1982,15 @@ import { fileURLToPath } from "node:url";
1927
1982
  async function importEntrypointFile(path8) {
1928
1983
  wxt.logger.debug("Loading file metadata:", path8);
1929
1984
  const normalPath = normalizePath(path8);
1930
- const unimport2 = createUnimport3({
1985
+ const unimport = createUnimport2({
1931
1986
  ...wxt.config.imports,
1932
1987
  // Only allow specific imports, not all from the project
1933
1988
  dirs: []
1934
1989
  });
1935
- await unimport2.init();
1990
+ await unimport.init();
1936
1991
  const text = await fs10.readFile(path8, "utf-8");
1937
1992
  const textNoImports = removeProjectImportStatements(text);
1938
- const { code } = await unimport2.injectImports(textNoImports);
1993
+ const { code } = await unimport.injectImports(textNoImports);
1939
1994
  wxt.logger.debug(
1940
1995
  ["Text:", text, "No imports:", textNoImports, "Code:", code].join("\n")
1941
1996
  );
@@ -3152,7 +3207,6 @@ async function createViteBuilder(wxtConfig, hooks, server) {
3152
3207
  config.plugins.push(
3153
3208
  download(wxtConfig),
3154
3209
  devHtmlPrerender(wxtConfig, server),
3155
- unimport(wxtConfig),
3156
3210
  resolveVirtualModules(wxtConfig),
3157
3211
  devServerGlobals(wxtConfig, server),
3158
3212
  tsconfigPaths(wxtConfig),
@@ -3434,18 +3488,16 @@ async function registerWxt(command, inlineConfig = {}, getServer) {
3434
3488
  builder,
3435
3489
  server
3436
3490
  };
3437
- for (const module of config.modules) {
3491
+ const initModule = async (module) => {
3438
3492
  if (module.hooks) wxt.hooks.addHooks(module.hooks);
3439
- if (wxt.config.imports !== false && module.imports) {
3440
- wxt.config.imports.imports ??= [];
3441
- wxt.config.imports.imports.push(...module.imports);
3442
- }
3443
3493
  await module.setup?.(
3444
3494
  wxt,
3445
3495
  // @ts-expect-error: Untyped configKey field
3446
3496
  module.configKey ? config[module.configKey] : void 0
3447
3497
  );
3448
- }
3498
+ };
3499
+ for (const builtinModule of builtinModules) await initModule(builtinModule);
3500
+ for (const userModule of config.userModules) await initModule(userModule);
3449
3501
  wxt.hooks.addHooks(config.hooks);
3450
3502
  await wxt.hooks.callHook("ready", wxt);
3451
3503
  }
@@ -3457,11 +3509,11 @@ export {
3457
3509
  isHtmlEntrypoint,
3458
3510
  formatDuration,
3459
3511
  download,
3460
- unimport,
3461
3512
  tsconfigPaths,
3462
3513
  globals,
3463
3514
  webextensionPolyfillMock,
3464
3515
  kebabCaseAlphanumeric,
3516
+ vitePlugin,
3465
3517
  wxt,
3466
3518
  registerWxt,
3467
3519
  detectDevChanges,
@@ -0,0 +1,57 @@
1
+ // src/modules.ts
2
+ import * as vite from "vite";
3
+ import glob from "fast-glob";
4
+ import { resolve } from "node:path";
5
+ function defineWxtModule(module) {
6
+ if (typeof module === "function") return { setup: module };
7
+ return module;
8
+ }
9
+ function addEntrypoint(wxt, entrypoint) {
10
+ wxt.hooks.hook("entrypoints:resolved", (wxt2, entrypoints) => {
11
+ entrypoints.push(entrypoint);
12
+ });
13
+ }
14
+ function addPublicAssets(wxt, dir) {
15
+ wxt.hooks.hook("build:publicAssets", async (wxt2, files) => {
16
+ const moreFiles = await glob("**/*", { cwd: dir });
17
+ if (moreFiles.length === 0) {
18
+ wxt2.logger.warn("No files to copy in", dir);
19
+ return;
20
+ }
21
+ moreFiles.forEach((file) => {
22
+ files.unshift({ absoluteSrc: resolve(dir, file), relativeDest: file });
23
+ });
24
+ });
25
+ }
26
+ function addViteConfig(wxt, viteConfig) {
27
+ wxt.hooks.hook("ready", (wxt2) => {
28
+ const userVite = wxt2.config.vite;
29
+ wxt2.config.vite = async (env) => {
30
+ const fromUser = await userVite(env);
31
+ const fromModule = viteConfig(env) ?? {};
32
+ return vite.mergeConfig(fromModule, fromUser);
33
+ };
34
+ });
35
+ }
36
+ function addWxtPlugin(wxt, plugin) {
37
+ wxt.hooks.hook("ready", (wxt2) => {
38
+ wxt2.config.plugins.push(plugin);
39
+ });
40
+ }
41
+ function addImportPreset(wxt, preset) {
42
+ wxt.hooks.hook("ready", (wxt2) => {
43
+ if (!wxt2.config.imports) return;
44
+ wxt2.config.imports.presets ??= [];
45
+ if (wxt2.config.imports.presets.includes(preset)) return;
46
+ wxt2.config.imports.presets.push(preset);
47
+ });
48
+ }
49
+
50
+ export {
51
+ defineWxtModule,
52
+ addEntrypoint,
53
+ addPublicAssets,
54
+ addViteConfig,
55
+ addWxtPlugin,
56
+ addImportPreset
57
+ };