wxt 0.21.0 → 0.21.1

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 (153) hide show
  1. package/README.md +0 -1
  2. package/bin/wxt-publish-extension.mjs +4 -3
  3. package/dist/browser.d.mts +7 -6
  4. package/dist/browser.mjs +6 -5
  5. package/dist/builtin-modules/favicon-permission.mjs +28 -0
  6. package/dist/builtin-modules/index.mjs +3 -4
  7. package/dist/builtin-modules/unimport.mjs +1 -3
  8. package/dist/cli/cli-utils.mjs +8 -9
  9. package/dist/cli/commands.mjs +1 -3
  10. package/dist/cli/index.mjs +1 -3
  11. package/dist/core/build.d.mts +9 -8
  12. package/dist/core/build.mjs +10 -11
  13. package/dist/core/builders/vite/index.mjs +123 -75
  14. package/dist/core/builders/vite/plugins/bundleAnalysis.mjs +1 -3
  15. package/dist/core/builders/vite/plugins/cssEntrypoints.mjs +6 -6
  16. package/dist/core/builders/vite/plugins/defineImportMeta.mjs +3 -4
  17. package/dist/core/builders/vite/plugins/devHtmlPrerender.mjs +34 -26
  18. package/dist/core/builders/vite/plugins/devServerGlobals.mjs +3 -3
  19. package/dist/core/builders/vite/plugins/entrypointGroupGlobals.mjs +2 -6
  20. package/dist/core/builders/vite/plugins/extensionApiMock.mjs +13 -8
  21. package/dist/core/builders/vite/plugins/globals.mjs +1 -3
  22. package/dist/core/builders/vite/plugins/iifeAnonymous.mjs +1 -2
  23. package/dist/core/builders/vite/plugins/iifeFooter.mjs +14 -7
  24. package/dist/core/builders/vite/plugins/index.mjs +17 -19
  25. package/dist/core/builders/vite/plugins/noopBackground.mjs +14 -9
  26. package/dist/core/builders/vite/plugins/removeEntrypointMainFunction.mjs +10 -12
  27. package/dist/core/builders/vite/plugins/resolveAppConfig.mjs +14 -10
  28. package/dist/core/builders/vite/plugins/resolveVirtualModules.mjs +15 -13
  29. package/dist/core/builders/vite/plugins/tsconfigPaths.mjs +1 -2
  30. package/dist/core/builders/vite/plugins/wxtPluginLoader.mjs +22 -17
  31. package/dist/core/clean.d.mts +3 -14
  32. package/dist/core/clean.mjs +19 -13
  33. package/dist/core/create-server.d.mts +6 -5
  34. package/dist/core/create-server.mjs +21 -117
  35. package/dist/core/define-config.mjs +1 -2
  36. package/dist/core/define-web-ext-config.d.mts +3 -6
  37. package/dist/core/define-web-ext-config.mjs +3 -12
  38. package/dist/core/generate-wxt-dir.mjs +53 -35
  39. package/dist/core/index.d.mts +3 -2
  40. package/dist/core/index.mjs +11 -11
  41. package/dist/core/initialize.mjs +28 -29
  42. package/dist/core/keyboard-shortcuts.mjs +4 -8
  43. package/dist/core/package-managers/bun.mjs +1 -3
  44. package/dist/core/package-managers/deno.mjs +1 -2
  45. package/dist/core/package-managers/index.mjs +1 -3
  46. package/dist/core/package-managers/npm.mjs +3 -5
  47. package/dist/core/package-managers/pnpm.mjs +1 -3
  48. package/dist/core/package-managers/yarn.mjs +1 -3
  49. package/dist/core/prepare.mjs +1 -3
  50. package/dist/core/resolve-config.mjs +63 -43
  51. package/dist/core/runners/manual.mjs +2 -6
  52. package/dist/core/runners/safari.mjs +3 -4
  53. package/dist/core/runners/web-ext.mjs +8 -11
  54. package/dist/core/runners/wsl.mjs +3 -4
  55. package/dist/core/utils/arrays.mjs +4 -11
  56. package/dist/core/utils/building/build-entrypoints.mjs +10 -11
  57. package/dist/core/utils/building/detect-dev-changes.mjs +37 -19
  58. package/dist/core/utils/building/find-entrypoints.mjs +40 -21
  59. package/dist/core/utils/building/group-entrypoints.mjs +3 -4
  60. package/dist/core/utils/building/index.mjs +7 -8
  61. package/dist/core/utils/building/internal-build.mjs +21 -21
  62. package/dist/core/utils/building/rebuild.mjs +10 -10
  63. package/dist/core/utils/cache.mjs +6 -8
  64. package/dist/core/utils/constants.mjs +3 -4
  65. package/dist/core/utils/content-scripts.mjs +3 -4
  66. package/dist/core/utils/content-security-policy.mjs +2 -5
  67. package/dist/core/utils/create-file-reloader.mjs +158 -0
  68. package/dist/core/utils/entrypoints.d.mts +10 -0
  69. package/dist/core/utils/entrypoints.mjs +6 -10
  70. package/dist/core/utils/env.mjs +24 -19
  71. package/dist/core/utils/environments/browser-environment.mjs +1 -3
  72. package/dist/core/utils/environments/environment.mjs +1 -2
  73. package/dist/core/utils/environments/extension-environment.mjs +1 -3
  74. package/dist/core/utils/environments/index.mjs +3 -4
  75. package/dist/core/utils/eslint.mjs +1 -2
  76. package/dist/core/utils/fs.mjs +23 -14
  77. package/dist/core/utils/globals.mjs +1 -2
  78. package/dist/core/utils/i18n.mjs +2 -3
  79. package/dist/core/utils/index.d.mts +2 -0
  80. package/dist/core/utils/index.mjs +3 -3
  81. package/dist/core/utils/log/index.mjs +5 -6
  82. package/dist/core/utils/log/printBuildSummary.mjs +1 -3
  83. package/dist/core/utils/log/printFileList.mjs +25 -21
  84. package/dist/core/utils/log/printHeader.mjs +3 -5
  85. package/dist/core/utils/log/printTable.mjs +1 -2
  86. package/dist/core/utils/manifest.mjs +39 -46
  87. package/dist/core/utils/number.mjs +1 -2
  88. package/dist/core/utils/package.mjs +3 -5
  89. package/dist/core/utils/paths.d.mts +2 -2
  90. package/dist/core/utils/paths.mjs +7 -9
  91. package/dist/core/utils/strings.mjs +4 -7
  92. package/dist/core/utils/syntax-errors.mjs +3 -5
  93. package/dist/core/utils/theme-icons.mjs +71 -0
  94. package/dist/core/utils/time.mjs +1 -13
  95. package/dist/core/utils/transform.mjs +9 -7
  96. package/dist/core/utils/validation.mjs +1 -2
  97. package/dist/core/utils/virtual-modules.mjs +9 -15
  98. package/dist/core/wxt.mjs +11 -12
  99. package/dist/core/zip.d.mts +1 -0
  100. package/dist/core/zip.mjs +25 -20
  101. package/dist/index.d.mts +4 -4
  102. package/dist/index.mjs +3 -3
  103. package/dist/modules.d.mts +64 -61
  104. package/dist/modules.mjs +70 -66
  105. package/dist/testing/fake-browser.mjs +1 -2
  106. package/dist/testing/wxt-vitest-plugin.d.mts +4 -2
  107. package/dist/testing/wxt-vitest-plugin.mjs +5 -7
  108. package/dist/types.d.mts +636 -450
  109. package/dist/utils/app-config.d.mts +1 -0
  110. package/dist/utils/app-config.mjs +3 -3
  111. package/dist/utils/content-script-context.d.mts +49 -39
  112. package/dist/utils/content-script-context.mjs +37 -32
  113. package/dist/utils/content-script-ui/iframe.d.mts +14 -15
  114. package/dist/utils/content-script-ui/iframe.mjs +1 -3
  115. package/dist/utils/content-script-ui/integrated.d.mts +8 -7
  116. package/dist/utils/content-script-ui/integrated.mjs +1 -3
  117. package/dist/utils/content-script-ui/shadow-root.d.mts +37 -25
  118. package/dist/utils/content-script-ui/shadow-root.mjs +5 -8
  119. package/dist/utils/content-script-ui/shared.mjs +1 -3
  120. package/dist/utils/content-script-ui/types.d.mts +29 -34
  121. package/dist/utils/content-script-ui/types.mjs +1 -1
  122. package/dist/utils/define-app-config.d.mts +4 -3
  123. package/dist/utils/define-app-config.mjs +5 -5
  124. package/dist/utils/define-background.mjs +1 -2
  125. package/dist/utils/define-content-script.mjs +1 -2
  126. package/dist/utils/define-unlisted-script.mjs +1 -2
  127. package/dist/utils/define-wxt-plugin.mjs +1 -2
  128. package/dist/utils/inject-script.d.mts +2 -2
  129. package/dist/utils/inject-script.mjs +4 -5
  130. package/dist/utils/internal/custom-events.mjs +3 -4
  131. package/dist/utils/internal/location-watcher.mjs +4 -6
  132. package/dist/utils/internal/logger.mjs +2 -5
  133. package/dist/utils/match-patterns.mjs +2 -3
  134. package/dist/utils/split-shadow-root-css.d.mts +6 -2
  135. package/dist/utils/split-shadow-root-css.mjs +7 -4
  136. package/dist/utils/storage.mjs +2 -3
  137. package/dist/version.mjs +2 -3
  138. package/dist/virtual/background-entrypoint.mjs +4 -16
  139. package/dist/virtual/content-script-isolated-world-entrypoint.mjs +2 -7
  140. package/dist/virtual/content-script-main-world-entrypoint.mjs +2 -7
  141. package/dist/virtual/mock-browser.d.mts +1 -1
  142. package/dist/virtual/mock-browser.mjs +2 -4
  143. package/dist/virtual/reload-html.mjs +3 -10
  144. package/dist/virtual/unlisted-script-entrypoint.mjs +2 -7
  145. package/package.json +56 -49
  146. package/LICENSE +0 -21
  147. package/dist/core/builders/vite/plugins/download.mjs +0 -25
  148. package/dist/core/runners/index.mjs +0 -17
  149. package/dist/core/utils/minimatch-multiple.mjs +0 -28
  150. package/dist/core/utils/network.mjs +0 -38
  151. package/dist/core/utils/wsl.mjs +0 -12
  152. package/dist/testing/index.d.mts +0 -3
  153. package/dist/testing/index.mjs +0 -4
@@ -1,31 +1,21 @@
1
1
  import { unnormalizePath } from "./utils/paths.mjs";
2
- import { getEntrypointBundlePath, isHtmlEntrypoint } from "./utils/entrypoints.mjs";
3
2
  import { deinitWxtModules, initWxtModules, registerWxt, wxt } from "./wxt.mjs";
4
- import { detectDevChanges } from "./utils/building/detect-dev-changes.mjs";
5
- import { findEntrypoints } from "./utils/building/find-entrypoints.mjs";
6
- import { getContentScriptJs, mapWxtOptionsToRegisteredContentScript } from "./utils/content-scripts.mjs";
7
- import { getContentScriptCssFiles, getContentScriptsCssMap } from "./utils/manifest.mjs";
8
- import { rebuild } from "./utils/building/rebuild.mjs";
9
3
  import { internalBuild } from "./utils/building/internal-build.mjs";
10
4
  import "./utils/building/index.mjs";
11
- import { createExtensionRunner } from "./runners/index.mjs";
12
5
  import { createKeyboardShortcuts } from "./keyboard-shortcuts.mjs";
13
6
  import { isBabelSyntaxError, logBabelSyntaxError } from "./utils/syntax-errors.mjs";
14
- import { relative } from "node:path";
15
- import pc from "picocolors";
16
- import { debounce } from "perfect-debounce";
7
+ import { createFileReloader, reloadContentScripts } from "./utils/create-file-reloader.mjs";
17
8
  import chokidar from "chokidar";
18
- import { Mutex } from "async-mutex";
19
-
20
9
  //#region src/core/create-server.ts
21
10
  /**
22
- * Creates a dev server and pre-builds all the files that need to exist before loading the extension.
11
+ * Creates a dev server and pre-builds all the files that need to exist before
12
+ * loading the extension.
23
13
  *
24
14
  * @example
25
- * const server = await wxt.createServer({
26
- * // Enter config...
27
- * });
28
- * await server.start();
15
+ * const server = await wxt.createServer({
16
+ * // Enter config...
17
+ * });
18
+ * await server.start();
29
19
  */
30
20
  async function createServer(inlineConfig) {
31
21
  await registerWxt("serve", inlineConfig);
@@ -42,7 +32,7 @@ async function createServerInternal() {
42
32
  origin
43
33
  };
44
34
  };
45
- let [runner, builderServer] = await Promise.all([createExtensionRunner(), wxt.builder.createServer(getServerInfo())]);
35
+ let builderServer = await wxt.builder.createServer(getServerInfo());
46
36
  let wasStopped = false;
47
37
  const server = {
48
38
  get host() {
@@ -64,7 +54,6 @@ async function createServerInternal() {
64
54
  async start() {
65
55
  if (wasStopped) {
66
56
  await wxt.reloadConfig();
67
- runner = await createExtensionRunner();
68
57
  builderServer = await wxt.builder.createServer(getServerInfo());
69
58
  await initWxtModules();
70
59
  }
@@ -80,14 +69,12 @@ async function createServerInternal() {
80
69
  const reloadOnChange = createFileReloader(server);
81
70
  server.watcher.on("all", async (...args) => {
82
71
  await reloadOnChange(args[0], args[1]);
83
- keyboardShortcuts.start();
84
72
  });
85
- keyboardShortcuts.printHelp({ canReopenBrowser: !wxt.config.runnerConfig.config.disabled && !!runner.canOpen?.() });
86
73
  },
87
74
  async stop() {
88
75
  wasStopped = true;
89
76
  keyboardShortcuts.stop();
90
- await runner.closeBrowser?.();
77
+ await wxt.config.runner.closeBrowser?.();
91
78
  await builderServer.close();
92
79
  await wxt.hooks.callHook("server:closed", wxt, server);
93
80
  deinitWxtModules();
@@ -110,12 +97,12 @@ async function createServerInternal() {
110
97
  server.ws.send("wxt:reload-extension");
111
98
  },
112
99
  async restartBrowser() {
113
- await runner.closeBrowser?.();
100
+ await wxt.config.runner.closeBrowser?.();
114
101
  keyboardShortcuts.stop();
115
102
  await wxt.reloadConfig();
116
- runner = await createExtensionRunner();
117
- await runner.openBrowser();
103
+ await wxt.config.runner.openBrowser();
118
104
  keyboardShortcuts.start();
105
+ keyboardShortcuts.printHelp({ canReopenBrowser: !wxt.config.webExt.config.disabled && !!wxt.config.runner.canOpen?.() });
119
106
  }
120
107
  };
121
108
  const keyboardShortcuts = createKeyboardShortcuts(server);
@@ -127,7 +114,10 @@ async function createServerInternal() {
127
114
  logBabelSyntaxError(err);
128
115
  wxt.logger.info("Waiting for syntax error to be fixed...");
129
116
  await new Promise((resolve) => {
130
- const watcher = chokidar.watch(err.id, { ignoreInitial: true });
117
+ const watcher = chokidar.watch(err.id, {
118
+ ...wxt.config.watchOptions,
119
+ ignoreInitial: true
120
+ });
131
121
  watcher.on("all", () => {
132
122
  watcher.close();
133
123
  wxt.logger.info("Syntax error resolved, rebuilding...");
@@ -141,101 +131,16 @@ async function createServerInternal() {
141
131
  } catch (err) {
142
132
  wxt.config.logger.warn("Failed to register additional file paths:", err);
143
133
  }
144
- await runner.openBrowser();
134
+ await wxt.config.runner.openBrowser();
135
+ keyboardShortcuts.start();
136
+ keyboardShortcuts.printHelp({ canReopenBrowser: !wxt.config.webExt.config.disabled && !!wxt.config.runner.canOpen?.() });
145
137
  };
146
138
  builderServer.on?.("close", () => keyboardShortcuts.stop());
147
139
  return server;
148
140
  }
149
141
  /**
150
- * Returns a function responsible for reloading different parts of the extension when a file
151
- * changes.
152
- */
153
- function createFileReloader(server) {
154
- const fileChangedMutex = new Mutex();
155
- const changeQueue = [];
156
- const cb = async (event, path) => {
157
- changeQueue.push([event, path]);
158
- await fileChangedMutex.runExclusive(async () => {
159
- if (server.currentOutput == null) return;
160
- const fileChanges = changeQueue.splice(0, changeQueue.length).map(([_, file]) => file);
161
- if (fileChanges.length === 0) return;
162
- await wxt.reloadConfig();
163
- const changes = detectDevChanges(fileChanges, server.currentOutput);
164
- if (changes.type === "no-change") return;
165
- if (changes.type === "full-restart") {
166
- wxt.logger.info("Config changed, restarting server...");
167
- server.restart();
168
- return;
169
- }
170
- if (changes.type === "browser-restart") {
171
- wxt.logger.info("Runner config changed, restarting browser...");
172
- server.restartBrowser();
173
- return;
174
- }
175
- wxt.logger.info(`Changed: ${Array.from(new Set(fileChanges)).map((file) => pc.dim(relative(wxt.config.root, file))).join(", ")}`);
176
- const allEntrypoints = await findEntrypoints();
177
- try {
178
- const { output: newOutput } = await rebuild(allEntrypoints, changes.rebuildGroups, changes.cachedOutput);
179
- server.currentOutput = newOutput;
180
- switch (changes.type) {
181
- case "extension-reload":
182
- server.reloadExtension();
183
- wxt.logger.success(`Reloaded extension`);
184
- break;
185
- case "html-reload":
186
- const { reloadedNames } = reloadHtmlPages(changes.rebuildGroups, server);
187
- wxt.logger.success(`Reloaded: ${getFilenameList(reloadedNames)}`);
188
- break;
189
- case "content-script-reload":
190
- reloadContentScripts(changes.changedSteps, server);
191
- const rebuiltNames = changes.rebuildGroups.flat().map((entry) => entry.name);
192
- wxt.logger.success(`Reloaded: ${getFilenameList(rebuiltNames)}`);
193
- break;
194
- }
195
- } catch {}
196
- }).catch((error) => {
197
- if (!isBabelSyntaxError(error)) throw error;
198
- logBabelSyntaxError(error);
199
- });
200
- };
201
- return debounce(cb, wxt.config.dev.server.watchDebounce, {
202
- leading: true,
203
- trailing: false
204
- });
205
- }
206
- /**
207
- * From the server, tell the client to reload content scripts from the provided build step outputs.
208
- */
209
- function reloadContentScripts(steps, server) {
210
- if (wxt.config.manifestVersion === 3) steps.forEach((step) => {
211
- if (server.currentOutput == null) return;
212
- const entry = step.entrypoints;
213
- if (Array.isArray(entry) || entry.type !== "content-script") return;
214
- const js = getContentScriptJs(wxt.config, entry);
215
- const cssMap = getContentScriptsCssMap(server.currentOutput, [entry]);
216
- const css = getContentScriptCssFiles([entry], cssMap);
217
- server.reloadContentScript({
218
- registration: entry.options.registration,
219
- contentScript: mapWxtOptionsToRegisteredContentScript(entry.options, js, css)
220
- });
221
- });
222
- else server.reloadExtension();
223
- }
224
- function reloadHtmlPages(groups, server) {
225
- const htmlEntries = groups.flat().filter(isHtmlEntrypoint);
226
- htmlEntries.forEach((entry) => {
227
- const path = getEntrypointBundlePath(entry, wxt.config.outDir, ".html");
228
- server.reloadPage(path);
229
- });
230
- return { reloadedNames: htmlEntries.map((entry) => entry.name) };
231
- }
232
- function getFilenameList(names) {
233
- return names.map((name) => {
234
- return pc.cyan(name);
235
- }).join(pc.dim(", "));
236
- }
237
- /**
238
142
  * Based on the current build output, return a list of files that are:
143
+ *
239
144
  * 1. Not in node_modules
240
145
  * 2. Not inside project root
241
146
  */
@@ -248,6 +153,5 @@ function getExternalOutputDependencies(server) {
248
153
  });
249
154
  }).filter((file) => !file.includes("node_modules") && !file.startsWith("\0")).map(unnormalizePath).filter((file) => !file.startsWith(wxt.config.root)) ?? [];
250
155
  }
251
-
252
156
  //#endregion
253
- export { createServer };
157
+ export { createServer };
@@ -2,6 +2,5 @@
2
2
  function defineConfig(config) {
3
3
  return config;
4
4
  }
5
-
6
5
  //#endregion
7
- export { defineConfig };
6
+ export { defineConfig };
@@ -2,12 +2,9 @@ import { WebExtConfig } from "../types.mjs";
2
2
 
3
3
  //#region src/core/define-web-ext-config.d.ts
4
4
  /**
5
- * @deprecated Use `defineWebExtConfig` instead. Same function, different name.
6
- */
7
- declare function defineRunnerConfig(config: WebExtConfig): WebExtConfig;
8
- /**
9
- * Configure how [`web-ext`](https://github.com/mozilla/web-ext) starts the browser during development.
5
+ * Configure how [`web-ext`](https://github.com/mozilla/web-ext) starts the
6
+ * browser during development.
10
7
  */
11
8
  declare function defineWebExtConfig(config: WebExtConfig): WebExtConfig;
12
9
  //#endregion
13
- export { defineRunnerConfig, defineWebExtConfig };
10
+ export { defineWebExtConfig };
@@ -1,19 +1,10 @@
1
- import consola from "consola";
2
-
3
1
  //#region src/core/define-web-ext-config.ts
4
2
  /**
5
- * @deprecated Use `defineWebExtConfig` instead. Same function, different name.
6
- */
7
- function defineRunnerConfig(config) {
8
- consola.warn("`defineRunnerConfig` is deprecated, use `defineWebExtConfig` instead. See https://wxt.dev/guide/resources/upgrading.html#v0-19-0-rarr-v0-20-0");
9
- return defineWebExtConfig(config);
10
- }
11
- /**
12
- * Configure how [`web-ext`](https://github.com/mozilla/web-ext) starts the browser during development.
3
+ * Configure how [`web-ext`](https://github.com/mozilla/web-ext) starts the
4
+ * browser during development.
13
5
  */
14
6
  function defineWebExtConfig(config) {
15
7
  return config;
16
8
  }
17
-
18
9
  //#endregion
19
- export { defineRunnerConfig, defineWebExtConfig };
10
+ export { defineWebExtConfig };
@@ -1,19 +1,19 @@
1
1
  import { normalizePath } from "./utils/paths.mjs";
2
- import "./utils/index.mjs";
3
2
  import { getEntrypointBundlePath, isHtmlEntrypoint } from "./utils/entrypoints.mjs";
3
+ import "./utils/index.mjs";
4
4
  import { getEntrypointGlobals, getGlobals } from "./utils/globals.mjs";
5
5
  import { wxt } from "./wxt.mjs";
6
- import { getPublicFiles, writeFileIfDifferent } from "./utils/fs.mjs";
6
+ import { getPublicFiles, pathExists, writeFileIfDifferent } from "./utils/fs.mjs";
7
7
  import { parseI18nMessages } from "./utils/i18n.mjs";
8
- import fs from "fs-extra";
8
+ import { mkdir, readFile } from "node:fs/promises";
9
9
  import path, { dirname, relative, resolve } from "node:path";
10
-
11
10
  //#region src/core/generate-wxt-dir.ts
12
11
  /**
13
- * Generate and write all the files inside the `InternalConfig.typesDir` directory.
12
+ * Generate and write all the files inside the `InternalConfig.typesDir`
13
+ * directory.
14
14
  */
15
15
  async function generateWxtDir(entrypoints) {
16
- await fs.ensureDir(wxt.config.typesDir);
16
+ await mkdir(wxt.config.typesDir, { recursive: true });
17
17
  const entries = [{ module: "wxt/vite-builder-env" }];
18
18
  wxt.config.userModules.forEach((module) => {
19
19
  if (module.type === "node_module") entries.push({ module: module.id });
@@ -29,7 +29,7 @@ async function generateWxtDir(entrypoints) {
29
29
  path: resolve(wxt.config.wxtDir, entry.path)
30
30
  }));
31
31
  await Promise.all(absoluteFileEntries.map(async (file) => {
32
- await fs.ensureDir(dirname(file.path));
32
+ await mkdir(dirname(file.path), { recursive: true });
33
33
  await writeFileIfDifferent(file.path, file.text);
34
34
  }));
35
35
  }
@@ -39,7 +39,7 @@ async function getPathsDeclarationEntry(entrypoints) {
39
39
  const unions = [
40
40
  ` | ""`,
41
41
  ` | "/"`,
42
- ...paths.map(normalizePath).sort().map((path) => ` | "/${path}"`)
42
+ ...paths.map(normalizePublicPathEntry).sort((a, b) => a.path.localeCompare(b.path) || a.type.localeCompare(b.type)).map(renderPublicPathUnionMember)
43
43
  ].join("\n");
44
44
  return {
45
45
  path: "types/paths.d.ts",
@@ -59,6 +59,23 @@ declare module "wxt/browser" {
59
59
  tsReference: true
60
60
  };
61
61
  }
62
+ function normalizePublicPathEntry(entry) {
63
+ if (typeof entry === "string") return {
64
+ type: "string",
65
+ path: normalizePath(entry)
66
+ };
67
+ return {
68
+ type: entry.type,
69
+ path: normalizePath(entry.path)
70
+ };
71
+ }
72
+ function renderPublicPathUnionMember(entry) {
73
+ const path = entry.path.startsWith("/") ? entry.path : `/${entry.path}`;
74
+ switch (entry.type) {
75
+ case "templateLiteral": return ` | \`${path}\``;
76
+ case "string": return ` | "${path}"`;
77
+ }
78
+ }
62
79
  function getEntrypointPublicExt(entry) {
63
80
  if (isHtmlEntrypoint(entry)) return ".html";
64
81
  switch (entry.type) {
@@ -90,7 +107,7 @@ declare module "wxt/browser" {
90
107
  `;
91
108
  const defaultLocalePath = path.resolve(wxt.config.publicDir, "_locales", defaultLocale ?? "", "messages.json");
92
109
  let messages;
93
- if (await fs.pathExists(defaultLocalePath)) messages = parseI18nMessages(JSON.parse(await fs.readFile(defaultLocalePath, "utf-8")));
110
+ if (await pathExists(defaultLocalePath)) messages = parseI18nMessages(JSON.parse(await readFile(defaultLocalePath, "utf-8")));
94
111
  else messages = parseI18nMessages({});
95
112
  const renderGetMessageOverload = (keyType, description, translation) => {
96
113
  const commentLines = [];
@@ -150,34 +167,35 @@ async function getTsConfigEntry() {
150
167
  if (res.startsWith(".") || res.startsWith("/")) return res;
151
168
  return "./" + res;
152
169
  };
170
+ const tsconfig = {
171
+ compilerOptions: {
172
+ lib: [
173
+ "ESNext",
174
+ "DOM",
175
+ "DOM.Iterable"
176
+ ],
177
+ target: "ESNext",
178
+ module: "Preserve",
179
+ moduleDetection: "force",
180
+ moduleResolution: "Bundler",
181
+ allowImportingTsExtensions: true,
182
+ verbatimModuleSyntax: true,
183
+ noEmit: true,
184
+ strict: true,
185
+ skipLibCheck: true,
186
+ noFallthroughCasesInSwitch: true,
187
+ noUncheckedIndexedAccess: true,
188
+ noImplicitOverride: true,
189
+ paths: Object.fromEntries(Object.entries(wxt.config.alias).map(([alias, absolutePath]) => [alias, getTsconfigPath(absolutePath)]).flatMap(([alias, path]) => [[alias, [path]], [alias + "/*", [path + "/*"]]]))
190
+ },
191
+ include: [`${getTsconfigPath(wxt.config.root)}/**/*`, "./wxt.d.ts"],
192
+ exclude: [getTsconfigPath(wxt.config.root) + "/**/node_modules", getTsconfigPath(wxt.config.outBaseDir)]
193
+ };
194
+ await wxt.hooks.callHook("prepare:tsconfig", wxt, { tsconfig });
153
195
  return {
154
196
  path: "tsconfig.json",
155
- text: `{
156
- "compilerOptions": {
157
- "target": "ESNext",
158
- "module": "ESNext",
159
- "moduleResolution": "Bundler",
160
- "noEmit": true,
161
- "esModuleInterop": true,
162
- "forceConsistentCasingInFileNames": true,
163
- "resolveJsonModule": true,
164
- "strict": true,
165
- "skipLibCheck": true,
166
- "paths": {
167
- ${Object.entries(wxt.config.alias).flatMap(([alias, absolutePath]) => {
168
- const aliasPath = getTsconfigPath(absolutePath);
169
- return [`"${alias}": ["${aliasPath}"]`, `"${alias}/*": ["${aliasPath}/*"]`];
170
- }).map((line) => ` ${line}`).join(",\n")}
171
- }
172
- },
173
- "include": [
174
- "${getTsconfigPath(wxt.config.root)}/**/*",
175
- "./wxt.d.ts"
176
- ],
177
- "exclude": ["${getTsconfigPath(wxt.config.outBaseDir)}"]
178
- }`
197
+ text: JSON.stringify(tsconfig, null, 2)
179
198
  };
180
199
  }
181
-
182
200
  //#endregion
183
- export { generateWxtDir };
201
+ export { generateWxtDir };
@@ -1,9 +1,10 @@
1
1
  import { build } from "./build.mjs";
2
2
  import { clean } from "./clean.mjs";
3
3
  import { defineConfig } from "./define-config.mjs";
4
- import { defineRunnerConfig, defineWebExtConfig } from "./define-web-ext-config.mjs";
4
+ import { defineWebExtConfig } from "./define-web-ext-config.mjs";
5
5
  import { createServer } from "./create-server.mjs";
6
6
  import { initialize } from "./initialize.mjs";
7
7
  import { prepare } from "./prepare.mjs";
8
8
  import { zip } from "./zip.mjs";
9
- import { normalizePath } from "./utils/paths.mjs";
9
+ import { normalizePath } from "./utils/paths.mjs";
10
+ import { getEntrypointBundlePath } from "./utils/entrypoints.mjs";
@@ -1,12 +1,12 @@
1
- import { normalizePath } from "./utils/paths.mjs";
1
+ import "./utils/paths.mjs";
2
+ import "./utils/entrypoints.mjs";
2
3
  import "./utils/index.mjs";
3
- import { build } from "./build.mjs";
4
- import { clean } from "./clean.mjs";
5
- import { defineConfig } from "./define-config.mjs";
6
- import { defineRunnerConfig, defineWebExtConfig } from "./define-web-ext-config.mjs";
7
- import { createServer } from "./create-server.mjs";
8
- import { initialize } from "./initialize.mjs";
9
- import { prepare } from "./prepare.mjs";
10
- import { zip } from "./zip.mjs";
11
-
12
- export { };
4
+ import "./build.mjs";
5
+ import "./clean.mjs";
6
+ import "./define-config.mjs";
7
+ import "./define-web-ext-config.mjs";
8
+ import "./create-server.mjs";
9
+ import "./initialize.mjs";
10
+ import "./prepare.mjs";
11
+ import "./zip.mjs";
12
+ export {};
@@ -1,10 +1,10 @@
1
- import fs from "fs-extra";
1
+ import { pathExists } from "./utils/fs.mjs";
2
+ import { readdir, rename } from "node:fs/promises";
2
3
  import path from "node:path";
3
4
  import { consola as consola$1 } from "consola";
4
- import pc from "picocolors";
5
+ import { styleText } from "node:util";
5
6
  import prompts from "prompts";
6
7
  import { downloadTemplate } from "giget";
7
-
8
8
  //#region src/core/initialize.ts
9
9
  async function initialize(options) {
10
10
  consola$1.info("Initializing new project");
@@ -22,7 +22,7 @@ async function initialize(options) {
22
22
  type: () => defaultTemplate == null ? "select" : void 0,
23
23
  message: "Choose a template",
24
24
  choices: templates.map((template) => ({
25
- title: TEMPLATE_COLORS[template.name]?.(template.name) ?? template.name,
25
+ title: TEMPLATE_COLORS[template.name] ? styleText(TEMPLATE_COLORS[template.name], template.name) : template.name,
26
26
  value: template
27
27
  }))
28
28
  },
@@ -32,29 +32,29 @@ async function initialize(options) {
32
32
  message: "Package Manager",
33
33
  choices: [
34
34
  {
35
- title: pc.red("npm"),
35
+ title: styleText("magenta", "bun"),
36
+ value: "bun"
37
+ },
38
+ {
39
+ title: styleText("red", "npm"),
36
40
  value: "npm"
37
41
  },
38
42
  {
39
- title: pc.yellow("pnpm"),
43
+ title: styleText("yellow", "pnpm"),
40
44
  value: "pnpm"
41
45
  },
42
46
  {
43
- title: pc.cyan("yarn"),
47
+ title: styleText("cyan", "yarn"),
44
48
  value: "yarn"
45
- },
46
- {
47
- title: pc.magenta("bun"),
48
- value: "bun"
49
49
  }
50
50
  ]
51
51
  }
52
52
  ], { onCancel: () => process.exit(1) });
53
- input.directory ??= options.directory;
53
+ input.directory ||= options.directory || ".";
54
54
  input.template ??= defaultTemplate;
55
55
  input.packageManager ??= options.packageManager;
56
- if (await fs.pathExists(input.directory)) {
57
- if (!((await fs.readdir(input.directory)).filter((dir) => dir !== ".git").length === 0)) {
56
+ if (await pathExists(input.directory)) {
57
+ if (!((await readdir(input.directory)).filter((dir) => dir !== ".git").length === 0)) {
58
58
  consola$1.error(`The directory ${path.resolve(input.directory)} is not empty. Aborted.`);
59
59
  process.exit(1);
60
60
  }
@@ -62,12 +62,12 @@ async function initialize(options) {
62
62
  await cloneProject(input);
63
63
  const cdPath = path.relative(process.cwd(), path.resolve(input.directory));
64
64
  console.log();
65
- consola$1.log(`✨ WXT project created with the ${TEMPLATE_COLORS[input.template.name]?.(input.template.name) ?? input.template.name} template.`);
65
+ consola$1.log(`✨ WXT project created with the ${TEMPLATE_COLORS[input.template.name] ? styleText(TEMPLATE_COLORS[input.template.name], input.template.name) : input.template.name} template.`);
66
66
  console.log();
67
67
  consola$1.log("Next steps:");
68
68
  let step = 0;
69
- if (cdPath !== "") consola$1.log(` ${++step}.`, pc.cyan(`cd ${cdPath}`));
70
- consola$1.log(` ${++step}.`, pc.cyan(`${input.packageManager} install`));
69
+ if (cdPath !== "") consola$1.log(` ${++step}.`, styleText("cyan", `cd ${cdPath}`));
70
+ consola$1.log(` ${++step}.`, styleText("cyan", `${input.packageManager} install`));
71
71
  console.log();
72
72
  }
73
73
  async function listTemplates() {
@@ -94,26 +94,26 @@ async function listTemplatesGithub() {
94
94
  return await res.json();
95
95
  }
96
96
  async function cloneProject({ directory, template }) {
97
- const { default: ora } = await import("ora");
98
- const spinner = ora("Downloading template").start();
97
+ const { createSpinner } = await import("nanospinner");
98
+ const spinner = createSpinner("Downloading template").start();
99
99
  try {
100
100
  await downloadTemplate(`gh:${REPO}/${template.path}`, {
101
101
  dir: directory,
102
102
  force: true
103
103
  });
104
- await fs.move(path.join(directory, "_gitignore"), path.join(directory, ".gitignore")).catch((err) => consola$1.warn("Failed to move _gitignore to .gitignore:", err));
105
- spinner.succeed();
104
+ await rename(path.join(directory, "_gitignore"), path.join(directory, ".gitignore")).catch((err) => consola$1.warn("Failed to move _gitignore to .gitignore:", err));
105
+ spinner.success();
106
106
  } catch (err) {
107
- spinner.fail();
107
+ spinner.error();
108
108
  throw Error(`Failed to setup new project: ${JSON.stringify(err, null, 2)}`);
109
109
  }
110
110
  }
111
111
  const TEMPLATE_COLORS = {
112
- vanilla: pc.blue,
113
- vue: pc.green,
114
- react: pc.cyan,
115
- svelte: pc.red,
116
- solid: pc.blue
112
+ vanilla: "blue",
113
+ vue: "green",
114
+ react: "cyan",
115
+ svelte: "red",
116
+ solid: "blue"
117
117
  };
118
118
  const TEMPLATE_SORT_WEIGHT = {
119
119
  vanilla: 0,
@@ -121,6 +121,5 @@ const TEMPLATE_SORT_WEIGHT = {
121
121
  react: 2
122
122
  };
123
123
  const REPO = "wxt-dev/wxt";
124
-
125
124
  //#endregion
126
- export { initialize };
125
+ export { initialize };
@@ -1,11 +1,8 @@
1
1
  import { wxt } from "./wxt.mjs";
2
- import pc from "picocolors";
2
+ import { styleText } from "node:util";
3
3
  import readline from "node:readline";
4
-
5
4
  //#region src/core/keyboard-shortcuts.ts
6
- /**
7
- * Function that creates a keyboard shortcut handler for the extension.
8
- */
5
+ /** Function that creates a keyboard shortcut handler for the extension. */
9
6
  function createKeyboardShortcuts(server) {
10
7
  let rl;
11
8
  const handleInput = (line) => {
@@ -24,10 +21,9 @@ function createKeyboardShortcuts(server) {
24
21
  rl?.removeListener("line", handleInput);
25
22
  },
26
23
  printHelp(flags) {
27
- if (flags.canReopenBrowser) wxt.logger.info(`${pc.dim("Press")} ${pc.bold("o + enter")} ${pc.dim("to reopen the browser")}`);
24
+ if (flags.canReopenBrowser) wxt.logger.info(`${styleText("dim", "Press")} ${styleText("bold", "o + enter")} ${styleText("dim", "to reopen the browser")}`);
28
25
  }
29
26
  };
30
27
  }
31
-
32
28
  //#endregion
33
- export { createKeyboardShortcuts };
29
+ export { createKeyboardShortcuts };
@@ -1,6 +1,5 @@
1
1
  import { dedupeDependencies, npm } from "./npm.mjs";
2
2
  import spawn from "nano-spawn";
3
-
4
3
  //#region src/core/package-managers/bun.ts
5
4
  const bun = {
6
5
  overridesKey: "overrides",
@@ -16,6 +15,5 @@ const bun = {
16
15
  })));
17
16
  }
18
17
  };
19
-
20
18
  //#endregion
21
- export { bun };
19
+ export { bun };
@@ -8,6 +8,5 @@ const deno = {
8
8
  throw Error("Deno not supported");
9
9
  }
10
10
  };
11
-
12
11
  //#endregion
13
- export { deno };
12
+ export { deno };
@@ -4,7 +4,6 @@ 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
-
8
7
  //#region src/core/package-managers/index.ts
9
8
  async function createWxtPackageManager(root) {
10
9
  const pm = await detectPackageManager(root, { includeParentDirs: true });
@@ -54,6 +53,5 @@ const packageManagers = {
54
53
  yarn,
55
54
  deno
56
55
  };
57
-
58
56
  //#endregion
59
- export { createWxtPackageManager };
57
+ export { createWxtPackageManager };
@@ -1,12 +1,11 @@
1
- import { ensureDir } from "fs-extra";
1
+ import { mkdir } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import spawn from "nano-spawn";
4
-
5
4
  //#region src/core/package-managers/npm.ts
6
5
  const npm = {
7
6
  overridesKey: "overrides",
8
7
  async downloadDependency(id, downloadDir) {
9
- await ensureDir(downloadDir);
8
+ await mkdir(downloadDir, { recursive: true });
10
9
  const res = await spawn("npm", [
11
10
  "pack",
12
11
  id,
@@ -51,6 +50,5 @@ function dedupeDependencies(dependencies) {
51
50
  }
52
51
  });
53
52
  }
54
-
55
53
  //#endregion
56
- export { dedupeDependencies, flattenNpmListOutput, npm };
54
+ export { dedupeDependencies, flattenNpmListOutput, npm };
@@ -1,6 +1,5 @@
1
1
  import { flattenNpmListOutput, npm } from "./npm.mjs";
2
2
  import spawn from "nano-spawn";
3
-
4
3
  //#region src/core/package-managers/pnpm.ts
5
4
  const pnpm = {
6
5
  overridesKey: "resolutions",
@@ -19,6 +18,5 @@ const pnpm = {
19
18
  return flattenNpmListOutput(JSON.parse(res.stdout));
20
19
  }
21
20
  };
22
-
23
21
  //#endregion
24
- export { pnpm };
22
+ export { pnpm };