wxt 0.19.16 → 0.19.18

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.
@@ -99,11 +99,13 @@ export declare class ContentScriptContext implements AbortController {
99
99
  * ctx.addEventListener(document, "visibilitychange", () => {
100
100
  * // ...
101
101
  * });
102
- * ctx.addEventListener(document, "wxt:locationchange", () => {
102
+ * ctx.addEventListener(window, "wxt:locationchange", () => {
103
103
  * // ...
104
104
  * });
105
105
  */
106
- addEventListener<TTarget extends EventTarget, TType extends keyof WxtContentScriptEventMap>(target: TTarget, type: TType, handler: (event: WxtContentScriptEventMap[TType]) => void, options?: AddEventListenerOptions): void;
106
+ addEventListener<TType extends keyof WxtWindowEventMap>(target: Window, type: TType, handler: (event: WxtWindowEventMap[TType]) => void, options?: AddEventListenerOptions): void;
107
+ addEventListener<TType extends keyof DocumentEventMap>(target: Document, type: keyof DocumentEventMap, handler: (event: DocumentEventMap[TType]) => void, options?: AddEventListenerOptions): void;
108
+ addEventListener<TTarget extends EventTarget>(target: TTarget, ...params: Parameters<TTarget['addEventListener']>): void;
107
109
  /**
108
110
  * @internal
109
111
  * Abort the abort controller and execute all `onInvalidated` listeners.
@@ -114,7 +116,6 @@ export declare class ContentScriptContext implements AbortController {
114
116
  ignoreFirstEvent?: boolean;
115
117
  }): void;
116
118
  }
117
- interface WxtContentScriptEventMap extends WindowEventMap {
119
+ export interface WxtWindowEventMap extends WindowEventMap {
118
120
  'wxt:locationchange': WxtLocationChangeEvent;
119
121
  }
120
- export {};
@@ -109,30 +109,12 @@ export class ContentScriptContext {
109
109
  this.onInvalidated(() => cancelIdleCallback(id));
110
110
  return id;
111
111
  }
112
- /**
113
- * Call `target.addEventListener` and remove the event listener when the context is invalidated.
114
- *
115
- * Includes additional events useful for content scripts:
116
- *
117
- * - `"wxt:locationchange"` - Triggered when HTML5 history mode is used to change URL. Content
118
- * scripts are not reloaded when navigating this way, so this can be used to reset the content
119
- * script state on URL change, or run custom code.
120
- *
121
- * @example
122
- * ctx.addEventListener(document, "visibilitychange", () => {
123
- * // ...
124
- * });
125
- * ctx.addEventListener(document, "wxt:locationchange", () => {
126
- * // ...
127
- * });
128
- */
129
112
  addEventListener(target, type, handler, options) {
130
113
  if (type === "wxt:locationchange") {
131
114
  if (this.isValid) this.locationWatcher.run();
132
115
  }
133
116
  target.addEventListener?.(
134
117
  type.startsWith("wxt:") ? getUniqueEventName(type) : type,
135
- // @ts-expect-error: Event don't match, but that's OK, EventTarget doesn't allow custom types in the callback
136
118
  handler,
137
119
  {
138
120
  ...options,
@@ -13,6 +13,7 @@ export function createIntegratedUi(ctx, options) {
13
13
  };
14
14
  const remove = () => {
15
15
  options.onRemove?.(mounted);
16
+ wrapper.replaceChildren();
16
17
  wrapper.remove();
17
18
  mounted = void 0;
18
19
  };
@@ -1,3 +1,3 @@
1
1
  import { ResolvedConfig, WxtBuilder, WxtDevServer, WxtHooks } from '../../../types';
2
2
  import { Hookable } from 'hookable';
3
- export declare function createViteBuilder(wxtConfig: ResolvedConfig, hooks: Hookable<WxtHooks>, server?: WxtDevServer): Promise<WxtBuilder>;
3
+ export declare function createViteBuilder(wxtConfig: ResolvedConfig, hooks: Hookable<WxtHooks>, getWxtDevServer?: () => WxtDevServer | undefined): Promise<WxtBuilder>;
@@ -9,7 +9,7 @@ import { importEntrypointFile } from "../../utils/building/index.mjs";
9
9
  import { ViteNodeServer } from "vite-node/server";
10
10
  import { ViteNodeRunner } from "vite-node/client";
11
11
  import { installSourcemapsSupport } from "vite-node/source-map";
12
- export async function createViteBuilder(wxtConfig, hooks, server) {
12
+ export async function createViteBuilder(wxtConfig, hooks, getWxtDevServer) {
13
13
  const vite = await import("vite");
14
14
  const getBaseConfig = async (baseConfigOptions) => {
15
15
  const config = await wxtConfig.vite(wxtConfig.env);
@@ -33,6 +33,7 @@ export async function createViteBuilder(wxtConfig, hooks, server) {
33
33
  config.server.watch = {
34
34
  ignored: [`${wxtConfig.outBaseDir}/**`, `${wxtConfig.wxtDir}/**`]
35
35
  };
36
+ const server = getWxtDevServer?.();
36
37
  config.plugins ??= [];
37
38
  config.plugins.push(
38
39
  wxtPlugins.download(wxtConfig),
@@ -180,18 +181,18 @@ export async function createViteBuilder(wxtConfig, hooks, server) {
180
181
  plugins: [wxtPlugins.removeEntrypointMainFunction(wxtConfig, path)]
181
182
  };
182
183
  const config = vite.mergeConfig(baseConfig, envConfig);
183
- const server2 = await vite.createServer(config);
184
- await server2.pluginContainer.buildStart({});
184
+ const server = await vite.createServer(config);
185
+ await server.pluginContainer.buildStart({});
185
186
  const node = new ViteNodeServer(
186
187
  // @ts-ignore: Some weird type error...
187
- server2
188
+ server
188
189
  );
189
190
  installSourcemapsSupport({
190
191
  getSourceMap: (source) => node.getSourceMap(source)
191
192
  });
192
193
  const runner = new ViteNodeRunner({
193
- root: server2.config.root,
194
- base: server2.config.base,
194
+ root: server.config.root,
195
+ base: server.config.base,
195
196
  // when having the server and runner in a different context,
196
197
  // you will need to handle the communication between them
197
198
  // and pass to this function
@@ -203,7 +204,7 @@ export async function createViteBuilder(wxtConfig, hooks, server) {
203
204
  }
204
205
  });
205
206
  const res = await runner.executeFile(path);
206
- await server2.close();
207
+ await server.close();
207
208
  return res.default;
208
209
  }
209
210
  }
@@ -239,7 +240,7 @@ export async function createViteBuilder(wxtConfig, hooks, server) {
239
240
  const finalConfig = vite.mergeConfig(baseConfig, serverConfig);
240
241
  await hooks.callHook("vite:devServer:extendConfig", finalConfig);
241
242
  const viteServer = await vite.createServer(finalConfig);
242
- const server2 = {
243
+ const server = {
243
244
  async listen() {
244
245
  await viteServer.listen(info.port);
245
246
  },
@@ -259,7 +260,7 @@ export async function createViteBuilder(wxtConfig, hooks, server) {
259
260
  },
260
261
  watcher: viteServer.watcher
261
262
  };
262
- return server2;
263
+ return server;
263
264
  }
264
265
  };
265
266
  }
@@ -14,66 +14,98 @@ import { createExtensionRunner } from "./runners/index.mjs";
14
14
  import { Mutex } from "async-mutex";
15
15
  import pc from "picocolors";
16
16
  import { relative } from "node:path";
17
- import { registerWxt, wxt } from "./wxt.mjs";
17
+ import { deinitWxtModules, initWxtModules, registerWxt, wxt } from "./wxt.mjs";
18
18
  import { unnormalizePath } from "./utils/paths.mjs";
19
19
  import {
20
20
  getContentScriptJs,
21
21
  mapWxtOptionsToRegisteredContentScript
22
22
  } from "./utils/content-scripts.mjs";
23
23
  export async function createServer(inlineConfig) {
24
- await registerWxt("serve", inlineConfig, async (config) => {
25
- const { port, hostname } = config.dev.server;
26
- const serverInfo = {
24
+ await registerWxt("serve", inlineConfig);
25
+ wxt.server = await createServerInternal();
26
+ await wxt.hooks.callHook("server:created", wxt, wxt.server);
27
+ return wxt.server;
28
+ }
29
+ async function createServerInternal() {
30
+ const getServerInfo = () => {
31
+ const { port, hostname } = wxt.config.dev.server;
32
+ return {
27
33
  port,
28
34
  hostname,
29
35
  origin: `http://${hostname}:${port}`
30
36
  };
31
- const server2 = {
32
- ...serverInfo,
33
- get watcher() {
34
- return builderServer.watcher;
35
- },
36
- get ws() {
37
- return builderServer.ws;
38
- },
39
- currentOutput: void 0,
40
- async start() {
41
- await builderServer.listen();
42
- wxt.logger.success(`Started dev server @ ${serverInfo.origin}`);
43
- await buildAndOpenBrowser();
44
- },
45
- async stop() {
46
- await runner.closeBrowser();
47
- await builderServer.close();
48
- },
49
- async restart() {
50
- await closeAndRecreateRunner();
51
- await buildAndOpenBrowser();
52
- },
53
- transformHtml(url, html, originalUrl) {
54
- return builderServer.transformHtml(url, html, originalUrl);
55
- },
56
- reloadContentScript(payload) {
57
- server2.ws.send("wxt:reload-content-script", payload);
58
- },
59
- reloadPage(path) {
60
- server2.ws.send("wxt:reload-page", path);
61
- },
62
- reloadExtension() {
63
- server2.ws.send("wxt:reload-extension");
64
- },
65
- async restartBrowser() {
66
- await closeAndRecreateRunner();
67
- await runner.openBrowser();
68
- }
69
- };
70
- return server2;
71
- });
72
- const server = wxt.server;
37
+ };
73
38
  let [runner, builderServer] = await Promise.all([
74
39
  createExtensionRunner(),
75
- wxt.builder.createServer(server)
40
+ wxt.builder.createServer(getServerInfo())
76
41
  ]);
42
+ let wasStopped = false;
43
+ const server = {
44
+ get hostname() {
45
+ return getServerInfo().hostname;
46
+ },
47
+ get port() {
48
+ return getServerInfo().port;
49
+ },
50
+ get origin() {
51
+ return getServerInfo().origin;
52
+ },
53
+ get watcher() {
54
+ return builderServer.watcher;
55
+ },
56
+ get ws() {
57
+ return builderServer.ws;
58
+ },
59
+ currentOutput: void 0,
60
+ async start() {
61
+ if (wasStopped) {
62
+ await wxt.reloadConfig();
63
+ runner = await createExtensionRunner();
64
+ builderServer = await wxt.builder.createServer(getServerInfo());
65
+ await initWxtModules();
66
+ }
67
+ await builderServer.listen();
68
+ wxt.logger.success(`Started dev server @ ${server.origin}`);
69
+ await wxt.hooks.callHook("server:started", wxt, server);
70
+ await buildAndOpenBrowser();
71
+ server.ws.on("wxt:background-initialized", () => {
72
+ if (server.currentOutput == null) return;
73
+ reloadContentScripts(server.currentOutput.steps, server);
74
+ });
75
+ const reloadOnChange = createFileReloader(server);
76
+ server.watcher.on("all", reloadOnChange);
77
+ },
78
+ async stop() {
79
+ wasStopped = true;
80
+ await runner.closeBrowser();
81
+ await builderServer.close();
82
+ await wxt.hooks.callHook("server:closed", wxt, server);
83
+ deinitWxtModules();
84
+ server.currentOutput = void 0;
85
+ },
86
+ async restart() {
87
+ await server.stop();
88
+ await server.start();
89
+ },
90
+ transformHtml(url, html, originalUrl) {
91
+ return builderServer.transformHtml(url, html, originalUrl);
92
+ },
93
+ reloadContentScript(payload) {
94
+ server.ws.send("wxt:reload-content-script", payload);
95
+ },
96
+ reloadPage(path) {
97
+ server.ws.send("wxt:reload-page", path);
98
+ },
99
+ reloadExtension() {
100
+ server.ws.send("wxt:reload-extension");
101
+ },
102
+ async restartBrowser() {
103
+ await runner.closeBrowser();
104
+ await wxt.reloadConfig();
105
+ runner = await createExtensionRunner();
106
+ await runner.openBrowser();
107
+ }
108
+ };
77
109
  const buildAndOpenBrowser = async () => {
78
110
  server.currentOutput = await internalBuild();
79
111
  try {
@@ -83,17 +115,6 @@ export async function createServer(inlineConfig) {
83
115
  }
84
116
  await runner.openBrowser();
85
117
  };
86
- const closeAndRecreateRunner = async () => {
87
- await runner.closeBrowser();
88
- await wxt.reloadConfig();
89
- runner = await createExtensionRunner();
90
- };
91
- server.ws.on("wxt:background-initialized", () => {
92
- if (server.currentOutput == null) return;
93
- reloadContentScripts(server.currentOutput.steps, server);
94
- });
95
- const reloadOnChange = createFileReloader(server);
96
- server.watcher.on("all", reloadOnChange);
97
118
  return server;
98
119
  }
99
120
  function createFileReloader(server) {
@@ -10,6 +10,7 @@ import { builtinModules } from "../builtin-modules/index.mjs";
10
10
  import { getEslintVersion } from "./utils/eslint.mjs";
11
11
  import { safeStringToNumber } from "./utils/number.mjs";
12
12
  import { loadEnv } from "./utils/env.mjs";
13
+ import { getPort } from "get-port-please";
13
14
  export async function resolveConfig(inlineConfig, command) {
14
15
  let userConfig = {};
15
16
  let userConfigMetadata;
@@ -82,14 +83,19 @@ export async function resolveConfig(inlineConfig, command) {
82
83
  );
83
84
  let devServerConfig;
84
85
  if (command === "serve") {
86
+ const hostname = mergedConfig.dev?.server?.hostname ?? "localhost";
85
87
  let port = mergedConfig.dev?.server?.port;
86
88
  if (port == null || !isFinite(port)) {
87
- const { default: getPort, portNumbers } = await import("get-port");
88
- port = await getPort({ port: portNumbers(3e3, 3010) });
89
+ port = await getPort({
90
+ port: 3e3,
91
+ portRange: [3001, 3010],
92
+ // Passing host required for Mac, unsure of Windows/Linux
93
+ host: hostname
94
+ });
89
95
  }
90
96
  devServerConfig = {
91
97
  port,
92
- hostname: mergedConfig.dev?.server?.hostname ?? "localhost",
98
+ hostname,
93
99
  watchDebounce: safeStringToNumber(process.env.WXT_WATCH_DEBOUNCE) ?? 800
94
100
  };
95
101
  }
@@ -274,9 +280,10 @@ async function getUnimportEslintOptions(wxtDir, options) {
274
280
  case "auto":
275
281
  const version = await getEslintVersion();
276
282
  let major = parseInt(version[0]);
283
+ if (isNaN(major)) eslintEnabled = false;
277
284
  if (major <= 8) eslintEnabled = 8;
278
285
  else if (major >= 9) eslintEnabled = 9;
279
- else eslintEnabled = 8;
286
+ else eslintEnabled = false;
280
287
  break;
281
288
  case true:
282
289
  eslintEnabled = 8;
@@ -17,7 +17,11 @@ import { BuildOutput, BuildStepOutput, EntrypointGroup } from '../../../types';
17
17
  * - Background script is changed
18
18
  * - Manifest is different
19
19
  * - Restart browser
20
- * - Config file changed (wxt.config.ts, .env, web-ext.config.ts, etc)
20
+ * - web-ext.config.ts (runner config changes)
21
+ * - Full dev server restart
22
+ * - wxt.config.ts (main config file)
23
+ * - modules/* (any file related to WXT modules)
24
+ * - .env (environment variable changed could effect build)
21
25
  */
22
26
  export declare function detectDevChanges(changedFiles: string[], currentOutput: BuildOutput): DevModeChange;
23
27
  /**
@@ -7,6 +7,11 @@ export function detectDevChanges(changedFiles, currentOutput) {
7
7
  (file) => file === wxt.config.userConfigMetadata.configFile
8
8
  );
9
9
  if (isConfigChange) return { type: "full-restart" };
10
+ const isWxtModuleChange = some(
11
+ changedFiles,
12
+ (file) => file.startsWith(wxt.config.modulesDir)
13
+ );
14
+ if (isWxtModuleChange) return { type: "full-restart" };
10
15
  const isRunnerChange = some(
11
16
  changedFiles,
12
17
  (file) => file === wxt.config.runnerConfig.configFile
@@ -39,12 +39,7 @@ export async function findEntrypoints() {
39
39
  );
40
40
  if (matchingGlob) {
41
41
  const type = PATH_GLOB_TO_TYPE_MAP[matchingGlob];
42
- results.push({
43
- name,
44
- inputPath,
45
- type,
46
- skipped: wxt.config.filterEntrypoints != null && !wxt.config.filterEntrypoints.has(name)
47
- });
42
+ results.push({ name, inputPath, type });
48
43
  }
49
44
  return results;
50
45
  }, []);
@@ -52,7 +47,7 @@ export async function findEntrypoints() {
52
47
  preventDuplicateEntrypointNames(entrypointInfos);
53
48
  let hasBackground = false;
54
49
  const env = createExtensionEnvironment();
55
- const entrypoints = await env.run(
50
+ const entrypointsWithoutSkipped = await env.run(
56
51
  () => Promise.all(
57
52
  entrypointInfos.map(async (info) => {
58
53
  const { type } = info;
@@ -97,45 +92,32 @@ export async function findEntrypoints() {
97
92
  )
98
93
  );
99
94
  if (wxt.config.command === "serve" && !hasBackground) {
100
- entrypoints.push(
95
+ entrypointsWithoutSkipped.push(
101
96
  await getBackgroundEntrypoint({
102
97
  inputPath: VIRTUAL_NOOP_BACKGROUND_MODULE_ID,
103
98
  name: "background",
104
- type: "background",
105
- skipped: false
99
+ type: "background"
106
100
  })
107
101
  );
108
102
  }
103
+ const entrypoints = entrypointsWithoutSkipped.map((entry) => ({
104
+ ...entry,
105
+ skipped: isEntrypointSkipped(entry)
106
+ }));
109
107
  wxt.logger.debug("All entrypoints:", entrypoints);
110
- const skippedEntrypointNames = entrypointInfos.filter((item) => item.skipped).map((item) => item.name);
108
+ const skippedEntrypointNames = entrypoints.filter((item) => item.skipped).map((item) => item.name);
111
109
  if (skippedEntrypointNames.length) {
112
110
  wxt.logger.warn(
113
- `Filter excluded the following entrypoints:
114
- ${skippedEntrypointNames.map((item) => `${pc.dim("-")} ${pc.cyan(item)}`).join("\n")}`
111
+ [
112
+ "The following entrypoints have been skipped:",
113
+ ...skippedEntrypointNames.map(
114
+ (item) => `${pc.dim("-")} ${pc.cyan(item)}`
115
+ )
116
+ ].join("\n")
115
117
  );
116
118
  }
117
- const targetEntrypoints = entrypoints.filter((entry) => {
118
- const { include, exclude } = entry.options;
119
- if (include?.length && exclude?.length) {
120
- wxt.logger.warn(
121
- `The ${entry.name} entrypoint lists both include and exclude, but only one can be used per entrypoint. Entrypoint ignored.`
122
- );
123
- return false;
124
- }
125
- if (exclude?.length && !include?.length) {
126
- return !exclude.includes(wxt.config.browser);
127
- }
128
- if (include?.length && !exclude?.length) {
129
- return include.includes(wxt.config.browser);
130
- }
131
- if (skippedEntrypointNames.includes(entry.name)) {
132
- return false;
133
- }
134
- return true;
135
- });
136
- wxt.logger.debug(`${wxt.config.browser} entrypoints:`, targetEntrypoints);
137
- await wxt.hooks.callHook("entrypoints:resolved", wxt, targetEntrypoints);
138
- return targetEntrypoints;
119
+ await wxt.hooks.callHook("entrypoints:resolved", wxt, entrypoints);
120
+ return entrypoints;
139
121
  }
140
122
  function preventDuplicateEntrypointNames(files) {
141
123
  const namesToPaths = files.reduce(
@@ -196,8 +178,7 @@ async function getPopupEntrypoint(info) {
196
178
  name: "popup",
197
179
  options: resolvePerBrowserOptions(options, wxt.config.browser),
198
180
  inputPath: info.inputPath,
199
- outputDir: wxt.config.outDir,
200
- skipped: info.skipped
181
+ outputDir: wxt.config.outDir
201
182
  };
202
183
  }
203
184
  async function getOptionsEntrypoint(info) {
@@ -216,8 +197,7 @@ async function getOptionsEntrypoint(info) {
216
197
  name: "options",
217
198
  options: resolvePerBrowserOptions(options, wxt.config.browser),
218
199
  inputPath: info.inputPath,
219
- outputDir: wxt.config.outDir,
220
- skipped: info.skipped
200
+ outputDir: wxt.config.outDir
221
201
  };
222
202
  }
223
203
  async function getUnlistedPageEntrypoint(info) {
@@ -230,14 +210,12 @@ async function getUnlistedPageEntrypoint(info) {
230
210
  name: info.name,
231
211
  inputPath: info.inputPath,
232
212
  outputDir: wxt.config.outDir,
233
- options,
234
- skipped: info.skipped
213
+ options
235
214
  };
236
215
  }
237
216
  async function getUnlistedScriptEntrypoint({
238
217
  inputPath,
239
- name,
240
- skipped
218
+ name
241
219
  }) {
242
220
  const defaultExport = await wxt.builder.importEntrypoint(inputPath);
243
221
  if (defaultExport == null) {
@@ -251,14 +229,12 @@ async function getUnlistedScriptEntrypoint({
251
229
  name,
252
230
  inputPath,
253
231
  outputDir: wxt.config.outDir,
254
- options: resolvePerBrowserOptions(options, wxt.config.browser),
255
- skipped
232
+ options: resolvePerBrowserOptions(options, wxt.config.browser)
256
233
  };
257
234
  }
258
235
  async function getBackgroundEntrypoint({
259
236
  inputPath,
260
- name,
261
- skipped
237
+ name
262
238
  }) {
263
239
  let options = {};
264
240
  if (inputPath !== VIRTUAL_NOOP_BACKGROUND_MODULE_ID) {
@@ -279,14 +255,12 @@ async function getBackgroundEntrypoint({
279
255
  name,
280
256
  inputPath,
281
257
  outputDir: wxt.config.outDir,
282
- options: resolvePerBrowserOptions(options, wxt.config.browser),
283
- skipped
258
+ options: resolvePerBrowserOptions(options, wxt.config.browser)
284
259
  };
285
260
  }
286
261
  async function getContentScriptEntrypoint({
287
262
  inputPath,
288
- name,
289
- skipped
263
+ name
290
264
  }) {
291
265
  const defaultExport = await wxt.builder.importEntrypoint(inputPath);
292
266
  if (defaultExport == null) {
@@ -305,8 +279,7 @@ async function getContentScriptEntrypoint({
305
279
  name,
306
280
  inputPath,
307
281
  outputDir: resolve(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
308
- options: resolvePerBrowserOptions(options, wxt.config.browser),
309
- skipped
282
+ options: resolvePerBrowserOptions(options, wxt.config.browser)
310
283
  };
311
284
  }
312
285
  async function getSidepanelEntrypoint(info) {
@@ -332,8 +305,7 @@ async function getSidepanelEntrypoint(info) {
332
305
  name: info.name,
333
306
  options: resolvePerBrowserOptions(options, wxt.config.browser),
334
307
  inputPath: info.inputPath,
335
- outputDir: wxt.config.outDir,
336
- skipped: info.skipped
308
+ outputDir: wxt.config.outDir
337
309
  };
338
310
  }
339
311
  async function getHtmlEntrypointOptions(info, keyMap, queries, parsers) {
@@ -357,6 +329,25 @@ async function getHtmlEntrypointOptions(info, keyMap, queries, parsers) {
357
329
  });
358
330
  return options;
359
331
  }
332
+ function isEntrypointSkipped(entry) {
333
+ if (wxt.config.filterEntrypoints != null) {
334
+ return !wxt.config.filterEntrypoints.has(entry.name);
335
+ }
336
+ const { include, exclude } = entry.options;
337
+ if (include?.length && exclude?.length) {
338
+ wxt.logger.warn(
339
+ `The ${entry.name} entrypoint lists both include and exclude, but only one can be used per entrypoint. Entrypoint skipped.`
340
+ );
341
+ return true;
342
+ }
343
+ if (exclude?.length && !include?.length) {
344
+ return exclude.includes(wxt.config.browser);
345
+ }
346
+ if (include?.length && !exclude?.length) {
347
+ return !include.includes(wxt.config.browser);
348
+ }
349
+ return false;
350
+ }
360
351
  const PATH_GLOB_TO_TYPE_MAP = {
361
352
  "sandbox.html": "sandbox",
362
353
  "sandbox/index.html": "sandbox",
@@ -1,7 +1,7 @@
1
1
  import { Entrypoint, EntrypointGroup } from '../../../types';
2
2
  /**
3
- * Entrypoints can be build in groups. HTML pages can all be built together in a single step, while
4
- * content scripts must be build individually.
3
+ * Entrypoints are built in groups. HTML pages can all be built together in a single step,
4
+ * content scripts must be build individually, etc.
5
5
  *
6
6
  * This function returns the entrypoints put into these types of groups.
7
7
  */
@@ -2,6 +2,7 @@ export function groupEntrypoints(entrypoints) {
2
2
  const groupIndexMap = {};
3
3
  const groups = [];
4
4
  for (const entry of entrypoints) {
5
+ if (entry.skipped) continue;
5
6
  let group = ENTRY_TYPE_TO_GROUP_MAP[entry.type];
6
7
  if (entry.type === "background" && entry.options.type === "module") {
7
8
  group = "esm";
@@ -28,7 +28,7 @@ export function hashContentScriptOptions(options) {
28
28
  }
29
29
  export function mapWxtOptionsToContentScript(options, js, css) {
30
30
  return {
31
- matches: options.matches,
31
+ matches: options.matches ?? [],
32
32
  all_frames: options.allFrames,
33
33
  match_about_blank: options.matchAboutBlank,
34
34
  exclude_globs: options.excludeGlobs,
@@ -35,10 +35,10 @@ export declare function stripPathFromMatchPattern(pattern: string): string;
35
35
  /**
36
36
  * Converts all MV3 web accessible resources to their MV2 forms. MV3 web accessible resources are
37
37
  * generated in this file, and may be defined by the user in their manifest. In both cases, when
38
- * targetting MV2, automatically convert their definitions down to the basic MV2 array.
38
+ * targeting MV2, automatically convert their definitions down to the basic MV2 array.
39
39
  */
40
40
  export declare function convertWebAccessibleResourcesToMv2(manifest: Manifest.WebExtensionManifest): void;
41
41
  /**
42
42
  * Make sure all resources are in MV3 format. If not, add a wanring
43
43
  */
44
- export declare function validateMv3WebAccessbileResources(manifest: Manifest.WebExtensionManifest): void;
44
+ export declare function validateMv3WebAccessibleResources(manifest: Manifest.WebExtensionManifest): void;