wxt 0.14.1 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -4,7 +4,7 @@ import "./chunk-VBXJIVYU.js";
4
4
  import cac from "cac";
5
5
 
6
6
  // package.json
7
- var version = "0.14.1";
7
+ var version = "0.14.2";
8
8
 
9
9
  // src/core/utils/fs.ts
10
10
  import fs from "fs-extra";
@@ -194,6 +194,7 @@ function resolvePerBrowserOption(option, browser) {
194
194
  var VIRTUAL_NOOP_BACKGROUND_MODULE_ID = "virtual:user-background";
195
195
 
196
196
  // src/core/utils/building/find-entrypoints.ts
197
+ import pc2 from "picocolors";
197
198
  async function findEntrypoints(config) {
198
199
  const relativePaths = await glob2(Object.keys(PATH_GLOB_TO_TYPE_MAP), {
199
200
  cwd: config.entrypointsDir
@@ -208,7 +209,12 @@ async function findEntrypoints(config) {
208
209
  );
209
210
  if (matchingGlob) {
210
211
  const type = PATH_GLOB_TO_TYPE_MAP[matchingGlob];
211
- results.push({ name, inputPath, type });
212
+ results.push({
213
+ name,
214
+ inputPath,
215
+ type,
216
+ skipped: config.filterEntrypoints != null && !config.filterEntrypoints.has(name)
217
+ });
212
218
  }
213
219
  return results;
214
220
  }, []);
@@ -260,11 +266,19 @@ async function findEntrypoints(config) {
260
266
  await getBackgroundEntrypoint(config, {
261
267
  inputPath: VIRTUAL_NOOP_BACKGROUND_MODULE_ID,
262
268
  name: "background",
263
- type: "background"
269
+ type: "background",
270
+ skipped: false
264
271
  })
265
272
  );
266
273
  }
267
274
  config.logger.debug("All entrypoints:", entrypoints);
275
+ const skippedEntrypointNames = entrypointInfos.filter((item) => item.skipped).map((item) => item.name);
276
+ if (skippedEntrypointNames.length) {
277
+ config.logger.warn(
278
+ `Filter excluded the following entrypoints:
279
+ ${skippedEntrypointNames.map((item) => `${pc2.dim("-")} ${pc2.cyan(item)}`).join("\n")}`
280
+ );
281
+ }
268
282
  const targetEntrypoints = entrypoints.filter((entry) => {
269
283
  const { include, exclude } = entry.options;
270
284
  if (include?.length && exclude?.length) {
@@ -279,6 +293,9 @@ async function findEntrypoints(config) {
279
293
  if (include?.length && !exclude?.length) {
280
294
  return include.includes(config.browser);
281
295
  }
296
+ if (skippedEntrypointNames.includes(entry.name)) {
297
+ return false;
298
+ }
282
299
  return true;
283
300
  });
284
301
  config.logger.debug(`${config.browser} entrypoints:`, targetEntrypoints);
@@ -331,7 +348,7 @@ function getHtmlBaseOptions(document) {
331
348
  }
332
349
  return options;
333
350
  }
334
- async function getPopupEntrypoint(config, { inputPath, name }) {
351
+ async function getPopupEntrypoint(config, { inputPath, name, skipped }) {
335
352
  const content = await fs3.readFile(inputPath, "utf-8");
336
353
  const { document } = parseHTML(content);
337
354
  const options = getHtmlBaseOptions(document);
@@ -362,10 +379,11 @@ async function getPopupEntrypoint(config, { inputPath, name }) {
362
379
  name: "popup",
363
380
  options,
364
381
  inputPath,
365
- outputDir: config.outDir
382
+ outputDir: config.outDir,
383
+ skipped
366
384
  };
367
385
  }
368
- async function getOptionsEntrypoint(config, { inputPath, name }) {
386
+ async function getOptionsEntrypoint(config, { inputPath, name, skipped }) {
369
387
  const content = await fs3.readFile(inputPath, "utf-8");
370
388
  const { document } = parseHTML(content);
371
389
  const options = getHtmlBaseOptions(document);
@@ -386,10 +404,11 @@ async function getOptionsEntrypoint(config, { inputPath, name }) {
386
404
  name: "options",
387
405
  options,
388
406
  inputPath,
389
- outputDir: config.outDir
407
+ outputDir: config.outDir,
408
+ skipped
390
409
  };
391
410
  }
392
- async function getUnlistedPageEntrypoint(config, { inputPath, name }) {
411
+ async function getUnlistedPageEntrypoint(config, { inputPath, name, skipped }) {
393
412
  const content = await fs3.readFile(inputPath, "utf-8");
394
413
  const { document } = parseHTML(content);
395
414
  return {
@@ -397,10 +416,11 @@ async function getUnlistedPageEntrypoint(config, { inputPath, name }) {
397
416
  name: getEntrypointName(config.entrypointsDir, inputPath),
398
417
  inputPath,
399
418
  outputDir: config.outDir,
400
- options: getHtmlBaseOptions(document)
419
+ options: getHtmlBaseOptions(document),
420
+ skipped
401
421
  };
402
422
  }
403
- async function getUnlistedScriptEntrypoint(config, { inputPath, name }) {
423
+ async function getUnlistedScriptEntrypoint(config, { inputPath, name, skipped }) {
404
424
  const defaultExport = await importEntrypointFile(
405
425
  inputPath,
406
426
  config
@@ -417,10 +437,11 @@ async function getUnlistedScriptEntrypoint(config, { inputPath, name }) {
417
437
  name,
418
438
  inputPath,
419
439
  outputDir: config.outDir,
420
- options
440
+ options,
441
+ skipped
421
442
  };
422
443
  }
423
- async function getBackgroundEntrypoint(config, { inputPath, name }) {
444
+ async function getBackgroundEntrypoint(config, { inputPath, name, skipped }) {
424
445
  let options = {};
425
446
  if (inputPath !== VIRTUAL_NOOP_BACKGROUND_MODULE_ID) {
426
447
  const defaultExport = await importEntrypointFile(
@@ -444,10 +465,11 @@ async function getBackgroundEntrypoint(config, { inputPath, name }) {
444
465
  ...options,
445
466
  type: resolvePerBrowserOption(options.type, config.browser),
446
467
  persistent: resolvePerBrowserOption(options.persistent, config.browser)
447
- }
468
+ },
469
+ skipped
448
470
  };
449
471
  }
450
- async function getContentScriptEntrypoint(config, { inputPath, name }) {
472
+ async function getContentScriptEntrypoint(config, { inputPath, name, skipped }) {
451
473
  const { main: _, ...options } = await importEntrypointFile(inputPath, config);
452
474
  if (options == null) {
453
475
  throw Error(
@@ -459,7 +481,8 @@ async function getContentScriptEntrypoint(config, { inputPath, name }) {
459
481
  name,
460
482
  inputPath,
461
483
  outputDir: resolve3(config.outDir, CONTENT_SCRIPT_OUT_DIR),
462
- options
484
+ options,
485
+ skipped
463
486
  };
464
487
  }
465
488
  var PATH_GLOB_TO_TYPE_MAP = {
@@ -670,8 +693,10 @@ import "wxt/browser";
670
693
  declare module "wxt/browser" {
671
694
  export type PublicPath =
672
695
  {{ union }}
696
+ type HtmlPublicPath = Extract<PublicPath, \`\${string}.html\`>
673
697
  export interface WxtRuntime extends Runtime.Static {
674
698
  getURL(path: PublicPath): string;
699
+ getURL(path: \`\${HtmlPublicPath}\${string}\`): string;
675
700
  }
676
701
  }
677
702
  `;
@@ -1286,7 +1311,7 @@ function entrypointGroupGlobals(entrypointGroup) {
1286
1311
  }
1287
1312
 
1288
1313
  // src/core/builders/vite/index.ts
1289
- async function craeteViteBuilder(inlineConfig, userConfig, wxtConfig) {
1314
+ async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
1290
1315
  const vite = await import("vite");
1291
1316
  const getBaseConfig = async () => {
1292
1317
  const resolvedInlineConfig = await inlineConfig.vite?.(wxtConfig.env) ?? {};
@@ -1523,6 +1548,7 @@ async function getInternalConfig(inlineConfig, command, server) {
1523
1548
  srcDir,
1524
1549
  mergedConfig.entrypointsDir ?? "entrypoints"
1525
1550
  );
1551
+ const filterEntrypoints = !!mergedConfig.filterEntrypoints?.length ? new Set(mergedConfig.filterEntrypoints) : void 0;
1526
1552
  const publicDir = path3.resolve(srcDir, mergedConfig.publicDir ?? "public");
1527
1553
  const typesDir = path3.resolve(wxtDir, "types");
1528
1554
  const outBaseDir = path3.resolve(root, mergedConfig.outDir ?? ".output");
@@ -1549,6 +1575,7 @@ async function getInternalConfig(inlineConfig, command, server) {
1549
1575
  command,
1550
1576
  debug,
1551
1577
  entrypointsDir,
1578
+ filterEntrypoints,
1552
1579
  env,
1553
1580
  fsCache: createFsCache(wxtDir),
1554
1581
  imports: mergedConfig.imports ?? {},
@@ -1580,7 +1607,7 @@ async function getInternalConfig(inlineConfig, command, server) {
1580
1607
  },
1581
1608
  server
1582
1609
  };
1583
- const builder = await craeteViteBuilder(
1610
+ const builder = await createViteBuilder(
1584
1611
  inlineConfig,
1585
1612
  userConfig,
1586
1613
  finalConfig
@@ -1622,6 +1649,7 @@ function mergeInlineConfig(inlineConfig, userConfig) {
1622
1649
  configFile: inlineConfig.configFile,
1623
1650
  debug: inlineConfig.debug ?? userConfig.debug,
1624
1651
  entrypointsDir: inlineConfig.entrypointsDir ?? userConfig.entrypointsDir,
1652
+ filterEntrypoints: inlineConfig.filterEntrypoints ?? userConfig.filterEntrypoints,
1625
1653
  imports,
1626
1654
  logger: inlineConfig.logger ?? userConfig.logger,
1627
1655
  manifest,
@@ -1709,7 +1737,7 @@ var ENTRY_TYPE_TO_GROUP_MAP = {
1709
1737
  import createJITI from "jiti";
1710
1738
  import { createUnimport as createUnimport3 } from "unimport";
1711
1739
  import fs8 from "fs-extra";
1712
- import { resolve as resolve9 } from "node:path";
1740
+ import { relative as relative5, resolve as resolve9 } from "node:path";
1713
1741
 
1714
1742
  // src/core/utils/strings.ts
1715
1743
  function kebabCaseAlphanumeric(str) {
@@ -1786,8 +1814,16 @@ async function importEntrypointFile(path7, config) {
1786
1814
  const res = await jiti(path7);
1787
1815
  return res.default;
1788
1816
  } catch (err) {
1789
- config.logger.error(err);
1790
- throw err;
1817
+ if (err instanceof ReferenceError) {
1818
+ const variableName = err.message.replace(" is not defined", "");
1819
+ const filePath = relative5(config.root, path7);
1820
+ throw Error(
1821
+ `${filePath}: Cannot use imported variable "${variableName}" outside the main function. See https://wxt.dev/guide/entrypoints.html#side-effects`,
1822
+ { cause: err }
1823
+ );
1824
+ } else {
1825
+ throw err;
1826
+ }
1791
1827
  }
1792
1828
  }
1793
1829
  function getEsbuildOptions(opts) {
@@ -1800,7 +1836,7 @@ function getEsbuildOptions(opts) {
1800
1836
  }
1801
1837
 
1802
1838
  // src/core/utils/building/internal-build.ts
1803
- import pc4 from "picocolors";
1839
+ import pc5 from "picocolors";
1804
1840
  import fs12 from "fs-extra";
1805
1841
 
1806
1842
  // src/core/utils/log/printBuildSummary.ts
@@ -1808,7 +1844,7 @@ import { resolve as resolve10 } from "path";
1808
1844
 
1809
1845
  // src/core/utils/log/printFileList.ts
1810
1846
  import path4 from "node:path";
1811
- import pc2 from "picocolors";
1847
+ import pc3 from "picocolors";
1812
1848
  import fs9 from "fs-extra";
1813
1849
  import { filesize } from "filesize";
1814
1850
 
@@ -1854,25 +1890,25 @@ async function printFileList(log, header, baseDir, files) {
1854
1890
  totalSize += stats.size;
1855
1891
  const size = String(filesize(stats.size));
1856
1892
  return [
1857
- `${pc2.gray(prefix)} ${pc2.dim(parts[0])}${color(parts[1])}`,
1858
- pc2.dim(size)
1893
+ `${pc3.gray(prefix)} ${pc3.dim(parts[0])}${color(parts[1])}`,
1894
+ pc3.dim(size)
1859
1895
  ];
1860
1896
  })
1861
1897
  );
1862
- fileRows.push([`${pc2.cyan("\u03A3 Total size:")} ${String(filesize(totalSize))}`]);
1898
+ fileRows.push([`${pc3.cyan("\u03A3 Total size:")} ${String(filesize(totalSize))}`]);
1863
1899
  printTable(log, header, fileRows);
1864
1900
  }
1865
- var DEFAULT_COLOR = pc2.blue;
1901
+ var DEFAULT_COLOR = pc3.blue;
1866
1902
  var CHUNK_COLORS = {
1867
- ".js.map": pc2.gray,
1868
- ".cjs.map": pc2.gray,
1869
- ".mjs.map": pc2.gray,
1870
- ".html": pc2.green,
1871
- ".css": pc2.magenta,
1872
- ".js": pc2.cyan,
1873
- ".cjs": pc2.cyan,
1874
- ".mjs": pc2.cyan,
1875
- ".zip": pc2.yellow
1903
+ ".js.map": pc3.gray,
1904
+ ".cjs.map": pc3.gray,
1905
+ ".mjs.map": pc3.gray,
1906
+ ".html": pc3.green,
1907
+ ".css": pc3.magenta,
1908
+ ".js": pc3.cyan,
1909
+ ".cjs": pc3.cyan,
1910
+ ".mjs": pc3.cyan,
1911
+ ".zip": pc3.yellow
1876
1912
  };
1877
1913
  function getChunkColor(filename) {
1878
1914
  return Object.entries(CHUNK_COLORS).find(([key]) => filename.endsWith(key))?.[1] ?? DEFAULT_COLOR;
@@ -1909,11 +1945,11 @@ function getChunkSortWeight(filename) {
1909
1945
  }
1910
1946
 
1911
1947
  // src/core/utils/log/printHeader.ts
1912
- import pc3 from "picocolors";
1948
+ import pc4 from "picocolors";
1913
1949
  import { consola as consola2 } from "consola";
1914
1950
  function printHeader() {
1915
1951
  console.log();
1916
- consola2.log(`${pc3.gray("WXT")} ${pc3.gray(pc3.bold(version))}`);
1952
+ consola2.log(`${pc4.gray("WXT")} ${pc4.gray(pc4.bold(version))}`);
1917
1953
  }
1918
1954
 
1919
1955
  // src/core/utils/building/internal-build.ts
@@ -2447,13 +2483,12 @@ function stripPathFromMatchPattern(pattern) {
2447
2483
  }
2448
2484
 
2449
2485
  // src/core/utils/building/rebuild.ts
2450
- async function rebuild(config, entrypointGroups, existingOutput = {
2486
+ async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput = {
2451
2487
  steps: [],
2452
2488
  publicAssets: []
2453
2489
  }) {
2454
2490
  const { default: ora } = await import("ora");
2455
2491
  const spinner = ora(`Preparing...`).start();
2456
- const allEntrypoints = await findEntrypoints(config);
2457
2492
  await generateTypesDir(allEntrypoints, config).catch((err) => {
2458
2493
  config.logger.warn("Failed to update .wxt directory:", err);
2459
2494
  if (config.command === "build")
@@ -2493,7 +2528,7 @@ async function internalBuild(config) {
2493
2528
  const verb = config.command === "serve" ? "Pre-rendering" : "Building";
2494
2529
  const target = `${config.browser}-mv${config.manifestVersion}`;
2495
2530
  config.logger.info(
2496
- `${verb} ${pc4.cyan(target)} for ${pc4.cyan(config.mode)} with ${pc4.green(
2531
+ `${verb} ${pc5.cyan(target)} for ${pc5.cyan(config.mode)} with ${pc5.green(
2497
2532
  `${config.builder.name} ${config.builder.version}`
2498
2533
  )}`
2499
2534
  );
@@ -2503,7 +2538,7 @@ async function internalBuild(config) {
2503
2538
  const entrypoints = await findEntrypoints(config);
2504
2539
  config.logger.debug("Detected entrypoints:", entrypoints);
2505
2540
  const groups = groupEntrypoints(entrypoints);
2506
- const { output } = await rebuild(config, groups, void 0);
2541
+ const { output } = await rebuild(config, entrypoints, groups, void 0);
2507
2542
  await printBuildSummary(
2508
2543
  config.logger.success,
2509
2544
  `Built extension in ${formatDuration(Date.now() - startTime)}`,
@@ -2514,7 +2549,7 @@ async function internalBuild(config) {
2514
2549
  await combineAnalysisStats(config);
2515
2550
  config.logger.info(
2516
2551
  `Analysis complete:
2517
- ${pc4.gray("\u2514\u2500")} ${pc4.yellow("stats.html")}`
2552
+ ${pc5.gray("\u2514\u2500")} ${pc5.yellow("stats.html")}`
2518
2553
  );
2519
2554
  }
2520
2555
  return output;
@@ -2543,7 +2578,7 @@ import path5 from "node:path";
2543
2578
  import glob4 from "fast-glob";
2544
2579
  import fs13 from "fs-extra";
2545
2580
  import { consola as consola3 } from "consola";
2546
- import pc5 from "picocolors";
2581
+ import pc6 from "picocolors";
2547
2582
  async function clean(root = process.cwd()) {
2548
2583
  consola3.info("Cleaning Project");
2549
2584
  const tempDirs = [
@@ -2552,7 +2587,7 @@ async function clean(root = process.cwd()) {
2552
2587
  "**/.wxt",
2553
2588
  ".output/*"
2554
2589
  ];
2555
- consola3.debug("Looking for:", tempDirs.map(pc5.cyan).join(", "));
2590
+ consola3.debug("Looking for:", tempDirs.map(pc6.cyan).join(", "));
2556
2591
  const directories = await glob4(tempDirs, {
2557
2592
  cwd: path5.resolve(root),
2558
2593
  absolute: true,
@@ -2565,21 +2600,21 @@ async function clean(root = process.cwd()) {
2565
2600
  }
2566
2601
  consola3.debug(
2567
2602
  "Found:",
2568
- directories.map((dir) => pc5.cyan(path5.relative(root, dir))).join(", ")
2603
+ directories.map((dir) => pc6.cyan(path5.relative(root, dir))).join(", ")
2569
2604
  );
2570
2605
  for (const directory of directories) {
2571
2606
  await fs13.rm(directory, { force: true, recursive: true });
2572
- consola3.debug("Deleted " + pc5.cyan(path5.relative(root, directory)));
2607
+ consola3.debug("Deleted " + pc6.cyan(path5.relative(root, directory)));
2573
2608
  }
2574
2609
  }
2575
2610
 
2576
2611
  // src/core/runners/wsl.ts
2577
- import { relative as relative5 } from "node:path";
2612
+ import { relative as relative6 } from "node:path";
2578
2613
  function createWslRunner() {
2579
2614
  return {
2580
2615
  async openBrowser(config) {
2581
2616
  config.logger.warn(
2582
- `Cannot open browser when using WSL. Load "${relative5(
2617
+ `Cannot open browser when using WSL. Load "${relative6(
2583
2618
  process.cwd(),
2584
2619
  config.outDir
2585
2620
  )}" as an unpacked extension manually`
@@ -2651,12 +2686,12 @@ var WARN_LOG_LEVEL = 40;
2651
2686
  var ERROR_LOG_LEVEL = 50;
2652
2687
 
2653
2688
  // src/core/runners/safari.ts
2654
- import { relative as relative6 } from "node:path";
2689
+ import { relative as relative7 } from "node:path";
2655
2690
  function createSafariRunner() {
2656
2691
  return {
2657
2692
  async openBrowser(config) {
2658
2693
  config.logger.warn(
2659
- `Cannot Safari using web-ext. Load "${relative6(
2694
+ `Cannot Safari using web-ext. Load "${relative7(
2660
2695
  process.cwd(),
2661
2696
  config.outDir
2662
2697
  )}" as an unpacked extension manually`
@@ -2668,12 +2703,12 @@ function createSafariRunner() {
2668
2703
  }
2669
2704
 
2670
2705
  // src/core/runners/manual.ts
2671
- import { relative as relative7 } from "node:path";
2706
+ import { relative as relative8 } from "node:path";
2672
2707
  function createManualRunner() {
2673
2708
  return {
2674
2709
  async openBrowser(config) {
2675
2710
  config.logger.info(
2676
- `Load "${relative7(
2711
+ `Load "${relative8(
2677
2712
  process.cwd(),
2678
2713
  config.outDir
2679
2714
  )}" as an unpacked extension manually`
@@ -2704,8 +2739,8 @@ async function createExtensionRunner(config) {
2704
2739
  // src/core/create-server.ts
2705
2740
  import { consola as consola4 } from "consola";
2706
2741
  import { Mutex } from "async-mutex";
2707
- import pc6 from "picocolors";
2708
- import { relative as relative8 } from "node:path";
2742
+ import pc7 from "picocolors";
2743
+ import { relative as relative9 } from "node:path";
2709
2744
  async function createServer(inlineConfig) {
2710
2745
  const port = await getPort();
2711
2746
  const hostname = "localhost";
@@ -2785,15 +2820,17 @@ function createFileReloader(options) {
2785
2820
  if (changes.type === "no-change")
2786
2821
  return;
2787
2822
  config.logger.info(
2788
- `Changed: ${Array.from(new Set(fileChanges.map((change) => change[1]))).map((file) => pc6.dim(relative8(config.root, file))).join(", ")}`
2823
+ `Changed: ${Array.from(new Set(fileChanges.map((change) => change[1]))).map((file) => pc7.dim(relative9(config.root, file))).join(", ")}`
2789
2824
  );
2790
2825
  const rebuiltNames = changes.rebuildGroups.flat().map((entry) => {
2791
- return pc6.cyan(
2792
- relative8(config.outDir, getEntrypointOutputFile(entry, ""))
2826
+ return pc7.cyan(
2827
+ relative9(config.outDir, getEntrypointOutputFile(entry, ""))
2793
2828
  );
2794
- }).join(pc6.dim(", "));
2829
+ }).join(pc7.dim(", "));
2830
+ const allEntrypoints = await findEntrypoints(config);
2795
2831
  const { output: newOutput } = await rebuild(
2796
2832
  config,
2833
+ allEntrypoints,
2797
2834
  // TODO: this excludes new entrypoints, so they're not built until the dev command is restarted
2798
2835
  changes.rebuildGroups,
2799
2836
  changes.cachedOutput
@@ -2857,7 +2894,7 @@ import { consola as consola5 } from "consola";
2857
2894
  import { downloadTemplate } from "giget";
2858
2895
  import fs14 from "fs-extra";
2859
2896
  import path6 from "node:path";
2860
- import pc7 from "picocolors";
2897
+ import pc8 from "picocolors";
2861
2898
  async function initialize(options) {
2862
2899
  consola5.info("Initalizing new project");
2863
2900
  const templates = await listTemplates();
@@ -2886,11 +2923,11 @@ async function initialize(options) {
2886
2923
  type: () => options.packageManager == null ? "select" : void 0,
2887
2924
  message: "Package Manager",
2888
2925
  choices: [
2889
- { title: pc7.red("npm"), value: "npm" },
2890
- { title: pc7.yellow("pnpm"), value: "pnpm" },
2891
- { title: pc7.cyan("yarn"), value: "yarn" },
2926
+ { title: pc8.red("npm"), value: "npm" },
2927
+ { title: pc8.yellow("pnpm"), value: "pnpm" },
2928
+ { title: pc8.cyan("yarn"), value: "yarn" },
2892
2929
  {
2893
- title: `${pc7.magenta("bun")}${pc7.gray(" (experimental)")}`,
2930
+ title: `${pc8.magenta("bun")}${pc8.gray(" (experimental)")}`,
2894
2931
  value: "bun"
2895
2932
  }
2896
2933
  ]
@@ -2913,8 +2950,8 @@ async function initialize(options) {
2913
2950
  consola5.log("Next steps:");
2914
2951
  let step = 0;
2915
2952
  if (cdPath !== "")
2916
- consola5.log(` ${++step}.`, pc7.cyan(`cd ${cdPath}`));
2917
- consola5.log(` ${++step}.`, pc7.cyan(`${input.packageManager} install`));
2953
+ consola5.log(` ${++step}.`, pc8.cyan(`cd ${cdPath}`));
2954
+ consola5.log(` ${++step}.`, pc8.cyan(`${input.packageManager} install`));
2918
2955
  console.log();
2919
2956
  }
2920
2957
  async function listTemplates() {
@@ -2968,11 +3005,11 @@ async function cloneProject({
2968
3005
  }
2969
3006
  }
2970
3007
  var TEMPLATE_COLORS = {
2971
- vanilla: pc7.blue,
2972
- vue: pc7.green,
2973
- react: pc7.cyan,
2974
- svelte: pc7.red,
2975
- solid: pc7.blue
3008
+ vanilla: pc8.blue,
3009
+ vue: pc8.green,
3010
+ react: pc8.cyan,
3011
+ svelte: pc8.red,
3012
+ solid: pc8.blue
2976
3013
  };
2977
3014
  var TEMPLATE_SORT_WEIGHT = {
2978
3015
  vanilla: 0,
@@ -2990,7 +3027,7 @@ async function prepare(config) {
2990
3027
 
2991
3028
  // src/core/zip.ts
2992
3029
  import zipdir from "zip-dir";
2993
- import { dirname as dirname5, relative as relative9, resolve as resolve13 } from "node:path";
3030
+ import { dirname as dirname5, relative as relative10, resolve as resolve13 } from "node:path";
2994
3031
  import fs15 from "fs-extra";
2995
3032
  import { minimatch as minimatch2 } from "minimatch";
2996
3033
  async function zip(config) {
@@ -3024,7 +3061,7 @@ async function zip(config) {
3024
3061
  await zipdir(internalConfig.zip.sourcesRoot, {
3025
3062
  saveTo: sourcesZipPath,
3026
3063
  filter(path7) {
3027
- const relativePath = relative9(internalConfig.zip.sourcesRoot, path7);
3064
+ const relativePath = relative10(internalConfig.zip.sourcesRoot, path7);
3028
3065
  const matchedPattern = internalConfig.zip.ignoredSources.find(
3029
3066
  (pattern) => minimatch2(relativePath, pattern)
3030
3067
  );
@@ -3049,7 +3086,13 @@ var cli = cac("wxt");
3049
3086
  cli.help();
3050
3087
  cli.version(version);
3051
3088
  cli.option("--debug", "enable debug mode");
3052
- cli.command("[root]", "start dev server").option("-c, --config <file>", "use specified config file").option("-m, --mode <mode>", "set env mode").option("-b, --browser <browser>", "specify a browser").option("--mv3", "target manifest v3").option("--mv2", "target manifest v2").action(
3089
+ cli.command("[root]", "start dev server").option("-c, --config <file>", "use specified config file").option("-m, --mode <mode>", "set env mode").option("-b, --browser <browser>", "specify a browser").option(
3090
+ "-e, --filter-entrypoint <entrypoint>",
3091
+ "only build specific entrypoints",
3092
+ {
3093
+ type: []
3094
+ }
3095
+ ).option("--mv3", "target manifest v3").option("--mv2", "target manifest v2").action(
3053
3096
  wrapAction(async (root, flags) => {
3054
3097
  const server = await createServer({
3055
3098
  root,
@@ -3057,13 +3100,20 @@ cli.command("[root]", "start dev server").option("-c, --config <file>", "use spe
3057
3100
  browser: flags.browser,
3058
3101
  manifestVersion: flags.mv3 ? 3 : flags.mv2 ? 2 : void 0,
3059
3102
  configFile: flags.config,
3060
- debug: flags.debug
3103
+ debug: flags.debug,
3104
+ filterEntrypoints: getArrayFromFlags(flags, "filterEntrypoint")
3061
3105
  });
3062
3106
  await server.start();
3063
3107
  return { isOngoing: true };
3064
3108
  })
3065
3109
  );
3066
- cli.command("build [root]", "build for production").option("-c, --config <file>", "use specified config file").option("-m, --mode <mode>", "set env mode").option("-b, --browser <browser>", "specify a browser").option("--mv3", "target manifest v3").option("--mv2", "target manifest v2").option("--analyze", "visualize extension bundle").action(
3110
+ cli.command("build [root]", "build for production").option("-c, --config <file>", "use specified config file").option("-m, --mode <mode>", "set env mode").option("-b, --browser <browser>", "specify a browser").option(
3111
+ "-e, --filter-entrypoint <entrypoint>",
3112
+ "only build specific entrypoints",
3113
+ {
3114
+ type: []
3115
+ }
3116
+ ).option("--mv3", "target manifest v3").option("--mv2", "target manifest v2").option("--analyze", "visualize extension bundle").action(
3067
3117
  wrapAction(async (root, flags) => {
3068
3118
  await build({
3069
3119
  root,
@@ -3074,7 +3124,8 @@ cli.command("build [root]", "build for production").option("-c, --config <file>"
3074
3124
  debug: flags.debug,
3075
3125
  analysis: {
3076
3126
  enabled: flags.analyze
3077
- }
3127
+ },
3128
+ filterEntrypoints: getArrayFromFlags(flags, "filterEntrypoint")
3078
3129
  });
3079
3130
  })
3080
3131
  );
@@ -3140,3 +3191,7 @@ function wrapAction(cb, options) {
3140
3191
  }
3141
3192
  };
3142
3193
  }
3194
+ function getArrayFromFlags(flags, name) {
3195
+ const array = [flags[name]].flat();
3196
+ return array.filter((item) => item != null);
3197
+ }
@@ -126,6 +126,12 @@ interface InlineConfig {
126
126
  * @default "${config.srcDir}/entrypoints"
127
127
  */
128
128
  entrypointsDir?: string;
129
+ /**
130
+ * A list of entrypoint names (`"popup"`, `"options"`, etc.) to build. Will speed up the build if
131
+ * your extension has lots of entrypoints, and you don't need to build all of them to develop a
132
+ * feature.
133
+ */
134
+ filterEntrypoints?: string[];
129
135
  /**
130
136
  * Output directory that stored build folders and ZIPs.
131
137
  *
@@ -445,6 +451,7 @@ interface BaseEntrypoint {
445
451
  */
446
452
  outputDir: string;
447
453
  options: BaseEntrypointOptions;
454
+ skipped: boolean;
448
455
  }
449
456
  interface GenericEntrypoint extends BaseEntrypoint {
450
457
  type: 'sandbox' | 'bookmarks' | 'history' | 'newtab' | 'sidepanel' | 'devtools' | 'unlisted-page' | 'unlisted-script' | 'unlisted-style' | 'content-script-style';
@@ -126,6 +126,12 @@ interface InlineConfig {
126
126
  * @default "${config.srcDir}/entrypoints"
127
127
  */
128
128
  entrypointsDir?: string;
129
+ /**
130
+ * A list of entrypoint names (`"popup"`, `"options"`, etc.) to build. Will speed up the build if
131
+ * your extension has lots of entrypoints, and you don't need to build all of them to develop a
132
+ * feature.
133
+ */
134
+ filterEntrypoints?: string[];
129
135
  /**
130
136
  * Output directory that stored build folders and ZIPs.
131
137
  *
@@ -445,6 +451,7 @@ interface BaseEntrypoint {
445
451
  */
446
452
  outputDir: string;
447
453
  options: BaseEntrypointOptions;
454
+ skipped: boolean;
448
455
  }
449
456
  interface GenericEntrypoint extends BaseEntrypoint {
450
457
  type: 'sandbox' | 'bookmarks' | 'history' | 'newtab' | 'sidepanel' | 'devtools' | 'unlisted-page' | 'unlisted-script' | 'unlisted-style' | 'content-script-style';