wxt 0.18.11 → 0.18.12

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/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <h1 align="center">
2
- <img style="vertical-align:middle" width="44" src="./docs/public/hero-logo.svg" alt="WXT Logo">
2
+ <img style="vertical-align:middle" width="44" src="https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/public/hero-logo.svg" alt="WXT Logo">
3
3
  <span>WXT</span>
4
4
  </h1>
5
5
 
@@ -22,22 +22,22 @@
22
22
  </p>
23
23
 
24
24
  <p align="center">
25
- <a href="https://wxt.dev" target="_blank">Get Started</a>
26
- &bull;
27
- <a href="https://wxt.dev/guide/installation.html" target="_blank">Installation</a>
25
+ <a href="https://wxt.dev/guide/installation.html" target="_blank">Get Started</a>
28
26
  &bull;
29
27
  <a href="https://wxt.dev/api/config.html" target="_blank">Configuration</a>
30
28
  &bull;
31
29
  <a href="https://wxt.dev/examples.html" target="_blank">Examples</a>
32
30
  &bull;
31
+ <a href="https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md" target="_blank">Changelog</a>
32
+ &bull;
33
33
  <a href="https://discord.gg/ZFsZqGery9" target="_blank">Discord</a>
34
34
  </p>
35
35
 
36
- ![Example CLI Output](./docs/assets/cli-output.png)
36
+ ![Example CLI Output](https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/assets/cli-output.png)
37
37
 
38
38
  ## Demo
39
39
 
40
- https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94
40
+ <video src="https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94"></video>
41
41
 
42
42
  ## Quick Start
43
43
 
@@ -16,7 +16,7 @@ import {
16
16
  } from "./chunk-QGM4M3NI.js";
17
17
 
18
18
  // package.json
19
- var version = "0.18.10";
19
+ var version = "0.18.11";
20
20
 
21
21
  // src/core/utils/paths.ts
22
22
  import systemPath from "node:path";
@@ -242,14 +242,33 @@ function webextensionPolyfillMock(config) {
242
242
  };
243
243
  }
244
244
 
245
+ // src/core/builders/vite/plugins/resolveAppConfig.ts
246
+ import { exists } from "fs-extra";
247
+ import { resolve as resolve2 } from "node:path";
248
+ function resolveAppConfig(config) {
249
+ const virtualModuleId = "virtual:app-config";
250
+ const resolvedVirtualModuleId = "\0" + virtualModuleId;
251
+ const appConfigFile = resolve2(config.srcDir, "app.config.ts");
252
+ return {
253
+ name: "wxt:resolve-app-config",
254
+ async resolveId(id) {
255
+ if (id !== virtualModuleId) return;
256
+ return await exists(appConfigFile) ? appConfigFile : resolvedVirtualModuleId;
257
+ },
258
+ load(id) {
259
+ if (id === resolvedVirtualModuleId) return `export default {}`;
260
+ }
261
+ };
262
+ }
263
+
245
264
  // src/core/builders/vite/plugins/devHtmlPrerender.ts
246
265
  import { parseHTML } from "linkedom";
247
- import { dirname, relative as relative2, resolve as resolve2 } from "node:path";
266
+ import { dirname, relative as relative2, resolve as resolve3 } from "node:path";
248
267
  import { murmurHash } from "ohash";
249
268
  var inlineScriptContents = {};
250
269
  function devHtmlPrerender(config, server) {
251
270
  const htmlReloadId = "@wxt/reload-html";
252
- const resolvedHtmlReloadId = resolve2(
271
+ const resolvedHtmlReloadId = resolve3(
253
272
  config.wxtModuleDir,
254
273
  "dist/virtual/reload-html.js"
255
274
  );
@@ -351,12 +370,12 @@ function pointToDevServer(config, server, id, document, querySelector, attr) {
351
370
  );
352
371
  if (matchingAlias) {
353
372
  const [alias, replacement] = matchingAlias;
354
- resolvedAbsolutePath = resolve2(
373
+ resolvedAbsolutePath = resolve3(
355
374
  config.root,
356
375
  src.replace(alias, replacement)
357
376
  );
358
377
  } else {
359
- resolvedAbsolutePath = resolve2(dirname(id), src);
378
+ resolvedAbsolutePath = resolve3(dirname(id), src);
360
379
  }
361
380
  if (resolvedAbsolutePath) {
362
381
  const relativePath = normalizePath(
@@ -400,7 +419,7 @@ function devServerGlobals(config, server) {
400
419
  }
401
420
 
402
421
  // src/core/builders/vite/plugins/multipageMove.ts
403
- import { dirname as dirname2, extname, resolve as resolve3, join } from "node:path";
422
+ import { dirname as dirname2, extname, resolve as resolve4, join } from "node:path";
404
423
  import fs, { ensureDir } from "fs-extra";
405
424
  function multipageMove(entrypoints, config) {
406
425
  return {
@@ -428,8 +447,8 @@ function multipageMove(entrypoints, config) {
428
447
  );
429
448
  continue;
430
449
  }
431
- const oldAbsPath = resolve3(config.outDir, oldBundlePath);
432
- const newAbsPath = resolve3(config.outDir, newBundlePath);
450
+ const oldAbsPath = resolve4(config.outDir, oldBundlePath);
451
+ const newAbsPath = resolve4(config.outDir, newBundlePath);
433
452
  await ensureDir(dirname2(newAbsPath));
434
453
  await fs.move(oldAbsPath, newAbsPath, { overwrite: true });
435
454
  const renamedChunk = {
@@ -476,7 +495,7 @@ var virtualModuleNames = [
476
495
 
477
496
  // src/core/builders/vite/plugins/resolveVirtualModules.ts
478
497
  import fs2 from "fs-extra";
479
- import { resolve as resolve4 } from "path";
498
+ import { resolve as resolve5 } from "path";
480
499
  function resolveVirtualModules(config) {
481
500
  return virtualModuleNames.map((name) => {
482
501
  const virtualId = `virtual:wxt-${name}?`;
@@ -493,7 +512,7 @@ function resolveVirtualModules(config) {
493
512
  if (!id.startsWith(resolvedVirtualId)) return;
494
513
  const inputPath = id.replace(resolvedVirtualId, "");
495
514
  const template = await fs2.readFile(
496
- resolve4(config.wxtModuleDir, `dist/virtual/${name}.js`),
515
+ resolve5(config.wxtModuleDir, `dist/virtual/${name}.js`),
497
516
  "utf-8"
498
517
  );
499
518
  return template.replace(`virtual:user-${name}`, inputPath);
@@ -635,9 +654,9 @@ function emptyMainFunction(mod) {
635
654
  }
636
655
 
637
656
  // src/core/builders/vite/plugins/removeEntrypointMainFunction.ts
638
- import { resolve as resolve5 } from "node:path";
657
+ import { resolve as resolve6 } from "node:path";
639
658
  function removeEntrypointMainFunction(config, path8) {
640
- const absPath = normalizePath(resolve5(config.root, path8));
659
+ const absPath = normalizePath(resolve6(config.root, path8));
641
660
  return {
642
661
  name: "wxt:remove-entrypoint-main-function",
643
662
  transform(code, id) {
@@ -813,6 +832,7 @@ function getEslint9ConfigEntry(options, globals2) {
813
832
  text: `const globals = ${JSON.stringify(globals2, null, 2)}
814
833
 
815
834
  export default {
835
+ name: "wxt/auto-imports",
816
836
  languageOptions: {
817
837
  globals,
818
838
  sourceType: "module",
@@ -839,7 +859,7 @@ async function getPublicFiles() {
839
859
 
840
860
  // src/core/utils/building/build-entrypoints.ts
841
861
  import fs4 from "fs-extra";
842
- import { dirname as dirname3, resolve as resolve6 } from "path";
862
+ import { dirname as dirname3, resolve as resolve7 } from "path";
843
863
  import pc from "picocolors";
844
864
  async function buildEntrypoints(groups, spinner) {
845
865
  const steps = [];
@@ -861,14 +881,14 @@ async function buildEntrypoints(groups, spinner) {
861
881
  }
862
882
  async function copyPublicDirectory() {
863
883
  const files = (await getPublicFiles()).map((file) => ({
864
- absoluteSrc: resolve6(wxt.config.publicDir, file),
884
+ absoluteSrc: resolve7(wxt.config.publicDir, file),
865
885
  relativeDest: file
866
886
  }));
867
887
  await wxt.hooks.callHook("build:publicAssets", wxt, files);
868
888
  if (files.length === 0) return [];
869
889
  const publicAssets = [];
870
890
  for (const file of files) {
871
- const absoluteDest = resolve6(wxt.config.outDir, file.relativeDest);
891
+ const absoluteDest = resolve7(wxt.config.outDir, file.relativeDest);
872
892
  await fs4.ensureDir(dirname3(absoluteDest));
873
893
  if ("absoluteSrc" in file) {
874
894
  await fs4.copyFile(file.absoluteSrc, absoluteDest);
@@ -976,7 +996,7 @@ function findEffectedSteps(changedFile, currentOutput) {
976
996
  }
977
997
 
978
998
  // src/core/utils/building/find-entrypoints.ts
979
- import { relative as relative3, resolve as resolve7 } from "path";
999
+ import { relative as relative3, resolve as resolve8 } from "path";
980
1000
  import fs5 from "fs-extra";
981
1001
  import { minimatch } from "minimatch";
982
1002
  import { parseHTML as parseHTML3 } from "linkedom";
@@ -985,14 +1005,14 @@ import glob2 from "fast-glob";
985
1005
  import pc2 from "picocolors";
986
1006
  async function findEntrypoints() {
987
1007
  await fs5.mkdir(wxt.config.wxtDir, { recursive: true });
988
- await fs5.writeJson(resolve7(wxt.config.wxtDir, "tsconfig.json"), {});
1008
+ await fs5.writeJson(resolve8(wxt.config.wxtDir, "tsconfig.json"), {});
989
1009
  const relativePaths = await glob2(Object.keys(PATH_GLOB_TO_TYPE_MAP), {
990
1010
  cwd: wxt.config.entrypointsDir
991
1011
  });
992
1012
  relativePaths.sort();
993
1013
  const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
994
1014
  const entrypointInfos = relativePaths.reduce((results, relativePath) => {
995
- const inputPath = resolve7(wxt.config.entrypointsDir, relativePath);
1015
+ const inputPath = resolve8(wxt.config.entrypointsDir, relativePath);
996
1016
  const name = getEntrypointName(wxt.config.entrypointsDir, inputPath);
997
1017
  const matchingGlob = pathGlobs.find(
998
1018
  (glob5) => minimatch(relativePath, glob5)
@@ -1034,7 +1054,7 @@ async function findEntrypoints() {
1034
1054
  return {
1035
1055
  ...info,
1036
1056
  type,
1037
- outputDir: resolve7(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1057
+ outputDir: resolve8(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1038
1058
  options: {
1039
1059
  include: void 0,
1040
1060
  exclude: void 0
@@ -1261,7 +1281,7 @@ async function getContentScriptEntrypoint({
1261
1281
  type: "content-script",
1262
1282
  name,
1263
1283
  inputPath,
1264
- outputDir: resolve7(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1284
+ outputDir: resolve8(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1265
1285
  options: resolvePerBrowserOptions(options, wxt.config.browser),
1266
1286
  skipped
1267
1287
  };
@@ -1357,7 +1377,7 @@ var CONTENT_SCRIPT_OUT_DIR = "content-scripts";
1357
1377
 
1358
1378
  // src/core/utils/building/generate-wxt-dir.ts
1359
1379
  import fs6 from "fs-extra";
1360
- import { dirname as dirname4, relative as relative4, resolve as resolve8 } from "node:path";
1380
+ import { dirname as dirname4, relative as relative4, resolve as resolve9 } from "node:path";
1361
1381
  import path4 from "node:path";
1362
1382
 
1363
1383
  // src/core/utils/i18n.ts
@@ -1416,7 +1436,7 @@ async function generateTypesDir(entrypoints) {
1416
1436
  entries.push(getMainDeclarationEntry(entries));
1417
1437
  const absoluteFileEntries = entries.filter((entry) => "path" in entry).map((entry) => ({
1418
1438
  ...entry,
1419
- path: resolve8(wxt.config.wxtDir, entry.path)
1439
+ path: resolve9(wxt.config.wxtDir, entry.path)
1420
1440
  }));
1421
1441
  await Promise.all(
1422
1442
  absoluteFileEntries.map(async (file) => {
@@ -1528,7 +1548,7 @@ function getMainDeclarationEntry(references) {
1528
1548
  if ("module" in ref) {
1529
1549
  return lines.push(`/// <reference types="${ref.module}" />`);
1530
1550
  } else if (ref.tsReference) {
1531
- const absolutePath = resolve8(wxt.config.wxtDir, ref.path);
1551
+ const absolutePath = resolve9(wxt.config.wxtDir, ref.path);
1532
1552
  const relativePath = relative4(wxt.config.wxtDir, absolutePath);
1533
1553
  lines.push(`/// <reference types="./${normalizePath(relativePath)}" />`);
1534
1554
  }
@@ -1581,9 +1601,9 @@ import path5 from "node:path";
1581
1601
 
1582
1602
  // src/core/utils/cache.ts
1583
1603
  import fs7, { ensureDir as ensureDir2 } from "fs-extra";
1584
- import { dirname as dirname5, resolve as resolve9 } from "path";
1604
+ import { dirname as dirname5, resolve as resolve10 } from "path";
1585
1605
  function createFsCache(wxtDir) {
1586
- const getPath = (key) => resolve9(wxtDir, "cache", encodeURIComponent(key));
1606
+ const getPath = (key) => resolve10(wxtDir, "cache", encodeURIComponent(key));
1587
1607
  return {
1588
1608
  async set(key, value) {
1589
1609
  const path8 = getPath(key);
@@ -1999,7 +2019,7 @@ var ENTRY_TYPE_TO_GROUP_MAP = {
1999
2019
  import createJITI from "jiti";
2000
2020
  import { createUnimport as createUnimport2 } from "unimport";
2001
2021
  import fs9 from "fs-extra";
2002
- import { relative as relative5, resolve as resolve10 } from "node:path";
2022
+ import { relative as relative5, resolve as resolve11 } from "node:path";
2003
2023
  import { transformSync } from "esbuild";
2004
2024
  import { fileURLToPath } from "node:url";
2005
2025
  async function importEntrypointFile(path8) {
@@ -2024,7 +2044,14 @@ async function importEntrypointFile(path8) {
2024
2044
  debug: wxt.config.debug,
2025
2045
  esmResolve: true,
2026
2046
  alias: {
2027
- "webextension-polyfill": resolve10(
2047
+ "webextension-polyfill": resolve11(
2048
+ wxt.config.wxtModuleDir,
2049
+ "dist/virtual/mock-browser.js"
2050
+ ),
2051
+ // TODO: Resolve this virtual module to some file with
2052
+ // `export default {}` instead of this hack of using another file with
2053
+ // a default export.
2054
+ "virtual:app-config": resolve11(
2028
2055
  wxt.config.wxtModuleDir,
2029
2056
  "dist/virtual/mock-browser.js"
2030
2057
  )
@@ -2089,7 +2116,7 @@ import pc5 from "picocolors";
2089
2116
  import fs13 from "fs-extra";
2090
2117
 
2091
2118
  // src/core/utils/log/printBuildSummary.ts
2092
- import { resolve as resolve11 } from "path";
2119
+ import { resolve as resolve12 } from "path";
2093
2120
 
2094
2121
  // src/core/utils/log/printFileList.ts
2095
2122
  import path6 from "node:path";
@@ -2173,7 +2200,7 @@ async function printBuildSummary(log, header, output) {
2173
2200
  return l.fileName.localeCompare(r.fileName);
2174
2201
  });
2175
2202
  const files = chunks.map(
2176
- (chunk) => resolve11(wxt.config.outDir, chunk.fileName)
2203
+ (chunk) => resolve12(wxt.config.outDir, chunk.fileName)
2177
2204
  );
2178
2205
  await printFileList(log, header, wxt.config.outDir, files);
2179
2206
  }
@@ -2199,7 +2226,7 @@ import glob4 from "fast-glob";
2199
2226
 
2200
2227
  // src/core/utils/manifest.ts
2201
2228
  import fs12 from "fs-extra";
2202
- import { resolve as resolve13 } from "path";
2229
+ import { resolve as resolve14 } from "path";
2203
2230
 
2204
2231
  // src/core/utils/content-security-policy.ts
2205
2232
  var ContentSecurityPolicy = class _ContentSecurityPolicy {
@@ -2304,10 +2331,10 @@ function getContentScriptJs(config, entrypoint) {
2304
2331
  }
2305
2332
 
2306
2333
  // src/core/utils/package.ts
2307
- import { resolve as resolve12 } from "node:path";
2334
+ import { resolve as resolve13 } from "node:path";
2308
2335
  import fs11 from "fs-extra";
2309
2336
  async function getPackageJson() {
2310
- const file = resolve12(wxt.config.root, "package.json");
2337
+ const file = resolve13(wxt.config.root, "package.json");
2311
2338
  try {
2312
2339
  return await fs11.readJson(file);
2313
2340
  } catch (err) {
@@ -2323,7 +2350,7 @@ import defu2 from "defu";
2323
2350
  async function writeManifest(manifest, output) {
2324
2351
  const str = wxt.config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
2325
2352
  await fs12.ensureDir(wxt.config.outDir);
2326
- await writeFileIfDifferent(resolve13(wxt.config.outDir, "manifest.json"), str);
2353
+ await writeFileIfDifferent(resolve14(wxt.config.outDir, "manifest.json"), str);
2327
2354
  output.publicAssets.unshift({
2328
2355
  type: "asset",
2329
2356
  fileName: "manifest.json"
@@ -3252,7 +3279,8 @@ async function createViteBuilder(wxtConfig, hooks, server) {
3252
3279
  globals(wxtConfig),
3253
3280
  excludeBrowserPolyfill(wxtConfig),
3254
3281
  defineImportMeta(),
3255
- wxtPluginLoader(wxtConfig)
3282
+ wxtPluginLoader(wxtConfig),
3283
+ resolveAppConfig(wxtConfig)
3256
3284
  );
3257
3285
  if (wxtConfig.analysis.enabled) {
3258
3286
  config.plugins.push(bundleAnalysis(wxtConfig));
@@ -3553,6 +3581,7 @@ export {
3553
3581
  tsconfigPaths,
3554
3582
  globals,
3555
3583
  webextensionPolyfillMock,
3584
+ resolveAppConfig,
3556
3585
  kebabCaseAlphanumeric,
3557
3586
  vitePlugin,
3558
3587
  wxt,
package/dist/cli.js CHANGED
@@ -903,6 +903,25 @@ try {
903
903
  };
904
904
  }
905
905
 
906
+ // src/core/builders/vite/plugins/resolveAppConfig.ts
907
+ import { exists } from "fs-extra";
908
+ import { resolve as resolve6 } from "node:path";
909
+ function resolveAppConfig(config) {
910
+ const virtualModuleId = "virtual:app-config";
911
+ const resolvedVirtualModuleId = "\0" + virtualModuleId;
912
+ const appConfigFile = resolve6(config.srcDir, "app.config.ts");
913
+ return {
914
+ name: "wxt:resolve-app-config",
915
+ async resolveId(id) {
916
+ if (id !== virtualModuleId) return;
917
+ return await exists(appConfigFile) ? appConfigFile : resolvedVirtualModuleId;
918
+ },
919
+ load(id) {
920
+ if (id === resolvedVirtualModuleId) return `export default {}`;
921
+ }
922
+ };
923
+ }
924
+
906
925
  // src/core/utils/arrays.ts
907
926
  function every(array, predicate) {
908
927
  for (let i = 0; i < array.length; i++)
@@ -975,7 +994,8 @@ async function createViteBuilder(wxtConfig, hooks, server) {
975
994
  globals(wxtConfig),
976
995
  excludeBrowserPolyfill(wxtConfig),
977
996
  defineImportMeta(),
978
- wxtPluginLoader(wxtConfig)
997
+ wxtPluginLoader(wxtConfig),
998
+ resolveAppConfig(wxtConfig)
979
999
  );
980
1000
  if (wxtConfig.analysis.enabled) {
981
1001
  config.plugins.push(bundleAnalysis(wxtConfig));
@@ -1339,6 +1359,7 @@ function getEslint9ConfigEntry(options, globals2) {
1339
1359
  text: `const globals = ${JSON.stringify(globals2, null, 2)}
1340
1360
 
1341
1361
  export default {
1362
+ name: "wxt/auto-imports",
1342
1363
  languageOptions: {
1343
1364
  globals,
1344
1365
  sourceType: "module",
@@ -1401,7 +1422,7 @@ async function getPublicFiles() {
1401
1422
 
1402
1423
  // src/core/utils/building/build-entrypoints.ts
1403
1424
  import fs4 from "fs-extra";
1404
- import { dirname as dirname3, resolve as resolve6 } from "path";
1425
+ import { dirname as dirname3, resolve as resolve7 } from "path";
1405
1426
  import pc from "picocolors";
1406
1427
  async function buildEntrypoints(groups, spinner) {
1407
1428
  const steps = [];
@@ -1423,14 +1444,14 @@ async function buildEntrypoints(groups, spinner) {
1423
1444
  }
1424
1445
  async function copyPublicDirectory() {
1425
1446
  const files = (await getPublicFiles()).map((file) => ({
1426
- absoluteSrc: resolve6(wxt.config.publicDir, file),
1447
+ absoluteSrc: resolve7(wxt.config.publicDir, file),
1427
1448
  relativeDest: file
1428
1449
  }));
1429
1450
  await wxt.hooks.callHook("build:publicAssets", wxt, files);
1430
1451
  if (files.length === 0) return [];
1431
1452
  const publicAssets = [];
1432
1453
  for (const file of files) {
1433
- const absoluteDest = resolve6(wxt.config.outDir, file.relativeDest);
1454
+ const absoluteDest = resolve7(wxt.config.outDir, file.relativeDest);
1434
1455
  await fs4.ensureDir(dirname3(absoluteDest));
1435
1456
  if ("absoluteSrc" in file) {
1436
1457
  await fs4.copyFile(file.absoluteSrc, absoluteDest);
@@ -1538,7 +1559,7 @@ function findEffectedSteps(changedFile, currentOutput) {
1538
1559
  }
1539
1560
 
1540
1561
  // src/core/utils/building/find-entrypoints.ts
1541
- import { relative as relative3, resolve as resolve7 } from "path";
1562
+ import { relative as relative3, resolve as resolve8 } from "path";
1542
1563
  import fs5 from "fs-extra";
1543
1564
  import { minimatch } from "minimatch";
1544
1565
  import { parseHTML as parseHTML3 } from "linkedom";
@@ -1547,14 +1568,14 @@ import glob3 from "fast-glob";
1547
1568
  import pc2 from "picocolors";
1548
1569
  async function findEntrypoints() {
1549
1570
  await fs5.mkdir(wxt.config.wxtDir, { recursive: true });
1550
- await fs5.writeJson(resolve7(wxt.config.wxtDir, "tsconfig.json"), {});
1571
+ await fs5.writeJson(resolve8(wxt.config.wxtDir, "tsconfig.json"), {});
1551
1572
  const relativePaths = await glob3(Object.keys(PATH_GLOB_TO_TYPE_MAP), {
1552
1573
  cwd: wxt.config.entrypointsDir
1553
1574
  });
1554
1575
  relativePaths.sort();
1555
1576
  const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
1556
1577
  const entrypointInfos = relativePaths.reduce((results, relativePath) => {
1557
- const inputPath = resolve7(wxt.config.entrypointsDir, relativePath);
1578
+ const inputPath = resolve8(wxt.config.entrypointsDir, relativePath);
1558
1579
  const name = getEntrypointName(wxt.config.entrypointsDir, inputPath);
1559
1580
  const matchingGlob = pathGlobs.find(
1560
1581
  (glob8) => minimatch(relativePath, glob8)
@@ -1596,7 +1617,7 @@ async function findEntrypoints() {
1596
1617
  return {
1597
1618
  ...info,
1598
1619
  type,
1599
- outputDir: resolve7(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1620
+ outputDir: resolve8(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1600
1621
  options: {
1601
1622
  include: void 0,
1602
1623
  exclude: void 0
@@ -1823,7 +1844,7 @@ async function getContentScriptEntrypoint({
1823
1844
  type: "content-script",
1824
1845
  name,
1825
1846
  inputPath,
1826
- outputDir: resolve7(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1847
+ outputDir: resolve8(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1827
1848
  options: resolvePerBrowserOptions(options, wxt.config.browser),
1828
1849
  skipped
1829
1850
  };
@@ -1919,7 +1940,7 @@ var CONTENT_SCRIPT_OUT_DIR = "content-scripts";
1919
1940
 
1920
1941
  // src/core/utils/building/generate-wxt-dir.ts
1921
1942
  import fs6 from "fs-extra";
1922
- import { dirname as dirname4, relative as relative4, resolve as resolve8 } from "node:path";
1943
+ import { dirname as dirname4, relative as relative4, resolve as resolve9 } from "node:path";
1923
1944
  import path5 from "node:path";
1924
1945
 
1925
1946
  // src/core/utils/i18n.ts
@@ -1978,7 +1999,7 @@ async function generateTypesDir(entrypoints) {
1978
1999
  entries.push(getMainDeclarationEntry(entries));
1979
2000
  const absoluteFileEntries = entries.filter((entry) => "path" in entry).map((entry) => ({
1980
2001
  ...entry,
1981
- path: resolve8(wxt.config.wxtDir, entry.path)
2002
+ path: resolve9(wxt.config.wxtDir, entry.path)
1982
2003
  }));
1983
2004
  await Promise.all(
1984
2005
  absoluteFileEntries.map(async (file) => {
@@ -2090,7 +2111,7 @@ function getMainDeclarationEntry(references) {
2090
2111
  if ("module" in ref) {
2091
2112
  return lines.push(`/// <reference types="${ref.module}" />`);
2092
2113
  } else if (ref.tsReference) {
2093
- const absolutePath = resolve8(wxt.config.wxtDir, ref.path);
2114
+ const absolutePath = resolve9(wxt.config.wxtDir, ref.path);
2094
2115
  const relativePath = relative4(wxt.config.wxtDir, absolutePath);
2095
2116
  lines.push(`/// <reference types="./${normalizePath(relativePath)}" />`);
2096
2117
  }
@@ -2143,9 +2164,9 @@ import path6 from "node:path";
2143
2164
 
2144
2165
  // src/core/utils/cache.ts
2145
2166
  import fs7, { ensureDir as ensureDir3 } from "fs-extra";
2146
- import { dirname as dirname5, resolve as resolve9 } from "path";
2167
+ import { dirname as dirname5, resolve as resolve10 } from "path";
2147
2168
  function createFsCache(wxtDir) {
2148
- const getPath = (key) => resolve9(wxtDir, "cache", encodeURIComponent(key));
2169
+ const getPath = (key) => resolve10(wxtDir, "cache", encodeURIComponent(key));
2149
2170
  return {
2150
2171
  async set(key, value) {
2151
2172
  const path11 = getPath(key);
@@ -2558,7 +2579,7 @@ var ENTRY_TYPE_TO_GROUP_MAP = {
2558
2579
  import createJITI from "jiti";
2559
2580
  import { createUnimport as createUnimport2 } from "unimport";
2560
2581
  import fs9 from "fs-extra";
2561
- import { relative as relative5, resolve as resolve10 } from "node:path";
2582
+ import { relative as relative5, resolve as resolve11 } from "node:path";
2562
2583
  import { transformSync } from "esbuild";
2563
2584
  import { fileURLToPath } from "node:url";
2564
2585
  async function importEntrypointFile(path11) {
@@ -2583,7 +2604,14 @@ async function importEntrypointFile(path11) {
2583
2604
  debug: wxt.config.debug,
2584
2605
  esmResolve: true,
2585
2606
  alias: {
2586
- "webextension-polyfill": resolve10(
2607
+ "webextension-polyfill": resolve11(
2608
+ wxt.config.wxtModuleDir,
2609
+ "dist/virtual/mock-browser.js"
2610
+ ),
2611
+ // TODO: Resolve this virtual module to some file with
2612
+ // `export default {}` instead of this hack of using another file with
2613
+ // a default export.
2614
+ "virtual:app-config": resolve11(
2587
2615
  wxt.config.wxtModuleDir,
2588
2616
  "dist/virtual/mock-browser.js"
2589
2617
  )
@@ -2648,7 +2676,7 @@ import pc5 from "picocolors";
2648
2676
  import fs13 from "fs-extra";
2649
2677
 
2650
2678
  // src/core/utils/log/printBuildSummary.ts
2651
- import { resolve as resolve11 } from "path";
2679
+ import { resolve as resolve12 } from "path";
2652
2680
 
2653
2681
  // src/core/utils/log/printFileList.ts
2654
2682
  import path7 from "node:path";
@@ -2732,7 +2760,7 @@ async function printBuildSummary(log, header, output) {
2732
2760
  return l.fileName.localeCompare(r.fileName);
2733
2761
  });
2734
2762
  const files = chunks.map(
2735
- (chunk) => resolve11(wxt.config.outDir, chunk.fileName)
2763
+ (chunk) => resolve12(wxt.config.outDir, chunk.fileName)
2736
2764
  );
2737
2765
  await printFileList(log, header, wxt.config.outDir, files);
2738
2766
  }
@@ -2754,7 +2782,7 @@ function getChunkSortWeight(filename) {
2754
2782
  import pc4 from "picocolors";
2755
2783
 
2756
2784
  // package.json
2757
- var version = "0.18.10";
2785
+ var version = "0.18.11";
2758
2786
 
2759
2787
  // src/core/utils/log/printHeader.ts
2760
2788
  function printHeader() {
@@ -2767,7 +2795,7 @@ import glob5 from "fast-glob";
2767
2795
 
2768
2796
  // src/core/utils/manifest.ts
2769
2797
  import fs12 from "fs-extra";
2770
- import { resolve as resolve13 } from "path";
2798
+ import { resolve as resolve14 } from "path";
2771
2799
 
2772
2800
  // src/core/utils/content-security-policy.ts
2773
2801
  var ContentSecurityPolicy = class _ContentSecurityPolicy {
@@ -2872,10 +2900,10 @@ function getContentScriptJs(config, entrypoint) {
2872
2900
  }
2873
2901
 
2874
2902
  // src/core/utils/package.ts
2875
- import { resolve as resolve12 } from "node:path";
2903
+ import { resolve as resolve13 } from "node:path";
2876
2904
  import fs11 from "fs-extra";
2877
2905
  async function getPackageJson() {
2878
- const file = resolve12(wxt.config.root, "package.json");
2906
+ const file = resolve13(wxt.config.root, "package.json");
2879
2907
  try {
2880
2908
  return await fs11.readJson(file);
2881
2909
  } catch (err) {
@@ -2891,7 +2919,7 @@ import defu2 from "defu";
2891
2919
  async function writeManifest(manifest, output) {
2892
2920
  const str = wxt.config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
2893
2921
  await fs12.ensureDir(wxt.config.outDir);
2894
- await writeFileIfDifferent(resolve13(wxt.config.outDir, "manifest.json"), str);
2922
+ await writeFileIfDifferent(resolve14(wxt.config.outDir, "manifest.json"), str);
2895
2923
  output.publicAssets.unshift({
2896
2924
  type: "asset",
2897
2925
  fileName: "manifest.json"
@@ -3688,6 +3716,9 @@ function createWebExtRunner() {
3688
3716
  ...userConfig,
3689
3717
  target: wxt.config.browser === "firefox" ? "firefox-desktop" : "chromium",
3690
3718
  sourceDir: wxt.config.outDir,
3719
+ // Don't add a "Reload Manager" extension alongside dev extension, WXT
3720
+ // already handles reloads intenrally.
3721
+ noReloadManagerExtension: true,
3691
3722
  // WXT handles reloads, so disable auto-reload behaviors in web-ext
3692
3723
  noReload: true,
3693
3724
  noInput: true
@@ -4179,14 +4210,15 @@ async function zipDir(directory, outputPath, options) {
4179
4210
  }
4180
4211
  }
4181
4212
  await options?.additionalWork?.(archive);
4182
- const buffer = await archive.generateAsync({
4183
- type: "base64",
4184
- ...wxt.config.zip.compressionLevel === 0 ? { compression: "STORE" } : {
4185
- compression: "DEFLATE",
4186
- compressionOptions: { level: wxt.config.zip.compressionLevel }
4187
- }
4188
- });
4189
- await fs16.writeFile(outputPath, buffer, "base64");
4213
+ await new Promise(
4214
+ (resolve15, reject) => archive.generateNodeStream({
4215
+ type: "nodebuffer",
4216
+ ...wxt.config.zip.compressionLevel === 0 ? { compression: "STORE" } : {
4217
+ compression: "DEFLATE",
4218
+ compressionOptions: { level: wxt.config.zip.compressionLevel }
4219
+ }
4220
+ }).pipe(fs16.createWriteStream(outputPath)).on("error", reject).on("close", resolve15)
4221
+ );
4190
4222
  }
4191
4223
  async function downloadPrivatePackages() {
4192
4224
  const overrides = {};
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as ContentScriptContext } from './index-Bk-a0SkY.js';
1
+ import { b as ContentScriptContext, a as WxtAppConfig } from './define-app-config-bg54F_lV.js';
2
2
  import 'webextension-polyfill';
3
3
 
4
4
  interface IntegratedContentScriptUi<TMounted> extends ContentScriptUi<TMounted> {
@@ -197,4 +197,6 @@ declare function createIframeUi<TMounted>(ctx: ContentScriptContext, options: If
197
197
  */
198
198
  declare function createShadowRootUi<TMounted>(ctx: ContentScriptContext, options: ShadowRootContentScriptUiOptions<TMounted>): Promise<ShadowRootContentScriptUi<TMounted>>;
199
199
 
200
- export { type ContentScriptAnchoredOptions, type ContentScriptAppendMode, ContentScriptContext, type ContentScriptInlinePositioningOptions, type ContentScriptModalPositioningOptions, type ContentScriptOverlayAlignment, type ContentScriptOverlayPositioningOptions, type ContentScriptPositioningOptions, type ContentScriptUi, type ContentScriptUiOptions, type IframeContentScriptUi, type IframeContentScriptUiOptions, type IntegratedContentScriptUi, type IntegratedContentScriptUiOptions, type ShadowRootContentScriptUi, type ShadowRootContentScriptUiOptions, createIframeUi, createIntegratedUi, createShadowRootUi };
200
+ declare function useAppConfig(): WxtAppConfig;
201
+
202
+ export { type ContentScriptAnchoredOptions, type ContentScriptAppendMode, ContentScriptContext, type ContentScriptInlinePositioningOptions, type ContentScriptModalPositioningOptions, type ContentScriptOverlayAlignment, type ContentScriptOverlayPositioningOptions, type ContentScriptPositioningOptions, type ContentScriptUi, type ContentScriptUiOptions, type IframeContentScriptUi, type IframeContentScriptUiOptions, type IntegratedContentScriptUi, type IntegratedContentScriptUiOptions, type ShadowRootContentScriptUi, type ShadowRootContentScriptUiOptions, createIframeUi, createIntegratedUi, createShadowRootUi, useAppConfig };
package/dist/client.js CHANGED
@@ -397,9 +397,16 @@ async function loadCss() {
397
397
  return "";
398
398
  }
399
399
  }
400
+
401
+ // src/client/app-config.ts
402
+ import appConfig from "virtual:app-config";
403
+ function useAppConfig() {
404
+ return appConfig;
405
+ }
400
406
  export {
401
407
  ContentScriptContext,
402
408
  createIframeUi,
403
409
  createIntegratedUi,
404
- createShadowRootUi
410
+ createShadowRootUi,
411
+ useAppConfig
405
412
  };
@@ -271,4 +271,24 @@ type PerBrowserMap<T> = {
271
271
  };
272
272
  type WxtPlugin = () => void;
273
273
 
274
- export { type BackgroundDefinition as B, type ContentScriptDefinition as C, type UnlistedScriptDefinition as U, type WxtPlugin as W, ContentScriptContext as a };
274
+ interface WxtAppConfig {
275
+ }
276
+ /**
277
+ * Runtime app config defined in `<srcDir>/app.config.ts`.
278
+ *
279
+ * You can add fields to this interface via ["Module Augmentation"](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation):
280
+ *
281
+ * ```ts
282
+ * // app.config.ts
283
+ * import 'wxt/sandbox';
284
+ *
285
+ * declare module "wxt/sandbox" {
286
+ * export interface WxtAppConfig {
287
+ * analytics: AnalyticsConfig
288
+ * }
289
+ * }
290
+ * ```
291
+ */
292
+ declare function defineAppConfig(config: WxtAppConfig): WxtAppConfig;
293
+
294
+ export { type BackgroundDefinition as B, type ContentScriptDefinition as C, type UnlistedScriptDefinition as U, type WxtPlugin as W, type WxtAppConfig as a, ContentScriptContext as b, defineAppConfig as d };