wxt 0.21.3 → 0.21.5

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.
Files changed (148) hide show
  1. package/README.md +1 -1
  2. package/dist/{core/build.d.mts → build.d.mts} +2 -2
  3. package/dist/{core/build.mjs → build.mjs} +3 -4
  4. package/dist/{core/clean.d.mts → clean.d.mts} +2 -2
  5. package/dist/{core/clean.mjs → clean.mjs} +3 -3
  6. package/dist/cli/cli-utils.mjs +11 -8
  7. package/dist/cli/commands.mjs +10 -9
  8. package/dist/{core/create-server.d.mts → create-server.d.mts} +2 -2
  9. package/dist/{core/create-server.mjs → create-server.mjs} +13 -14
  10. package/dist/define-config.d.mts +6 -0
  11. package/dist/{core/define-config.mjs → define-config.mjs} +1 -1
  12. package/dist/{core/define-web-ext-config.d.mts → define-web-ext-config.d.mts} +2 -2
  13. package/dist/{core/define-web-ext-config.mjs → define-web-ext-config.mjs} +1 -1
  14. package/dist/index.d.mts +12 -12
  15. package/dist/index.mjs +10 -11
  16. package/dist/{core/initialize.d.mts → initialize.d.mts} +2 -1
  17. package/dist/{core/initialize.mjs → initialize.mjs} +22 -7
  18. package/dist/inline/dotenv-expand/index.mjs +31 -0
  19. package/dist/inline/get-port-please/index.mjs +196 -0
  20. package/dist/inline/is-wsl/index.mjs +44 -0
  21. package/dist/inline/normalize-path/index.mjs +23 -0
  22. package/dist/inline/ohash/index.mjs +113 -0
  23. package/dist/inline/scule/index.mjs +50 -0
  24. package/dist/{core/utils/building → internal}/build-entrypoints.mjs +5 -5
  25. package/dist/internal/builders/unknown.mjs +22 -0
  26. package/dist/{core → internal}/builders/vite/index.mjs +144 -139
  27. package/dist/internal/builders/vite/plugins/add-entrypoint-group-runtime-env-entries.mjs +16 -0
  28. package/dist/internal/builders/vite/plugins/add-runtime-env-entries.mjs +14 -0
  29. package/dist/{core/builders/vite/plugins/bundleAnalysis.mjs → internal/builders/vite/plugins/bundle-analysis.mjs} +1 -1
  30. package/dist/{core/builders/vite/plugins/cssEntrypoints.mjs → internal/builders/vite/plugins/css-entrypoints.mjs} +2 -2
  31. package/dist/{core/builders/vite/plugins/defineImportMeta.mjs → internal/builders/vite/plugins/define-import-meta.mjs} +1 -1
  32. package/dist/{core/builders/vite/plugins/devHtmlPrerender.mjs → internal/builders/vite/plugins/dev-html-prerender.mjs} +6 -7
  33. package/dist/{core/builders/vite/plugins/devServerGlobals.mjs → internal/builders/vite/plugins/dev-server-globals.mjs} +1 -1
  34. package/dist/{core/builders/vite/plugins/extensionApiMock.mjs → internal/builders/vite/plugins/extension-api-mock.mjs} +1 -1
  35. package/dist/{core/builders/vite/plugins/iifeAnonymous.mjs → internal/builders/vite/plugins/iife-anonymous.mjs} +1 -1
  36. package/dist/{core/builders/vite/plugins/iifeFooter.mjs → internal/builders/vite/plugins/iife-footer.mjs} +1 -1
  37. package/dist/internal/builders/vite/plugins/index.mjs +17 -0
  38. package/dist/{core/builders/vite/plugins/noopBackground.mjs → internal/builders/vite/plugins/noop-background.mjs} +2 -2
  39. package/dist/{core/builders/vite/plugins/removeEntrypointMainFunction.mjs → internal/builders/vite/plugins/remove-entrypoint-main-function.mjs} +3 -4
  40. package/dist/{core/builders/vite/plugins/resolveAppConfig.mjs → internal/builders/vite/plugins/resolve-app-config.mjs} +2 -2
  41. package/dist/{core/builders/vite/plugins/resolveVirtualModules.mjs → internal/builders/vite/plugins/resolve-virtual-modules.mjs} +8 -6
  42. package/dist/{core/builders/vite/plugins/tsconfigPaths.mjs → internal/builders/vite/plugins/tsconfig-paths.mjs} +1 -1
  43. package/dist/internal/builders/vite/plugins/wxt-plugin-loader.mjs +77 -0
  44. package/dist/{builtin-modules → internal/builtin-modules}/escape-unicode.mjs +2 -2
  45. package/dist/{builtin-modules → internal/builtin-modules}/favicon-permission.mjs +2 -2
  46. package/dist/{builtin-modules → internal/builtin-modules}/index.mjs +4 -2
  47. package/dist/internal/builtin-modules/plugins.mjs +21 -0
  48. package/dist/{builtin-modules → internal/builtin-modules}/unimport.mjs +20 -9
  49. package/dist/{core/utils → internal}/constants.mjs +1 -1
  50. package/dist/internal/detect-builder.mjs +9 -0
  51. package/dist/{core/utils/building → internal}/detect-dev-changes.mjs +4 -4
  52. package/dist/internal/detect-runner.mjs +11 -0
  53. package/dist/internal/entrypoint-finders/flat.mjs +84 -0
  54. package/dist/internal/environments/browser-environment.mjs +48 -0
  55. package/dist/{core/utils → internal}/environments/environment.mjs +1 -1
  56. package/dist/{core/utils → internal}/environments/extension-environment.mjs +1 -1
  57. package/dist/{core/utils/create-file-reloader.mjs → internal/file-reloader.mjs} +10 -11
  58. package/dist/{core/utils/building → internal}/find-entrypoints.mjs +10 -75
  59. package/dist/{core → internal}/generate-wxt-dir.mjs +10 -10
  60. package/dist/internal/get-public-files.mjs +14 -0
  61. package/dist/{core/utils/building → internal}/group-entrypoints.mjs +1 -1
  62. package/dist/{core/utils → internal}/i18n.mjs +1 -1
  63. package/dist/{core/utils/building → internal}/internal-build.mjs +10 -10
  64. package/dist/{core → internal}/keyboard-shortcuts.mjs +2 -1
  65. package/dist/{core/utils → internal}/manifest.mjs +14 -14
  66. package/dist/internal/package-managers/bun.mjs +22 -0
  67. package/dist/{core → internal}/package-managers/deno.mjs +1 -1
  68. package/dist/{core → internal}/package-managers/index.mjs +1 -1
  69. package/dist/{core → internal}/package-managers/npm.mjs +11 -5
  70. package/dist/{core → internal}/package-managers/pnpm.mjs +6 -3
  71. package/dist/{core → internal}/package-managers/yarn.mjs +6 -3
  72. package/dist/{core/utils → internal}/package.mjs +3 -3
  73. package/dist/{core/utils/building → internal}/rebuild.mjs +5 -5
  74. package/dist/{core → internal}/resolve-config.mjs +22 -42
  75. package/dist/internal/runners/manual.mjs +22 -0
  76. package/dist/internal/runners/web-ext.mjs +79 -0
  77. package/dist/{core/utils/globals.mjs → internal/runtime-env-entries.mjs} +4 -4
  78. package/dist/internal/spinner.mjs +69 -0
  79. package/dist/{core/utils → internal}/syntax-errors.mjs +2 -2
  80. package/dist/{core/utils → internal}/theme-icons.mjs +3 -3
  81. package/dist/{core/utils → internal}/transform.mjs +1 -1
  82. package/dist/{core/utils → internal}/validation.mjs +1 -1
  83. package/dist/{core → internal}/wxt.mjs +24 -7
  84. package/dist/{core/utils/arrays.mjs → internal-utils/array-utils.mjs} +1 -1
  85. package/dist/{core/utils/cache.mjs → internal-utils/cache-utils.mjs} +3 -3
  86. package/dist/{core/utils/content-scripts.mjs → internal-utils/content-script-utils.mjs} +2 -2
  87. package/dist/{core/utils/content-security-policy.mjs → internal-utils/csp-utils.mjs} +1 -1
  88. package/dist/{core/utils/entrypoints.d.mts → internal-utils/entrypoint-utils.d.mts} +2 -2
  89. package/dist/{core/utils/entrypoints.mjs → internal-utils/entrypoint-utils.mjs} +2 -2
  90. package/dist/{core/utils/env.mjs → internal-utils/env-utils.mjs} +3 -3
  91. package/dist/internal-utils/eslint-utils.mjs +8 -0
  92. package/dist/{core/utils/fs.mjs → internal-utils/fs-utils.mjs} +6 -11
  93. package/dist/internal-utils/log/index.mjs +6 -0
  94. package/dist/{core/utils/log/printBuildSummary.mjs → internal-utils/log/print-build-summary.mjs} +3 -3
  95. package/dist/{core/utils/log/printFileList.mjs → internal-utils/log/print-file-list.mjs} +9 -8
  96. package/dist/{core/utils/log/printHeader.mjs → internal-utils/log/print-header.mjs} +2 -2
  97. package/dist/{core/utils/log/printTable.mjs → internal-utils/log/print-table.mjs} +1 -1
  98. package/dist/internal-utils/log/wxt-logger.mjs +32 -0
  99. package/dist/internal-utils/module-utils.mjs +32 -0
  100. package/dist/{core/utils/number.mjs → internal-utils/number-utils.mjs} +1 -1
  101. package/dist/{core/utils/paths.d.mts → internal-utils/path-utils.d.mts} +1 -1
  102. package/dist/{core/utils/paths.mjs → internal-utils/path-utils.mjs} +3 -3
  103. package/dist/{core/utils/strings.mjs → internal-utils/string-utils.mjs} +3 -3
  104. package/dist/{core/utils/time.mjs → internal-utils/time-utils.mjs} +1 -1
  105. package/dist/{core/utils/types.d.mts → internal-utils/type-utils.d.mts} +2 -1
  106. package/dist/{modules.d.mts → modules/index.d.mts} +10 -4
  107. package/dist/{modules.mjs → modules/index.mjs} +14 -5
  108. package/dist/prepare.d.mts +6 -0
  109. package/dist/prepare.mjs +11 -0
  110. package/dist/testing/wxt-vitest-plugin.mjs +7 -7
  111. package/dist/types.d.mts +97 -47
  112. package/dist/utils/content-script-context.d.mts +1 -1
  113. package/dist/utils/content-script-ui/iframe.d.mts +7 -0
  114. package/dist/utils/content-script-ui/iframe.mjs +2 -0
  115. package/dist/utils/content-script-ui/integrated.d.mts +7 -0
  116. package/dist/utils/content-script-ui/integrated.mjs +2 -0
  117. package/dist/utils/content-script-ui/shadow-root.d.mts +7 -0
  118. package/dist/utils/content-script-ui/shadow-root.mjs +2 -0
  119. package/dist/utils/content-script-ui/types.d.mts +23 -7
  120. package/dist/utils/internal/custom-events.d.mts +11 -1
  121. package/dist/utils/internal/custom-events.mjs +4 -0
  122. package/dist/version.mjs +1 -1
  123. package/dist/virtual/background-entrypoint.mjs +11 -0
  124. package/dist/{core/zip.d.mts → zip.d.mts} +2 -2
  125. package/dist/{core/zip.mjs → zip.mjs} +11 -13
  126. package/package.json +14 -15
  127. package/dist/core/builders/vite/plugins/entrypointGroupGlobals.mjs +0 -16
  128. package/dist/core/builders/vite/plugins/globals.mjs +0 -14
  129. package/dist/core/builders/vite/plugins/index.mjs +0 -17
  130. package/dist/core/builders/vite/plugins/wxtPluginLoader.mjs +0 -56
  131. package/dist/core/define-config.d.mts +0 -6
  132. package/dist/core/index.d.mts +0 -10
  133. package/dist/core/index.mjs +0 -12
  134. package/dist/core/package-managers/bun.mjs +0 -19
  135. package/dist/core/prepare.d.mts +0 -6
  136. package/dist/core/prepare.mjs +0 -12
  137. package/dist/core/runners/manual.mjs +0 -11
  138. package/dist/core/runners/safari.mjs +0 -14
  139. package/dist/core/runners/web-ext.mjs +0 -63
  140. package/dist/core/runners/wsl.mjs +0 -14
  141. package/dist/core/utils/building/index.mjs +0 -7
  142. package/dist/core/utils/environments/browser-environment.mjs +0 -18
  143. package/dist/core/utils/eslint.mjs +0 -11
  144. package/dist/core/utils/index.d.mts +0 -2
  145. package/dist/core/utils/index.mjs +0 -3
  146. package/dist/core/utils/log/index.mjs +0 -5
  147. /package/dist/{core/utils → internal}/environments/index.mjs +0 -0
  148. /package/dist/{core/utils → internal}/virtual-modules.mjs +0 -0
@@ -1,16 +1,13 @@
1
- import { CSS_EXTENSIONS_PATTERN } from "../paths.mjs";
2
- import { getEntrypointName, isHtmlEntrypoint, isJsEntrypoint, resolvePerBrowserOptions } from "../entrypoints.mjs";
3
- import { VIRTUAL_NOOP_BACKGROUND_MODULE_ID } from "../constants.mjs";
4
- import { wxt } from "../../wxt.mjs";
5
- import { mkdir, readFile, writeFile } from "node:fs/promises";
6
- import { glob } from "tinyglobby";
1
+ import { isHtmlEntrypoint, isJsEntrypoint, resolvePerBrowserOptions } from "../internal-utils/entrypoint-utils.mjs";
2
+ import { VIRTUAL_NOOP_BACKGROUND_MODULE_ID } from "./constants.mjs";
3
+ import { s } from "../inline/scule/index.mjs";
4
+ import { wxt } from "./wxt.mjs";
7
5
  import { relative, resolve } from "path";
6
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
8
7
  import { parseHTML } from "linkedom";
9
- import { camelCase } from "scule";
10
- import { styleText } from "node:util";
11
- import picomatch from "picomatch";
12
8
  import JSON5 from "json5";
13
- //#region src/core/utils/building/find-entrypoints.ts
9
+ import { styleText } from "node:util";
10
+ //#region src/internal/find-entrypoints.ts
14
11
  /**
15
12
  * Return entrypoints and their configuration by looking through the project's
16
13
  * files.
@@ -22,30 +19,7 @@ async function findEntrypoints() {
22
19
  } catch (err) {
23
20
  if (!(err instanceof Error) || !("code" in err) || err.code !== "EEXIST") throw err;
24
21
  }
25
- const relativePaths = await glob(Object.keys(PATH_GLOB_TO_TYPE_MAP), {
26
- cwd: wxt.config.entrypointsDir,
27
- expandDirectories: false
28
- });
29
- relativePaths.sort();
30
- const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
31
- const entrypointInfos = relativePaths.reduce((results, relativePath) => {
32
- const inputPath = resolve(wxt.config.entrypointsDir, relativePath);
33
- const name = getEntrypointName(wxt.config.entrypointsDir, inputPath);
34
- const matchingGlob = pathGlobs.find((glob) => picomatch(glob)(relativePath));
35
- if (matchingGlob) {
36
- const type = PATH_GLOB_TO_TYPE_MAP[matchingGlob];
37
- results.push({
38
- name,
39
- inputPath,
40
- type
41
- });
42
- }
43
- return results;
44
- }, []).filter(({ name, inputPath }, _, entrypointInfos) => {
45
- if (inputPath.endsWith(".html")) return true;
46
- if (!/index\..+$/.test(inputPath)) return true;
47
- return !entrypointInfos.some((entry) => entry.name === name && entry.inputPath.endsWith("index.html"));
48
- });
22
+ const entrypointInfos = await wxt.entrypointFinder.findEntrypoints();
49
23
  await wxt.hooks.callHook("entrypoints:found", wxt, entrypointInfos);
50
24
  preventNoEntrypoints(entrypointInfos);
51
25
  preventDuplicateEntrypointNames(entrypointInfos);
@@ -118,8 +92,8 @@ async function importHtmlEntrypoint(info) {
118
92
  metaTags.forEach((tag) => {
119
93
  const name = tag.name;
120
94
  let key;
121
- if (name.startsWith("manifest.")) key = camelCase(name.slice(9));
122
- else if (name.startsWith("wxt.")) key = camelCase(name.slice(4));
95
+ if (name.startsWith("manifest.")) key = s(name.slice(9));
96
+ else if (name.startsWith("wxt.")) key = s(name.slice(4));
123
97
  else return;
124
98
  try {
125
99
  res[key] = JSON5.parse(tag.content);
@@ -256,45 +230,6 @@ function isEntrypointSkipped(entry) {
256
230
  if (include?.length && !exclude?.length) return !include.includes(wxt.config.browser);
257
231
  return false;
258
232
  }
259
- const PATH_GLOB_TO_TYPE_MAP = {
260
- "sandbox.html": "sandbox",
261
- "sandbox/index.html": "sandbox",
262
- "*.sandbox.html": "sandbox",
263
- "*.sandbox/index.html": "sandbox",
264
- "bookmarks.html": "bookmarks",
265
- "bookmarks/index.html": "bookmarks",
266
- "history.html": "history",
267
- "history/index.html": "history",
268
- "newtab.html": "newtab",
269
- "newtab/index.html": "newtab",
270
- "sidepanel.html": "sidepanel",
271
- "sidepanel/index.html": "sidepanel",
272
- "*.sidepanel.html": "sidepanel",
273
- "*.sidepanel/index.html": "sidepanel",
274
- "devtools.html": "devtools",
275
- "devtools/index.html": "devtools",
276
- "background.[jt]s": "background",
277
- "background/index.[jt]s": "background",
278
- [VIRTUAL_NOOP_BACKGROUND_MODULE_ID]: "background",
279
- "content.[jt]s?(x)": "content-script",
280
- "content/index.[jt]s?(x)": "content-script",
281
- "*.content.[jt]s?(x)": "content-script",
282
- "*.content/index.[jt]s?(x)": "content-script",
283
- [`content.${CSS_EXTENSIONS_PATTERN}`]: "content-script-style",
284
- [`*.content.${CSS_EXTENSIONS_PATTERN}`]: "content-script-style",
285
- [`content/index.${CSS_EXTENSIONS_PATTERN}`]: "content-script-style",
286
- [`*.content/index.${CSS_EXTENSIONS_PATTERN}`]: "content-script-style",
287
- "popup.html": "popup",
288
- "popup/index.html": "popup",
289
- "options.html": "options",
290
- "options/index.html": "options",
291
- "*.html": "unlisted-page",
292
- "*/index.html": "unlisted-page",
293
- "*.[jt]s?(x)": "unlisted-script",
294
- "*/index.[jt]s?(x)": "unlisted-script",
295
- [`*.${CSS_EXTENSIONS_PATTERN}`]: "unlisted-style",
296
- [`*/index.${CSS_EXTENSIONS_PATTERN}`]: "unlisted-style"
297
- };
298
233
  const CONTENT_SCRIPT_OUT_DIR = "content-scripts";
299
234
  //#endregion
300
235
  export { findEntrypoints };
@@ -1,13 +1,13 @@
1
- import { normalizePath } from "./utils/paths.mjs";
2
- import { getEntrypointBundlePath, isHtmlEntrypoint } from "./utils/entrypoints.mjs";
3
- import "./utils/index.mjs";
4
- import { getEntrypointGlobals, getGlobals } from "./utils/globals.mjs";
1
+ import { normalizePath } from "../internal-utils/path-utils.mjs";
2
+ import { getEntrypointBundlePath, isHtmlEntrypoint } from "../internal-utils/entrypoint-utils.mjs";
3
+ import { pathExists, writeFileIfDifferent } from "../internal-utils/fs-utils.mjs";
4
+ import { getEntrypointRuntimeEnvEntries, getRuntimeEnvEntries } from "./runtime-env-entries.mjs";
5
5
  import { wxt } from "./wxt.mjs";
6
- import { getPublicFiles, pathExists, writeFileIfDifferent } from "./utils/fs.mjs";
7
- import { parseI18nMessages } from "./utils/i18n.mjs";
6
+ import { parseI18nMessages } from "./i18n.mjs";
7
+ import { getPublicFiles } from "./get-public-files.mjs";
8
8
  import { mkdir, readFile } from "node:fs/promises";
9
9
  import path, { dirname, relative, resolve } from "node:path";
10
- //#region src/core/generate-wxt-dir.ts
10
+ //#region src/internal/generate-wxt-dir.ts
11
11
  /**
12
12
  * Generate and write all the files inside the `InternalConfig.typesDir`
13
13
  * directory.
@@ -20,7 +20,7 @@ async function generateWxtDir(entrypoints) {
20
20
  });
21
21
  entries.push(await getPathsDeclarationEntry(entrypoints));
22
22
  entries.push(await getI18nDeclarationEntry());
23
- entries.push(await getGlobalsDeclarationEntry());
23
+ entries.push(await getRuntimeEnvDeclarationEntry());
24
24
  entries.push(await getTsConfigEntry());
25
25
  await wxt.hooks.callHook("prepare:types", wxt, entries);
26
26
  entries.push(getMainDeclarationEntry(entries));
@@ -129,13 +129,13 @@ declare module "wxt/browser" {
129
129
  tsReference: true
130
130
  };
131
131
  }
132
- async function getGlobalsDeclarationEntry() {
132
+ async function getRuntimeEnvDeclarationEntry() {
133
133
  return {
134
134
  path: "types/globals.d.ts",
135
135
  text: [
136
136
  "// Generated by wxt",
137
137
  "interface ImportMetaEnv {",
138
- ...[...getGlobals(wxt.config), ...getEntrypointGlobals("")].map((global) => ` readonly ${global.name}: ${global.type};`),
138
+ ...[...getRuntimeEnvEntries(wxt.config), ...getEntrypointRuntimeEnvEntries("")].map((global) => ` readonly ${global.name}: ${global.type};`),
139
139
  "}",
140
140
  "interface ImportMeta {",
141
141
  " readonly env: ImportMetaEnv",
@@ -0,0 +1,14 @@
1
+ import { unnormalizePath } from "../internal-utils/path-utils.mjs";
2
+ import { pathExists } from "../internal-utils/fs-utils.mjs";
3
+ import { wxt } from "./wxt.mjs";
4
+ import { glob } from "tinyglobby";
5
+ //#region src/internal/get-public-files.ts
6
+ async function getPublicFiles() {
7
+ if (!await pathExists(wxt.config.publicDir)) return [];
8
+ return (await glob("**/*", {
9
+ cwd: wxt.config.publicDir,
10
+ expandDirectories: false
11
+ })).map(unnormalizePath);
12
+ }
13
+ //#endregion
14
+ export { getPublicFiles };
@@ -1,4 +1,4 @@
1
- //#region src/core/utils/building/group-entrypoints.ts
1
+ //#region src/internal/group-entrypoints.ts
2
2
  /**
3
3
  * Entrypoints are built in groups. HTML pages can all be built together in a
4
4
  * single step, content scripts must be build individually, etc.
@@ -1,4 +1,4 @@
1
- //#region src/core/utils/i18n.ts
1
+ //#region src/internal/i18n.ts
2
2
  const predefinedMessages = {
3
3
  "@@extension_id": {
4
4
  message: "<browser.runtime.id>",
@@ -1,20 +1,20 @@
1
- import { unnormalizePath } from "../paths.mjs";
2
- import { isCI } from "../env.mjs";
3
- import { wxt } from "../../wxt.mjs";
1
+ import { unnormalizePath } from "../internal-utils/path-utils.mjs";
2
+ import { isCI } from "../internal-utils/env-utils.mjs";
3
+ import { formatDuration } from "../internal-utils/time-utils.mjs";
4
+ import { wxt } from "./wxt.mjs";
4
5
  import { findEntrypoints } from "./find-entrypoints.mjs";
5
6
  import { groupEntrypoints } from "./group-entrypoints.mjs";
6
- import { formatDuration } from "../time.mjs";
7
- import { printBuildSummary } from "../log/printBuildSummary.mjs";
8
- import "../log/index.mjs";
7
+ import { printBuildSummary } from "../internal-utils/log/print-build-summary.mjs";
8
+ import "../internal-utils/log/index.mjs";
9
9
  import { rebuild } from "./rebuild.mjs";
10
- import { ValidationError, validateEntrypoints } from "../validation.mjs";
10
+ import { ValidationError, validateEntrypoints } from "./validation.mjs";
11
11
  import { mkdir, rm } from "node:fs/promises";
12
- import { glob } from "tinyglobby";
13
12
  import { relative } from "node:path";
14
- import { mergeJsonOutputs } from "@aklinker1/rollup-plugin-visualizer";
13
+ import { glob } from "tinyglobby";
15
14
  import { styleText } from "node:util";
15
+ import { mergeJsonOutputs } from "@aklinker1/rollup-plugin-visualizer";
16
16
  import open from "tiny-open";
17
- //#region src/core/utils/building/internal-build.ts
17
+ //#region src/internal/internal-build.ts
18
18
  /**
19
19
  * Builds the extension based on an internal config. No more config discovery is
20
20
  * performed, the build is based on exactly what is passed in.
@@ -1,7 +1,7 @@
1
1
  import { wxt } from "./wxt.mjs";
2
2
  import { styleText } from "node:util";
3
3
  import readline from "node:readline";
4
- //#region src/core/keyboard-shortcuts.ts
4
+ //#region src/internal/keyboard-shortcuts.ts
5
5
  /** Function that creates a keyboard shortcut handler for the extension. */
6
6
  function createKeyboardShortcuts(server) {
7
7
  let rl;
@@ -11,6 +11,7 @@ function createKeyboardShortcuts(server) {
11
11
  return {
12
12
  start() {
13
13
  this.stop();
14
+ if (!process.stdin.isTTY) return;
14
15
  rl ??= readline.createInterface({
15
16
  input: process.stdin,
16
17
  terminal: false
@@ -1,15 +1,15 @@
1
- import { normalizePath } from "./paths.mjs";
2
- import { getEntrypointBundlePath } from "./entrypoints.mjs";
3
- import { wxt } from "../wxt.mjs";
4
- import { writeFileIfDifferent } from "./fs.mjs";
5
- import { ContentSecurityPolicy } from "./content-security-policy.mjs";
6
- import { hashContentScriptOptions, mapWxtOptionsToContentScript } from "./content-scripts.mjs";
1
+ import { normalizePath } from "../internal-utils/path-utils.mjs";
2
+ import { getEntrypointBundlePath } from "../internal-utils/entrypoint-utils.mjs";
3
+ import { writeFileIfDifferent } from "../internal-utils/fs-utils.mjs";
4
+ import { wxt } from "./wxt.mjs";
5
+ import { ContentSecurityPolicy } from "../internal-utils/csp-utils.mjs";
6
+ import { hashContentScriptOptions, mapWxtOptionsToContentScript } from "../internal-utils/content-script-utils.mjs";
7
7
  import { getPackageJson } from "./package.mjs";
8
8
  import { addDiscoveredThemeIcons } from "./theme-icons.mjs";
9
- import { mkdir } from "node:fs/promises";
10
9
  import { resolve } from "path";
10
+ import { mkdir } from "node:fs/promises";
11
11
  import defu from "defu";
12
- //#region src/core/utils/manifest.ts
12
+ //#region src/internal/manifest.ts
13
13
  /** Writes the manifest to the output directory and the build output. */
14
14
  async function writeManifest(manifest, output) {
15
15
  const str = wxt.config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
@@ -28,7 +28,7 @@ async function generateManifest(allEntrypoints, buildOutput) {
28
28
  let versionName = wxt.config.manifest.version_name ?? wxt.config.manifest.version ?? pkg?.version;
29
29
  if (versionName == null) {
30
30
  versionName = "0.0.0";
31
- wxt.logger.warn("Extension version not found, defaulting to \"0.0.0\". Add a version to your `package.json` or `wxt.config.ts` file. For more details, see: https://wxt.dev/guide/key-concepts/manifest.html#version-and-version-name");
31
+ wxt.logger.warnOnce("Extension version not found, defaulting to \"0.0.0\". Add a version to your `package.json` or `wxt.config.ts` file. For more details, see: https://wxt.dev/guide/essentials/config/manifest.html#version-and-version-name");
32
32
  }
33
33
  const version = wxt.config.manifest.version ?? simplifyVersion(versionName);
34
34
  const baseManifest = {
@@ -42,7 +42,7 @@ async function generateManifest(allEntrypoints, buildOutput) {
42
42
  const userManifest = wxt.config.manifest;
43
43
  if (userManifest.manifest_version) {
44
44
  delete userManifest.manifest_version;
45
- wxt.logger.warn("`manifest.manifest_version` config was set, but ignored. To change the target manifest version, use the `manifestVersion` option or the `--mv2`/`--mv3` CLI flags.\nSee https://wxt.dev/guide/essentials/target-different-browsers.html#target-a-manifest-version");
45
+ wxt.logger.warnOnce("`manifest.manifest_version` config was set, but ignored. To change the target manifest version, use the `manifestVersion` option or the `--mv2`/`--mv3` CLI flags.\nSee https://wxt.dev/guide/essentials/target-different-browsers.html#target-a-manifest-version");
46
46
  }
47
47
  let manifest = defu(userManifest, baseManifest);
48
48
  if (wxt.config.command === "serve" && wxt.config.dev.reloadCommand) if (manifest.commands && Object.values(manifest.commands).filter((command) => command.suggested_key).length >= 4) warnings.push(["Extension already has 4 registered commands with suggested keys, WXT's reload command is disabled"]);
@@ -55,8 +55,8 @@ async function generateManifest(allEntrypoints, buildOutput) {
55
55
  }
56
56
  manifest.version = version;
57
57
  manifest.version_name = wxt.config.browser === "firefox" || versionName === version ? void 0 : versionName;
58
- if (wxt.config.browser === "firefox" && !userManifest.browser_specific_settings?.gecko?.data_collection_permissions && !wxt.config.suppressWarnings?.firefoxDataCollection) wxt.logger.warn("Firefox requires `data_collection_permissions` for new extensions from November 3, 2025. Existing extensions are exempt for now.\nFor more details, see: https://extensionworkshop.com/documentation/develop/firefox-builtin-data-consent/\nTo suppress this warning, set `suppressWarnings.firefoxDataCollection` to `true` in your wxt config.\n");
59
- if (wxt.config.browser === "firefox" && !manifest.browser_specific_settings?.gecko?.id && !wxt.config.suppressWarnings?.firefoxId) wxt.logger.warn("Firefox requires extension ID for MV3 and recommends it for MV2.\nFor more details, see: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings#id");
58
+ if (wxt.config.browser === "firefox" && !userManifest.browser_specific_settings?.gecko?.data_collection_permissions && !wxt.config.suppressWarnings?.firefoxDataCollection) wxt.logger.warnOnce("Firefox requires `data_collection_permissions` for new extensions from November 3, 2025. Existing extensions are exempt for now.\nFor more details, see: https://extensionworkshop.com/documentation/develop/firefox-builtin-data-consent/\nTo suppress this warning, set `suppressWarnings.firefoxDataCollection` to `true` in your wxt config.\n");
59
+ if (wxt.config.browser === "firefox" && !manifest.browser_specific_settings?.gecko?.id && !wxt.config.suppressWarnings?.firefoxId) wxt.logger.warnOnce("Firefox requires extension ID for MV3 and recommends it for MV2.\nFor more details, see: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings#id");
60
60
  addEntrypoints(manifest, entrypoints, buildOutput);
61
61
  if (wxt.config.browser === "firefox") addDiscoveredThemeIcons(manifest, buildOutput);
62
62
  if (wxt.config.command === "serve") addDevModeCsp(manifest);
@@ -190,7 +190,7 @@ function addEntrypoints(manifest, entrypoints, buildOutput) {
190
190
  return map;
191
191
  }, /* @__PURE__ */ new Map());
192
192
  const manifestContentScripts = Array.from(hashToEntrypointsMap.values()).map((scripts) => mapWxtOptionsToContentScript(scripts[0].options, scripts.map((entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".js")), getContentScriptCssFiles(scripts, cssMap)));
193
- if (manifestContentScripts.length >= 0) {
193
+ if (manifestContentScripts.length > 0) {
194
194
  manifest.content_scripts ??= [];
195
195
  manifest.content_scripts.push(...manifestContentScripts);
196
196
  }
@@ -284,7 +284,7 @@ function getContentScriptCssWebAccessibleResources(contentScripts, contentScript
284
284
  if (cssFile == null) return;
285
285
  resources.push({
286
286
  resources: [cssFile],
287
- use_dynamic_url: true,
287
+ ...wxt.config.browser !== "firefox" && wxt.config.browser !== "safari" ? { use_dynamic_url: true } : {},
288
288
  matches: script.options.matches?.map((matchPattern) => stripPathFromMatchPattern(matchPattern)) ?? []
289
289
  });
290
290
  });
@@ -0,0 +1,22 @@
1
+ import { dedupeDependencies, npm } from "./npm.mjs";
2
+ import { x } from "tinyexec";
3
+ //#region src/internal/package-managers/bun.ts
4
+ const bun = {
5
+ overridesKey: "overrides",
6
+ downloadDependency(...args) {
7
+ return npm.downloadDependency(...args);
8
+ },
9
+ async listDependencies(options) {
10
+ const args = ["pm", "ls"];
11
+ if (options?.all) args.push("--all");
12
+ return dedupeDependencies((await x("bun", args, {
13
+ throwOnError: true,
14
+ nodeOptions: { cwd: options?.cwd }
15
+ })).stdout.split("\n").slice(1).map((line) => line.trim()).map((line) => /.* (@?\S+)@(\S+)$/.exec(line)).filter((match) => !!match).map(([_, name, version]) => ({
16
+ name,
17
+ version
18
+ })));
19
+ }
20
+ };
21
+ //#endregion
22
+ export { bun };
@@ -1,4 +1,4 @@
1
- //#region src/core/package-managers/deno.ts
1
+ //#region src/internal/package-managers/deno.ts
2
2
  const deno = {
3
3
  overridesKey: "na",
4
4
  downloadDependency() {
@@ -4,7 +4,7 @@ import { yarn } from "./yarn.mjs";
4
4
  import { pnpm } from "./pnpm.mjs";
5
5
  import { deno } from "./deno.mjs";
6
6
  import { addDependency, addDevDependency, detectPackageManager, ensureDependencyInstalled, installDependencies, removeDependency } from "nypm";
7
- //#region src/core/package-managers/index.ts
7
+ //#region src/internal/package-managers/index.ts
8
8
  async function createWxtPackageManager(root) {
9
9
  const pm = await detectPackageManager(root, { includeParentDirs: true });
10
10
  const requirePm = (cb) => {
@@ -1,23 +1,29 @@
1
1
  import { mkdir } from "node:fs/promises";
2
2
  import path from "node:path";
3
- import spawn from "nano-spawn";
4
- //#region src/core/package-managers/npm.ts
3
+ import { x } from "tinyexec";
4
+ //#region src/internal/package-managers/npm.ts
5
5
  const npm = {
6
6
  overridesKey: "overrides",
7
7
  async downloadDependency(id, downloadDir) {
8
8
  await mkdir(downloadDir, { recursive: true });
9
- const res = await spawn("npm", [
9
+ const res = await x("npm", [
10
10
  "pack",
11
11
  id,
12
12
  "--json"
13
- ], { cwd: downloadDir });
13
+ ], {
14
+ throwOnError: true,
15
+ nodeOptions: { cwd: downloadDir }
16
+ });
14
17
  const packed = JSON.parse(res.stdout);
15
18
  return path.resolve(downloadDir, packed[0].filename);
16
19
  },
17
20
  async listDependencies(options) {
18
21
  const args = ["ls", "--json"];
19
22
  if (options?.all) args.push("--depth", "Infinity");
20
- const res = await spawn("npm", args, { cwd: options?.cwd });
23
+ const res = await x("npm", args, {
24
+ throwOnError: true,
25
+ nodeOptions: { cwd: options?.cwd }
26
+ });
21
27
  return flattenNpmListOutput([JSON.parse(res.stdout)]);
22
28
  }
23
29
  };
@@ -1,6 +1,6 @@
1
1
  import { flattenNpmListOutput, npm } from "./npm.mjs";
2
- import spawn from "nano-spawn";
3
- //#region src/core/package-managers/pnpm.ts
2
+ import { x } from "tinyexec";
3
+ //#region src/internal/package-managers/pnpm.ts
4
4
  const pnpm = {
5
5
  overridesKey: "resolutions",
6
6
  downloadDependency(...args) {
@@ -14,7 +14,10 @@ const pnpm = {
14
14
  ];
15
15
  if (options?.all) args.push("--depth", "Infinity");
16
16
  if (typeof process !== "undefined" && process.env.WXT_PNPM_IGNORE_WORKSPACE === "true") args.push("--ignore-workspace");
17
- const res = await spawn("pnpm", args, { cwd: options?.cwd });
17
+ const res = await x("pnpm", args, {
18
+ throwOnError: true,
19
+ nodeOptions: { cwd: options?.cwd }
20
+ });
18
21
  return flattenNpmListOutput(JSON.parse(res.stdout));
19
22
  }
20
23
  };
@@ -1,6 +1,6 @@
1
1
  import { dedupeDependencies, npm } from "./npm.mjs";
2
- import spawn from "nano-spawn";
3
- //#region src/core/package-managers/yarn.ts
2
+ import { x } from "tinyexec";
3
+ //#region src/internal/package-managers/yarn.ts
4
4
  const yarn = {
5
5
  overridesKey: "resolutions",
6
6
  downloadDependency(...args) {
@@ -9,7 +9,10 @@ const yarn = {
9
9
  async listDependencies(options) {
10
10
  const args = ["list", "--json"];
11
11
  if (options?.all) args.push("--depth", "Infinity");
12
- const tree = (await spawn("yarn", args, { cwd: options?.cwd })).stdout.split("\n").map((line) => JSON.parse(line)).find((line) => line.type === "tree")?.data;
12
+ const tree = (await x("yarn", args, {
13
+ throwOnError: true,
14
+ nodeOptions: { cwd: options?.cwd }
15
+ })).stdout.trimEnd().split("\n").map((line) => JSON.parse(line)).find((line) => line.type === "tree")?.data;
13
16
  if (tree == null) throw Error("'yarn list --json' did not output a tree");
14
17
  const queue = [...tree.trees];
15
18
  const dependencies = [];
@@ -1,7 +1,7 @@
1
- import { wxt } from "../wxt.mjs";
2
- import { readJson } from "./fs.mjs";
1
+ import { readJson } from "../internal-utils/fs-utils.mjs";
2
+ import { wxt } from "./wxt.mjs";
3
3
  import { resolve } from "node:path";
4
- //#region src/core/utils/package.ts
4
+ //#region src/internal/package.ts
5
5
  /**
6
6
  * Read the project's package.json.
7
7
  *
@@ -1,9 +1,9 @@
1
- import { wxt } from "../../wxt.mjs";
1
+ import { wxt } from "./wxt.mjs";
2
+ import { createSpinner } from "./spinner.mjs";
3
+ import { generateWxtDir } from "./generate-wxt-dir.mjs";
4
+ import { generateManifest, writeManifest } from "./manifest.mjs";
2
5
  import { buildEntrypoints } from "./build-entrypoints.mjs";
3
- import { generateWxtDir } from "../../generate-wxt-dir.mjs";
4
- import { generateManifest, writeManifest } from "../manifest.mjs";
5
- import { createSpinner } from "nanospinner";
6
- //#region src/core/utils/building/rebuild.ts
6
+ //#region src/internal/rebuild.ts
7
7
  /**
8
8
  * Given a configuration, list of entrypoints, and an existing, partial output,
9
9
  * build the entrypoints and merge the new output with the existing output.
@@ -1,23 +1,19 @@
1
- import { builtinModules } from "../builtin-modules/index.mjs";
2
- import { normalizePath } from "./utils/paths.mjs";
3
- import "./utils/index.mjs";
4
- import { createFsCache } from "./utils/cache.mjs";
5
- import { getEslintVersion } from "./utils/eslint.mjs";
6
- import { safeStringToNumber } from "./utils/number.mjs";
7
- import { loadEnv } from "./utils/env.mjs";
8
- import { createSafariRunner } from "./runners/safari.mjs";
9
- import { createWslRunner } from "./runners/wsl.mjs";
10
- import { createManualRunner } from "./runners/manual.mjs";
11
- import { pathExists } from "./utils/fs.mjs";
12
- import { glob } from "tinyglobby";
1
+ import { normalizePath } from "../internal-utils/path-utils.mjs";
2
+ import { builtinModules } from "./builtin-modules/index.mjs";
3
+ import { pathExists } from "../internal-utils/fs-utils.mjs";
4
+ import { createFsCache } from "../internal-utils/cache-utils.mjs";
5
+ import { getEslintVersion } from "../internal-utils/eslint-utils.mjs";
6
+ import { safeStringToNumber } from "../internal-utils/number-utils.mjs";
7
+ import { loadEnv } from "../internal-utils/env-utils.mjs";
8
+ import { v } from "../inline/get-port-please/index.mjs";
9
+ import { createWxtLogger } from "../internal-utils/log/wxt-logger.mjs";
13
10
  import path from "node:path";
11
+ import { glob } from "tinyglobby";
14
12
  import { loadConfig } from "c12";
15
13
  import consola, { LogLevels } from "consola";
16
14
  import defu from "defu";
17
- import { getPort } from "get-port-please";
18
- import { fileURLToPath, pathToFileURL } from "node:url";
19
- import isWsl from "is-wsl";
20
- //#region src/core/resolve-config.ts
15
+ import { fileURLToPath } from "node:url";
16
+ //#region src/internal/resolve-config.ts
21
17
  /**
22
18
  * Given an inline config, discover the config file if necessary, merge the
23
19
  * results, resolve any relative paths, and apply any defaults.
@@ -40,7 +36,7 @@ async function resolveConfig(inlineConfig, command) {
40
36
  }
41
37
  const mergedConfig = await mergeInlineConfig(inlineConfig, userConfig);
42
38
  const debug = mergedConfig.debug ?? false;
43
- const logger = mergedConfig.logger ?? consola;
39
+ const logger = createWxtLogger(mergedConfig.logger ?? consola);
44
40
  if (debug) logger.level = LogLevels.debug;
45
41
  const browser = mergedConfig.browser ?? "chrome";
46
42
  const targetBrowsers = mergedConfig.targetBrowsers ?? [];
@@ -93,12 +89,12 @@ async function resolveConfig(inlineConfig, command) {
93
89
  let port = mergedConfig.dev?.server?.port;
94
90
  const origin = mergedConfig.dev?.server?.origin ?? "localhost";
95
91
  const strictPort = mergedConfig.dev?.server?.strictPort ?? false;
96
- if (port == null || !isFinite(port)) port = await getPort({
92
+ if (port == null || !isFinite(port)) port = await v({
97
93
  host,
98
94
  port: 3e3,
99
95
  portRange: [3001, 3010]
100
96
  });
101
- else if (!strictPort) port = await getPort({
97
+ else if (!strictPort) port = await v({
102
98
  host,
103
99
  port
104
100
  });
@@ -141,7 +137,7 @@ async function resolveConfig(inlineConfig, command) {
141
137
  wxtModuleDir,
142
138
  root,
143
139
  webExt,
144
- runner: command === "serve" ? await resolveRunner(browser, logger, mergedConfig) : createManualRunner(),
140
+ runner: void 0,
145
141
  srcDir,
146
142
  typesDir,
147
143
  wxtDir,
@@ -341,17 +337,14 @@ async function getUnimportOptions(wxtDir, srcDir, logger, config) {
341
337
  return defu(config.imports ?? {}, defaultOptions);
342
338
  }
343
339
  async function getUnimportEslintOptions(logger, wxtDir, options) {
344
- const inlineEnabled = options === false ? false : options?.eslintrc?.enabled ?? "auto";
340
+ const inlineEnabled = options === false ? false : options?.eslintrc?.enabled ?? true;
345
341
  const version = await getEslintVersion();
346
342
  const major = parseInt(version[0]);
347
343
  let enabled;
348
344
  switch (inlineEnabled) {
349
- case "auto":
345
+ case "auto": logger.warn(`\`imports.eslintrc.enabled: "auto"\` is deprecated. Use \`true\` instead.`);
350
346
  case true:
351
- if (isNaN(major)) {
352
- if (inlineEnabled === true) logger.warn("Could not determine installed ESLint version, `eslint-auto-imports.mjs` not generated");
353
- enabled = false;
354
- } else if (major <= 8) enabled = 8;
347
+ if (major <= 8) enabled = 8;
355
348
  else if (major >= 9) enabled = 9;
356
349
  else enabled = false;
357
350
  break;
@@ -365,14 +358,14 @@ async function getUnimportEslintOptions(logger, wxtDir, options) {
365
358
  }
366
359
  /** Returns the path to `node_modules/wxt`. */
367
360
  function resolveWxtModuleDir() {
368
- const url = import.meta.resolve("wxt", import.meta.url);
361
+ const url = import.meta.resolve("wxt");
369
362
  return path.resolve(fileURLToPath(url), "../..");
370
363
  }
371
364
  async function isDirMissing(dir) {
372
365
  return !await pathExists(dir);
373
366
  }
374
367
  function logMissingDir(logger, name, expected) {
375
- logger.warn(`${name} directory not found: ./${normalizePath(path.relative(process.cwd(), expected))}`);
368
+ logger.warnOnce(`${name} directory not found: ./${normalizePath(path.relative(process.cwd(), expected))}`);
376
369
  }
377
370
  /** Map of `ConfigEnv` commands to their default modes. */
378
371
  const COMMAND_MODES = {
@@ -390,9 +383,8 @@ async function mergeBuilderConfig(logger, inlineConfig, userConfig) {
390
383
  throw Error("Builder not found. Make sure vite is installed.");
391
384
  }
392
385
  async function resolveWxtUserModules(root, modulesDir, modules = []) {
393
- const importer = pathToFileURL(path.join(root, "index.js")).href;
394
386
  const npmModules = await Promise.all(modules.map(async (moduleId) => {
395
- const mod = await import(import.meta.resolve(moduleId, importer));
387
+ const mod = await import(import.meta.resolve(moduleId));
396
388
  if (mod.default == null) throw Error("Module missing default export: " + moduleId);
397
389
  return {
398
390
  ...mod.default,
@@ -426,17 +418,5 @@ async function resolveWxtUserModules(root, modulesDir, modules = []) {
426
418
  }));
427
419
  return [...npmModules, ...localModules];
428
420
  }
429
- async function resolveRunner(browser, logger, mergedConfig) {
430
- if (browser === "safari") return createSafariRunner();
431
- if (isWsl) return createWslRunner();
432
- try {
433
- const { createWebExtRunner } = await import("./runners/web-ext.mjs");
434
- return mergedConfig.webExt?.disabled ? createManualRunner() : createWebExtRunner();
435
- } catch (err) {
436
- if (err?.code !== "ERR_MODULE_NOT_FOUND") throw err;
437
- logger.debug("Error loading the web-ext runner", err);
438
- }
439
- return createManualRunner();
440
- }
441
421
  //#endregion
442
422
  export { resolveConfig };
@@ -0,0 +1,22 @@
1
+ import { relative } from "node:path";
2
+ //#region src/internal/runners/manual.ts
3
+ /**
4
+ * Base runner that just tells developers to load the extension into their
5
+ * browser manually.
6
+ *
7
+ * You can extend this class and call any `super` method when your runner can't
8
+ * open the browser.
9
+ */
10
+ var ManualRunner = class {
11
+ constructor(config) {
12
+ this.config = config;
13
+ }
14
+ canOpen() {
15
+ return Promise.resolve(false);
16
+ }
17
+ async openBrowser() {
18
+ this.config.logger.info(`Load "${relative(process.cwd(), this.config.outDir)}" as an unpacked extension manually`);
19
+ }
20
+ };
21
+ //#endregion
22
+ export { ManualRunner };