wxt 0.17.12 → 0.18.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.
@@ -3,6 +3,10 @@ import {
3
3
  some,
4
4
  toArray
5
5
  } from "./chunk-5X3S6AWF.js";
6
+ import {
7
+ LogLevels,
8
+ consola
9
+ } from "./chunk-ZZCTFNQ5.js";
6
10
  import {
7
11
  __require
8
12
  } from "./chunk-VBXJIVYU.js";
@@ -655,6 +659,58 @@ function defineImportMeta() {
655
659
  };
656
660
  }
657
661
 
662
+ // src/core/utils/transform.ts
663
+ import { parseModule } from "magicast";
664
+ function removeMainFunctionCode(code) {
665
+ const mod = parseModule(code);
666
+ emptyMainFunction(mod);
667
+ return mod.generate();
668
+ }
669
+ function emptyMainFunction(mod) {
670
+ if (mod.exports?.default?.$type === "function-call") {
671
+ if (mod.exports.default.$ast?.arguments?.[0]?.body) {
672
+ mod.exports.default.$ast.arguments[0].body.body = [];
673
+ } else if (mod.exports.default.$ast?.arguments?.[0]?.properties) {
674
+ mod.exports.default.$ast.arguments[0].properties = mod.exports.default.$ast.arguments[0].properties.filter(
675
+ (prop) => prop.key.name !== "main"
676
+ );
677
+ }
678
+ }
679
+ }
680
+
681
+ // src/core/builders/vite/plugins/removeEntrypointMainFunction.ts
682
+ import { resolve as resolve5 } from "node:path";
683
+ function removeEntrypointMainFunction(config, path8) {
684
+ const absPath = normalizePath(resolve5(config.root, path8));
685
+ return {
686
+ name: "wxt:remove-entrypoint-main-function",
687
+ transform(code, id) {
688
+ if (id === absPath)
689
+ return removeMainFunctionCode(code);
690
+ }
691
+ };
692
+ }
693
+
694
+ // src/core/utils/strings.ts
695
+ function kebabCaseAlphanumeric(str) {
696
+ return str.toLowerCase().replace(/[^a-z0-9-\s]/g, "").replace(/\s+/g, "-");
697
+ }
698
+ function safeVarName(str) {
699
+ return "_" + kebabCaseAlphanumeric(str.trim()).replace("-", "_");
700
+ }
701
+ function removeImportStatements(text) {
702
+ return text.replace(
703
+ /(import\s?[{\w][\s\S]*?from\s?["'][\s\S]*?["'];?|import\s?["'][\s\S]*?["'];?)/gm,
704
+ ""
705
+ );
706
+ }
707
+ function removeProjectImportStatements(text) {
708
+ const noImports = removeImportStatements(text);
709
+ return `import { defineUnlistedScript, defineContentScript, defineBackground } from 'wxt/sandbox';
710
+
711
+ ${noImports}`;
712
+ }
713
+
658
714
  // src/core/utils/fs.ts
659
715
  import fs3 from "fs-extra";
660
716
  import glob from "fast-glob";
@@ -673,7 +729,7 @@ async function getPublicFiles() {
673
729
 
674
730
  // src/core/utils/building/build-entrypoints.ts
675
731
  import fs4 from "fs-extra";
676
- import { dirname as dirname3, resolve as resolve5 } from "path";
732
+ import { dirname as dirname3, resolve as resolve6 } from "path";
677
733
  import pc from "picocolors";
678
734
  async function buildEntrypoints(groups, spinner) {
679
735
  const steps = [];
@@ -699,8 +755,8 @@ async function copyPublicDirectory() {
699
755
  return [];
700
756
  const publicAssets = [];
701
757
  for (const file of files) {
702
- const srcPath = resolve5(wxt.config.publicDir, file);
703
- const outPath = resolve5(wxt.config.outDir, file);
758
+ const srcPath = resolve6(wxt.config.publicDir, file);
759
+ const outPath = resolve6(wxt.config.outDir, file);
704
760
  await fs4.ensureDir(dirname3(outPath));
705
761
  await fs4.copyFile(srcPath, outPath);
706
762
  publicAssets.push({
@@ -806,21 +862,114 @@ function findEffectedSteps(changedFile, currentOutput) {
806
862
  }
807
863
 
808
864
  // src/core/utils/building/find-entrypoints.ts
809
- import { relative as relative3, resolve as resolve6 } from "path";
810
- import fs5 from "fs-extra";
865
+ import { relative as relative4, resolve as resolve8 } from "path";
866
+ import fs6 from "fs-extra";
811
867
  import { minimatch } from "minimatch";
812
868
  import { parseHTML as parseHTML2 } from "linkedom";
813
869
  import JSON5 from "json5";
814
870
  import glob2 from "fast-glob";
815
871
  import pc2 from "picocolors";
872
+
873
+ // src/core/utils/building/import-entrypoint.ts
874
+ import createJITI from "jiti";
875
+ import { createUnimport as createUnimport2 } from "unimport";
876
+ import fs5 from "fs-extra";
877
+ import { relative as relative3, resolve as resolve7 } from "node:path";
878
+ import { transformSync } from "esbuild";
879
+ import { fileURLToPath } from "node:url";
880
+ async function importEntrypointFile(path8) {
881
+ wxt.logger.debug("Loading file metadata:", path8);
882
+ const normalPath = normalizePath(path8);
883
+ const unimport2 = createUnimport2({
884
+ ...wxt.config.imports,
885
+ // Only allow specific imports, not all from the project
886
+ dirs: []
887
+ });
888
+ await unimport2.init();
889
+ const text = await fs5.readFile(path8, "utf-8");
890
+ const textNoImports = removeProjectImportStatements(text);
891
+ const { code } = await unimport2.injectImports(textNoImports);
892
+ wxt.logger.debug(
893
+ ["Text:", text, "No imports:", textNoImports, "Code:", code].join("\n")
894
+ );
895
+ const jiti = createJITI(
896
+ typeof __filename !== "undefined" ? __filename : fileURLToPath(import.meta.url),
897
+ {
898
+ cache: false,
899
+ debug: wxt.config.debug,
900
+ esmResolve: true,
901
+ alias: {
902
+ "webextension-polyfill": resolve7(
903
+ wxt.config.wxtModuleDir,
904
+ "dist/virtual/mock-browser.js"
905
+ )
906
+ },
907
+ // Continue using node to load TS files even if `bun run --bun` is detected. Jiti does not
908
+ // respect the custom transform function when using it's native bun option.
909
+ experimentalBun: false,
910
+ // List of extensions to transform with esbuild
911
+ extensions: [
912
+ ".ts",
913
+ ".cts",
914
+ ".mts",
915
+ ".tsx",
916
+ ".js",
917
+ ".cjs",
918
+ ".mjs",
919
+ ".jsx"
920
+ ],
921
+ transform(opts) {
922
+ const isEntrypoint = opts.filename === normalPath;
923
+ return transformSync(
924
+ // Use modified source code for entrypoints
925
+ isEntrypoint ? code : opts.source,
926
+ getEsbuildOptions(opts)
927
+ );
928
+ }
929
+ }
930
+ );
931
+ try {
932
+ const res = await jiti(path8);
933
+ return res.default;
934
+ } catch (err) {
935
+ const filePath = relative3(wxt.config.root, path8);
936
+ if (err instanceof ReferenceError) {
937
+ const variableName = err.message.replace(" is not defined", "");
938
+ throw Error(
939
+ `${filePath}: Cannot use imported variable "${variableName}" outside the main function. See https://wxt.dev/guide/entrypoints.html#side-effects`,
940
+ { cause: err }
941
+ );
942
+ } else {
943
+ wxt.logger.error(err);
944
+ throw Error(`Failed to load entrypoint: ${filePath}`, { cause: err });
945
+ }
946
+ }
947
+ }
948
+ function getEsbuildOptions(opts) {
949
+ const isJsx = opts.filename?.endsWith("x");
950
+ return {
951
+ format: "cjs",
952
+ loader: isJsx ? "tsx" : "ts",
953
+ ...isJsx ? {
954
+ // `h` and `Fragment` are undefined, but that's OK because JSX is never evaluated while
955
+ // grabbing the entrypoint's options.
956
+ jsxFactory: "h",
957
+ jsxFragment: "Fragment"
958
+ } : void 0
959
+ };
960
+ }
961
+
962
+ // src/core/utils/building/find-entrypoints.ts
816
963
  async function findEntrypoints() {
964
+ await fs6.mkdir(wxt.config.wxtDir, { recursive: true });
965
+ await fs6.writeJson(resolve8(wxt.config.wxtDir, "tsconfig.json"), {});
817
966
  const relativePaths = await glob2(Object.keys(PATH_GLOB_TO_TYPE_MAP), {
818
967
  cwd: wxt.config.entrypointsDir
819
968
  });
820
969
  relativePaths.sort();
821
970
  const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
822
971
  const entrypointInfos = relativePaths.reduce((results, relativePath) => {
823
- const inputPath = resolve6(wxt.config.entrypointsDir, relativePath);
972
+ const inputPath = resolve8(wxt.config.entrypointsDir, relativePath);
824
973
  const name = getEntrypointName(wxt.config.entrypointsDir, inputPath);
825
974
  const matchingGlob = pathGlobs.find(
826
975
  (glob4) => minimatch(relativePath, glob4)
@@ -862,7 +1011,7 @@ async function findEntrypoints() {
862
1011
  return {
863
1012
  ...info,
864
1013
  type,
865
- outputDir: resolve6(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1014
+ outputDir: resolve8(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
866
1015
  options: {
867
1016
  include: void 0,
868
1017
  exclude: void 0
@@ -936,7 +1085,7 @@ function preventDuplicateEntrypointNames(files) {
936
1085
  if (absolutePaths.length > 1) {
937
1086
  lines.push(`- ${name}`);
938
1087
  absolutePaths.forEach((absolutePath) => {
939
- lines.push(` - ${relative3(wxt.config.root, absolutePath)}`);
1088
+ lines.push(` - ${relative4(wxt.config.root, absolutePath)}`);
940
1089
  });
941
1090
  }
942
1091
  return lines;
@@ -1024,7 +1173,7 @@ async function getUnlistedScriptEntrypoint({
1024
1173
  name,
1025
1174
  skipped
1026
1175
  }) {
1027
- const defaultExport = await importEntrypointFile(inputPath);
1176
+ const defaultExport = await importEntrypoint(inputPath);
1028
1177
  if (defaultExport == null) {
1029
1178
  throw Error(
1030
1179
  `${name}: Default export not found, did you forget to call "export default defineUnlistedScript(...)"?`
@@ -1047,7 +1196,7 @@ async function getBackgroundEntrypoint({
1047
1196
  }) {
1048
1197
  let options = {};
1049
1198
  if (inputPath !== VIRTUAL_NOOP_BACKGROUND_MODULE_ID) {
1050
- const defaultExport = await importEntrypointFile(inputPath);
1199
+ const defaultExport = await importEntrypoint(inputPath);
1051
1200
  if (defaultExport == null) {
1052
1201
  throw Error(
1053
1202
  `${name}: Default export not found, did you forget to call "export default defineBackground(...)"?`
@@ -1073,7 +1222,7 @@ async function getContentScriptEntrypoint({
1073
1222
  name,
1074
1223
  skipped
1075
1224
  }) {
1076
- const { main: _, ...options } = await importEntrypointFile(inputPath);
1225
+ const { main: _, ...options } = await importEntrypoint(inputPath);
1077
1226
  if (options == null) {
1078
1227
  throw Error(
1079
1228
  `${name}: Default export not found, did you forget to call "export default defineContentScript(...)"?`
@@ -1083,7 +1232,7 @@ async function getContentScriptEntrypoint({
1083
1232
  type: "content-script",
1084
1233
  name,
1085
1234
  inputPath,
1086
- outputDir: resolve6(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1235
+ outputDir: resolve8(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
1087
1236
  options: resolvePerBrowserOptions(options, wxt.config.browser),
1088
1237
  skipped
1089
1238
  };
@@ -1116,7 +1265,7 @@ async function getSidepanelEntrypoint(info) {
1116
1265
  };
1117
1266
  }
1118
1267
  async function getHtmlEntrypointOptions(info, keyMap, queries, parsers) {
1119
- const content = await fs5.readFile(info.inputPath, "utf-8");
1268
+ const content = await fs6.readFile(info.inputPath, "utf-8");
1120
1269
  const { document } = parseHTML2(content);
1121
1270
  const options = {};
1122
1271
  const defaultQuery = (manifestKey) => document.querySelector(`meta[name='manifest.${manifestKey}']`)?.getAttribute("content");
@@ -1176,11 +1325,14 @@ var PATH_GLOB_TO_TYPE_MAP = {
1176
1325
  [`*/index.${CSS_EXTENSIONS_PATTERN}`]: "unlisted-style"
1177
1326
  };
1178
1327
  var CONTENT_SCRIPT_OUT_DIR = "content-scripts";
1328
+ function importEntrypoint(path8) {
1329
+ return wxt.config.experimental.viteRuntime ? wxt.builder.importEntrypoint(path8) : importEntrypointFile(path8);
1330
+ }
1179
1331
 
1180
1332
  // src/core/utils/building/generate-wxt-dir.ts
1181
- import { createUnimport as createUnimport2 } from "unimport";
1182
- import fs6 from "fs-extra";
1183
- import { relative as relative4, resolve as resolve7 } from "path";
1333
+ import { createUnimport as createUnimport3 } from "unimport";
1334
+ import fs7 from "fs-extra";
1335
+ import { relative as relative5, resolve as resolve9 } from "path";
1184
1336
  import path4 from "node:path";
1185
1337
 
1186
1338
  // src/core/utils/i18n.ts
@@ -1222,10 +1374,10 @@ function parseI18nMessages(messagesJson) {
1222
1374
 
1223
1375
  // src/core/utils/building/generate-wxt-dir.ts
1224
1376
  async function generateTypesDir(entrypoints) {
1225
- await fs6.ensureDir(wxt.config.typesDir);
1377
+ await fs7.ensureDir(wxt.config.typesDir);
1226
1378
  const references = [];
1227
1379
  if (wxt.config.imports !== false) {
1228
- const unimport2 = createUnimport2(wxt.config.imports);
1380
+ const unimport2 = createUnimport3(wxt.config.imports);
1229
1381
  references.push(await writeImportsDeclarationFile(unimport2));
1230
1382
  if (wxt.config.imports.eslintrc.enabled) {
1231
1383
  await writeImportsEslintFile(unimport2, wxt.config.imports);
@@ -1238,7 +1390,7 @@ async function generateTypesDir(entrypoints) {
1238
1390
  await writeTsConfigFile(mainReference);
1239
1391
  }
1240
1392
  async function writeImportsDeclarationFile(unimport2) {
1241
- const filePath = resolve7(wxt.config.typesDir, "imports.d.ts");
1393
+ const filePath = resolve9(wxt.config.typesDir, "imports.d.ts");
1242
1394
  await unimport2.scanImportsFromDir(void 0, { cwd: wxt.config.srcDir });
1243
1395
  await writeFileIfDifferent(
1244
1396
  filePath,
@@ -1254,10 +1406,10 @@ async function writeImportsEslintFile(unimport2, options) {
1254
1406
  (await unimport2.getImports()).map((i) => i.as ?? i.name).filter(Boolean).sort().forEach((name) => {
1255
1407
  eslintrc.globals[name] = options.eslintrc.globalsPropValue;
1256
1408
  });
1257
- await fs6.writeJson(options.eslintrc.filePath, eslintrc, { spaces: 2 });
1409
+ await fs7.writeJson(options.eslintrc.filePath, eslintrc, { spaces: 2 });
1258
1410
  }
1259
1411
  async function writePathsDeclarationFile(entrypoints) {
1260
- const filePath = resolve7(wxt.config.typesDir, "paths.d.ts");
1412
+ const filePath = resolve9(wxt.config.typesDir, "paths.d.ts");
1261
1413
  const unions = entrypoints.map(
1262
1414
  (entry) => getEntrypointBundlePath(
1263
1415
  entry,
@@ -1285,7 +1437,7 @@ declare module "wxt/browser" {
1285
1437
  return filePath;
1286
1438
  }
1287
1439
  async function writeI18nDeclarationFile() {
1288
- const filePath = resolve7(wxt.config.typesDir, "i18n.d.ts");
1440
+ const filePath = resolve9(wxt.config.typesDir, "i18n.d.ts");
1289
1441
  const defaultLocale = wxt.config.manifest.default_locale;
1290
1442
  const template = `// Generated by wxt
1291
1443
  import "wxt/browser";
@@ -1314,7 +1466,7 @@ declare module "wxt/browser" {
1314
1466
  defaultLocale,
1315
1467
  "messages.json"
1316
1468
  );
1317
- const content = JSON.parse(await fs6.readFile(defaultLocalePath, "utf-8"));
1469
+ const content = JSON.parse(await fs7.readFile(defaultLocalePath, "utf-8"));
1318
1470
  messages = parseI18nMessages(content);
1319
1471
  } else {
1320
1472
  messages = parseI18nMessages({});
@@ -1338,7 +1490,7 @@ declare module "wxt/browser" {
1338
1490
  return filePath;
1339
1491
  }
1340
1492
  async function writeGlobalsDeclarationFile() {
1341
- const filePath = resolve7(wxt.config.typesDir, "globals.d.ts");
1493
+ const filePath = resolve9(wxt.config.typesDir, "globals.d.ts");
1342
1494
  const globals2 = [...getGlobals(wxt.config), ...getEntrypointGlobals("")];
1343
1495
  await writeFileIfDifferent(
1344
1496
  filePath,
@@ -1357,14 +1509,14 @@ async function writeGlobalsDeclarationFile() {
1357
1509
  }
1358
1510
  async function writeMainDeclarationFile(references) {
1359
1511
  const dir = wxt.config.wxtDir;
1360
- const filePath = resolve7(dir, "wxt.d.ts");
1512
+ const filePath = resolve9(dir, "wxt.d.ts");
1361
1513
  await writeFileIfDifferent(
1362
1514
  filePath,
1363
1515
  [
1364
1516
  "// Generated by wxt",
1365
1517
  `/// <reference types="wxt/vite-builder-env" />`,
1366
1518
  ...references.map(
1367
- (ref) => `/// <reference types="./${normalizePath(relative4(dir, ref))}" />`
1519
+ (ref) => `/// <reference types="./${normalizePath(relative5(dir, ref))}" />`
1368
1520
  )
1369
1521
  ].join("\n") + "\n"
1370
1522
  );
@@ -1372,7 +1524,7 @@ async function writeMainDeclarationFile(references) {
1372
1524
  }
1373
1525
  async function writeTsConfigFile(mainReference) {
1374
1526
  const dir = wxt.config.wxtDir;
1375
- const getTsconfigPath = (path8) => normalizePath(relative4(dir, path8));
1527
+ const getTsconfigPath = (path8) => normalizePath(relative5(dir, path8));
1376
1528
  const paths = Object.entries(wxt.config.alias).flatMap(([alias, absolutePath]) => {
1377
1529
  const aliasPath = getTsconfigPath(absolutePath);
1378
1530
  return [
@@ -1381,7 +1533,7 @@ async function writeTsConfigFile(mainReference) {
1381
1533
  ];
1382
1534
  }).join(",\n");
1383
1535
  await writeFileIfDifferent(
1384
- resolve7(dir, "tsconfig.json"),
1536
+ resolve9(dir, "tsconfig.json"),
1385
1537
  `{
1386
1538
  "compilerOptions": {
1387
1539
  "target": "ESNext",
@@ -1411,10 +1563,10 @@ import { loadConfig } from "c12";
1411
1563
  import path5 from "node:path";
1412
1564
 
1413
1565
  // src/core/utils/cache.ts
1414
- import fs7, { ensureDir as ensureDir2 } from "fs-extra";
1415
- import { dirname as dirname4, resolve as resolve8 } from "path";
1566
+ import fs8, { ensureDir as ensureDir2 } from "fs-extra";
1567
+ import { dirname as dirname4, resolve as resolve10 } from "path";
1416
1568
  function createFsCache(wxtDir) {
1417
- const getPath = (key) => resolve8(wxtDir, "cache", encodeURIComponent(key));
1569
+ const getPath = (key) => resolve10(wxtDir, "cache", encodeURIComponent(key));
1418
1570
  return {
1419
1571
  async set(key, value) {
1420
1572
  const path8 = getPath(key);
@@ -1424,7 +1576,7 @@ function createFsCache(wxtDir) {
1424
1576
  async get(key) {
1425
1577
  const path8 = getPath(key);
1426
1578
  try {
1427
- return await fs7.readFile(path8, "utf-8");
1579
+ return await fs8.readFile(path8, "utf-8");
1428
1580
  } catch {
1429
1581
  return void 0;
1430
1582
  }
@@ -1433,16 +1585,15 @@ function createFsCache(wxtDir) {
1433
1585
  }
1434
1586
 
1435
1587
  // src/core/utils/building/resolve-config.ts
1436
- import consola, { LogLevels } from "consola";
1437
1588
  import defu from "defu";
1438
1589
 
1439
1590
  // src/core/utils/package.ts
1440
- import { resolve as resolve9 } from "node:path";
1441
- import fs8 from "fs-extra";
1591
+ import { resolve as resolve11 } from "node:path";
1592
+ import fs9 from "fs-extra";
1442
1593
  async function getPackageJson() {
1443
- const file = resolve9(wxt.config.root, "package.json");
1594
+ const file = resolve11(wxt.config.root, "package.json");
1444
1595
  try {
1445
- return await fs8.readJson(file);
1596
+ return await fs9.readJson(file);
1446
1597
  } catch (err) {
1447
1598
  wxt.logger.debug(
1448
1599
  `Failed to read package.json at: ${file}. Returning undefined.`
@@ -1451,11 +1602,14 @@ async function getPackageJson() {
1451
1602
  }
1452
1603
  }
1453
1604
  function isModuleInstalled(name) {
1454
- return import(name).then(() => true).catch(() => false);
1605
+ return import(
1606
+ /* @vite-ignore */
1607
+ name
1608
+ ).then(() => true).catch(() => false);
1455
1609
  }
1456
1610
 
1457
1611
  // src/core/utils/building/resolve-config.ts
1458
- import fs9 from "fs-extra";
1612
+ import fs10 from "fs-extra";
1459
1613
  async function resolveConfig(inlineConfig, command) {
1460
1614
  let userConfig = {};
1461
1615
  let userConfigMetadata;
@@ -1560,7 +1714,8 @@ async function resolveConfig(inlineConfig, command) {
1560
1714
  userConfigMetadata: userConfigMetadata ?? {},
1561
1715
  alias,
1562
1716
  experimental: defu(mergedConfig.experimental, {
1563
- includeBrowserPolyfill: true
1717
+ includeBrowserPolyfill: true,
1718
+ viteRuntime: false
1564
1719
  }),
1565
1720
  dev: {
1566
1721
  server: devServerConfig,
@@ -1602,6 +1757,7 @@ function resolveZipConfig(root, mergedConfig) {
1602
1757
  artifactTemplate: "{{name}}-{{version}}-{{browser}}.zip",
1603
1758
  sourcesRoot: root,
1604
1759
  includeSources: [],
1760
+ compressionLevel: 9,
1605
1761
  ...mergedConfig.zip,
1606
1762
  excludeSources: [
1607
1763
  "**/node_modules",
@@ -1679,7 +1835,7 @@ async function resolveWxtModuleDir() {
1679
1835
  return path5.resolve(requireResolve("wxt"), "../..");
1680
1836
  }
1681
1837
  async function isDirMissing(dir) {
1682
- return !await fs9.exists(dir);
1838
+ return !await fs10.exists(dir);
1683
1839
  }
1684
1840
  function logMissingDir(logger, name, expected) {
1685
1841
  logger.warn(
@@ -1745,120 +1901,12 @@ var ENTRY_TYPE_TO_GROUP_MAP = {
1745
1901
  "content-script-style": "individual"
1746
1902
  };
1747
1903
 
1748
- // src/core/utils/building/import-entrypoint.ts
1749
- import createJITI from "jiti";
1750
- import { createUnimport as createUnimport3 } from "unimport";
1751
- import fs10 from "fs-extra";
1752
- import { relative as relative5, resolve as resolve10 } from "node:path";
1753
-
1754
- // src/core/utils/strings.ts
1755
- function kebabCaseAlphanumeric(str) {
1756
- return str.toLowerCase().replace(/[^a-z0-9-\s]/g, "").replace(/\s+/g, "-");
1757
- }
1758
- function removeImportStatements(text) {
1759
- return text.replace(
1760
- /(import\s?[{\w][\s\S]*?from\s?["'][\s\S]*?["'];?|import\s?["'][\s\S]*?["'];?)/gm,
1761
- ""
1762
- );
1763
- }
1764
- function removeProjectImportStatements(text) {
1765
- const noImports = removeImportStatements(text);
1766
- return `import { defineUnlistedScript, defineContentScript, defineBackground } from 'wxt/sandbox';
1767
-
1768
- ${noImports}`;
1769
- }
1770
-
1771
- // src/core/utils/building/import-entrypoint.ts
1772
- import { transformSync } from "esbuild";
1773
- import { fileURLToPath } from "node:url";
1774
- async function importEntrypointFile(path8) {
1775
- wxt.logger.debug("Loading file metadata:", path8);
1776
- const normalPath = normalizePath(path8);
1777
- const unimport2 = createUnimport3({
1778
- ...wxt.config.imports,
1779
- // Only allow specific imports, not all from the project
1780
- dirs: []
1781
- });
1782
- await unimport2.init();
1783
- const text = await fs10.readFile(path8, "utf-8");
1784
- const textNoImports = removeProjectImportStatements(text);
1785
- const { code } = await unimport2.injectImports(textNoImports);
1786
- wxt.logger.debug(
1787
- ["Text:", text, "No imports:", textNoImports, "Code:", code].join("\n")
1788
- );
1789
- const jiti = createJITI(
1790
- typeof __filename !== "undefined" ? __filename : fileURLToPath(import.meta.url),
1791
- {
1792
- cache: false,
1793
- debug: wxt.config.debug,
1794
- esmResolve: true,
1795
- alias: {
1796
- "webextension-polyfill": resolve10(
1797
- wxt.config.wxtModuleDir,
1798
- "dist/virtual/mock-browser.js"
1799
- )
1800
- },
1801
- // Continue using node to load TS files even if `bun run --bun` is detected. Jiti does not
1802
- // respect the custom transform function when using it's native bun option.
1803
- experimentalBun: false,
1804
- // List of extensions to transform with esbuild
1805
- extensions: [
1806
- ".ts",
1807
- ".cts",
1808
- ".mts",
1809
- ".tsx",
1810
- ".js",
1811
- ".cjs",
1812
- ".mjs",
1813
- ".jsx"
1814
- ],
1815
- transform(opts) {
1816
- const isEntrypoint = opts.filename === normalPath;
1817
- return transformSync(
1818
- // Use modified source code for entrypoints
1819
- isEntrypoint ? code : opts.source,
1820
- getEsbuildOptions(opts)
1821
- );
1822
- }
1823
- }
1824
- );
1825
- try {
1826
- const res = await jiti(path8);
1827
- return res.default;
1828
- } catch (err) {
1829
- const filePath = relative5(wxt.config.root, path8);
1830
- if (err instanceof ReferenceError) {
1831
- const variableName = err.message.replace(" is not defined", "");
1832
- throw Error(
1833
- `${filePath}: Cannot use imported variable "${variableName}" outside the main function. See https://wxt.dev/guide/entrypoints.html#side-effects`,
1834
- { cause: err }
1835
- );
1836
- } else {
1837
- wxt.logger.error(err);
1838
- throw Error(`Failed to load entrypoint: ${filePath}`, { cause: err });
1839
- }
1840
- }
1841
- }
1842
- function getEsbuildOptions(opts) {
1843
- const isJsx = opts.filename?.endsWith("x");
1844
- return {
1845
- format: "cjs",
1846
- loader: isJsx ? "tsx" : "ts",
1847
- ...isJsx ? {
1848
- // `h` and `Fragment` are undefined, but that's OK because JSX is never evaluated while
1849
- // grabbing the entrypoint's options.
1850
- jsxFactory: "h",
1851
- jsxFragment: "Fragment"
1852
- } : void 0
1853
- };
1854
- }
1855
-
1856
1904
  // src/core/utils/building/internal-build.ts
1857
1905
  import pc5 from "picocolors";
1858
1906
  import fs13 from "fs-extra";
1859
1907
 
1860
1908
  // src/core/utils/log/printBuildSummary.ts
1861
- import { resolve as resolve11 } from "path";
1909
+ import { resolve as resolve12 } from "path";
1862
1910
 
1863
1911
  // src/core/utils/log/printFileList.ts
1864
1912
  import path6 from "node:path";
@@ -1946,7 +1994,7 @@ async function printBuildSummary(log, header, output) {
1946
1994
  return l.fileName.localeCompare(r.fileName);
1947
1995
  });
1948
1996
  const files = chunks.map(
1949
- (chunk) => resolve11(wxt.config.outDir, chunk.fileName)
1997
+ (chunk) => resolve12(wxt.config.outDir, chunk.fileName)
1950
1998
  );
1951
1999
  await printFileList(log, header, wxt.config.outDir, files);
1952
2000
  }
@@ -1966,14 +2014,13 @@ function getChunkSortWeight(filename) {
1966
2014
 
1967
2015
  // src/core/utils/log/printHeader.ts
1968
2016
  import pc4 from "picocolors";
1969
- import { consola as consola2 } from "consola";
1970
2017
 
1971
2018
  // src/core/utils/building/internal-build.ts
1972
2019
  import glob3 from "fast-glob";
1973
2020
 
1974
2021
  // src/core/utils/manifest.ts
1975
2022
  import fs12 from "fs-extra";
1976
- import { resolve as resolve12 } from "path";
2023
+ import { resolve as resolve13 } from "path";
1977
2024
 
1978
2025
  // src/core/utils/content-security-policy.ts
1979
2026
  var ContentSecurityPolicy = class _ContentSecurityPolicy {
@@ -2087,7 +2134,7 @@ import defu2 from "defu";
2087
2134
  async function writeManifest(manifest, output) {
2088
2135
  const str = wxt.config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
2089
2136
  await fs12.ensureDir(wxt.config.outDir);
2090
- await writeFileIfDifferent(resolve12(wxt.config.outDir, "manifest.json"), str);
2137
+ await writeFileIfDifferent(resolve13(wxt.config.outDir, "manifest.json"), str);
2091
2138
  output.publicAssets.unshift({
2092
2139
  type: "asset",
2093
2140
  fileName: "manifest.json"
@@ -2145,6 +2192,7 @@ async function generateManifest(entrypoints, buildOutput) {
2145
2192
  if (wxt.config.manifestVersion === 2) {
2146
2193
  convertWebAccessibleResourcesToMv2(manifest);
2147
2194
  convertActionToMv2(manifest);
2195
+ moveHostPermissionsToPermissions(manifest);
2148
2196
  }
2149
2197
  if (wxt.config.manifestVersion === 3) {
2150
2198
  validateMv3WebAccessbileResources(manifest);
@@ -2525,6 +2573,14 @@ function convertWebAccessibleResourcesToMv2(manifest) {
2525
2573
  )
2526
2574
  );
2527
2575
  }
2576
+ function moveHostPermissionsToPermissions(manifest) {
2577
+ if (!manifest.host_permissions?.length)
2578
+ return;
2579
+ manifest.host_permissions.forEach(
2580
+ (permission) => addPermission(manifest, permission)
2581
+ );
2582
+ delete manifest.host_permissions;
2583
+ }
2528
2584
  function convertActionToMv2(manifest) {
2529
2585
  if (manifest.action == null || manifest.browser_action != null || manifest.page_action != null)
2530
2586
  return;
@@ -2686,7 +2742,6 @@ var ValidationError = class extends Error {
2686
2742
  };
2687
2743
 
2688
2744
  // src/core/utils/building/internal-build.ts
2689
- import consola3 from "consola";
2690
2745
  import { mergeJsonOutputs } from "@aklinker1/rollup-plugin-visualizer";
2691
2746
  import { isCI } from "ci-info";
2692
2747
  async function internalBuild() {
@@ -2774,12 +2829,12 @@ function printValidationResults({
2774
2829
  return map;
2775
2830
  }, /* @__PURE__ */ new Map());
2776
2831
  Array.from(entrypointErrors.entries()).forEach(([entrypoint, errors2]) => {
2777
- consola3.log(relative6(cwd, entrypoint.inputPath));
2832
+ consola.log(relative6(cwd, entrypoint.inputPath));
2778
2833
  console.log();
2779
2834
  errors2.forEach((err) => {
2780
2835
  const type = err.type === "error" ? pc5.red("ERROR") : pc5.yellow("WARN");
2781
2836
  const recieved = pc5.dim(`(recieved: ${JSON.stringify(err.value)})`);
2782
- consola3.log(` - ${type} ${err.message} ${recieved}`);
2837
+ consola.log(` - ${type} ${err.message} ${recieved}`);
2783
2838
  });
2784
2839
  console.log();
2785
2840
  });
@@ -2805,7 +2860,7 @@ var npm = {
2805
2860
  overridesKey: "overrides",
2806
2861
  async downloadDependency(id, downloadDir) {
2807
2862
  await ensureDir3(downloadDir);
2808
- const { execa } = await import("./execa-4F7CCWCA.js");
2863
+ const { execa } = await import("./execa-VDW6HLFV.js");
2809
2864
  const res = await execa("npm", ["pack", id, "--json"], {
2810
2865
  cwd: downloadDir
2811
2866
  });
@@ -2817,7 +2872,7 @@ var npm = {
2817
2872
  if (options?.all) {
2818
2873
  args.push("--depth", "Infinity");
2819
2874
  }
2820
- const { execa } = await import("./execa-4F7CCWCA.js");
2875
+ const { execa } = await import("./execa-VDW6HLFV.js");
2821
2876
  const res = await execa("npm", args, { cwd: options?.cwd });
2822
2877
  const project = JSON.parse(res.stdout);
2823
2878
  return flattenNpmListOutput([project]);
@@ -2874,7 +2929,7 @@ var bun = {
2874
2929
  if (options?.all) {
2875
2930
  args.push("--all");
2876
2931
  }
2877
- const { execa } = await import("./execa-4F7CCWCA.js");
2932
+ const { execa } = await import("./execa-VDW6HLFV.js");
2878
2933
  const res = await execa("bun", args, { cwd: options?.cwd });
2879
2934
  return dedupeDependencies(
2880
2935
  res.stdout.split("\n").slice(1).map((line) => line.trim()).map((line) => /.* (@?\S+)@(\S+)$/.exec(line)).filter((match) => !!match).map(([_, name, version2]) => ({ name, version: version2 }))
@@ -2893,7 +2948,7 @@ var yarn = {
2893
2948
  if (options?.all) {
2894
2949
  args.push("--depth", "Infinity");
2895
2950
  }
2896
- const { execa } = await import("./execa-4F7CCWCA.js");
2951
+ const { execa } = await import("./execa-VDW6HLFV.js");
2897
2952
  const res = await execa("yarn", args, { cwd: options?.cwd });
2898
2953
  const tree = res.stdout.split("\n").map((line) => JSON.parse(line)).find((line) => line.type === "tree")?.data;
2899
2954
  if (tree == null)
@@ -2930,7 +2985,7 @@ var pnpm = {
2930
2985
  if (typeof process !== "undefined" && process.env.WXT_PNPM_IGNORE_WORKSPACE === "true") {
2931
2986
  args.push("--ignore-workspace");
2932
2987
  }
2933
- const { execa } = await import("./execa-4F7CCWCA.js");
2988
+ const { execa } = await import("./execa-VDW6HLFV.js");
2934
2989
  const res = await execa("pnpm", args, { cwd: options?.cwd });
2935
2990
  const projects = JSON.parse(res.stdout);
2936
2991
  return flattenNpmListOutput(projects);
@@ -2997,9 +3052,7 @@ var packageManagers = {
2997
3052
  async function createViteBuilder(wxtConfig, hooks, server) {
2998
3053
  const vite = await import("vite");
2999
3054
  const getBaseConfig = async () => {
3000
- const config = await wxtConfig.vite({
3001
- ...wxtConfig.env
3002
- });
3055
+ const config = await wxtConfig.vite(wxtConfig.env);
3003
3056
  config.root = wxtConfig.root;
3004
3057
  config.configFile = false;
3005
3058
  config.logLevel = "warn";
@@ -3041,14 +3094,22 @@ async function createViteBuilder(wxtConfig, hooks, server) {
3041
3094
  if (entrypoint.type === "content-script-style" || entrypoint.type === "unlisted-style") {
3042
3095
  plugins.push(cssEntrypoints(entrypoint, wxtConfig));
3043
3096
  }
3097
+ const iifeReturnValueName = safeVarName(entrypoint.name);
3044
3098
  const libMode = {
3045
3099
  mode: wxtConfig.mode,
3046
3100
  plugins,
3101
+ esbuild: {
3102
+ // Add a footer with the returned value so it can return values to `scripting.executeScript`
3103
+ // Footer is added apart of esbuild to make sure it's not minified. It
3104
+ // get's removed if added to `build.rollupOptions.output.footer`
3105
+ // See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/executeScript#return_value
3106
+ footer: iifeReturnValueName + ";"
3107
+ },
3047
3108
  build: {
3048
3109
  lib: {
3049
3110
  entry,
3050
3111
  formats: ["iife"],
3051
- name: "_",
3112
+ name: iifeReturnValueName,
3052
3113
  fileName: entrypoint.name
3053
3114
  },
3054
3115
  rollupOptions: {
@@ -3135,6 +3196,22 @@ async function createViteBuilder(wxtConfig, hooks, server) {
3135
3196
  return {
3136
3197
  name: "Vite",
3137
3198
  version: vite.version,
3199
+ async importEntrypoint(url) {
3200
+ const baseConfig = await getBaseConfig();
3201
+ const envConfig = {
3202
+ plugins: [
3203
+ webextensionPolyfillMock(wxtConfig),
3204
+ removeEntrypointMainFunction(wxtConfig, url)
3205
+ ]
3206
+ };
3207
+ const config = vite.mergeConfig(baseConfig, envConfig);
3208
+ const server2 = await vite.createServer(config);
3209
+ await server2.listen();
3210
+ const runtime = await vite.createViteRuntime(server2, { hmr: false });
3211
+ const module = await runtime.executeUrl(url);
3212
+ await server2.close();
3213
+ return module.default;
3214
+ },
3138
3215
  async build(group) {
3139
3216
  let entryConfig;
3140
3217
  if (Array.isArray(group))
@@ -3253,6 +3330,7 @@ export {
3253
3330
  tsconfigPaths,
3254
3331
  globals,
3255
3332
  webextensionPolyfillMock,
3333
+ kebabCaseAlphanumeric,
3256
3334
  wxt,
3257
3335
  registerWxt,
3258
3336
  detectDevChanges,
@@ -3260,7 +3338,6 @@ export {
3260
3338
  generateTypesDir,
3261
3339
  getPackageJson,
3262
3340
  resolveConfig,
3263
- kebabCaseAlphanumeric,
3264
3341
  printFileList,
3265
3342
  version,
3266
3343
  mapWxtOptionsToRegisteredContentScript,