wxt 0.14.4 → 0.14.6

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.
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "0.14.4";
2
+ var version = "0.14.6";
3
3
 
4
4
  // src/core/utils/arrays.ts
5
5
  function every(array, predicate) {
@@ -8,6 +8,12 @@ function every(array, predicate) {
8
8
  return false;
9
9
  return true;
10
10
  }
11
+ function some(array, predicate) {
12
+ for (let i = 0; i < array.length; i++)
13
+ if (predicate(array[i], i))
14
+ return true;
15
+ return false;
16
+ }
11
17
 
12
18
  // src/core/utils/paths.ts
13
19
  import systemPath from "node:path";
@@ -22,9 +28,19 @@ var CSS_EXTENSIONS = ["css", "scss", "sass", "less", "styl", "stylus"];
22
28
  var CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
23
29
 
24
30
  // src/core/utils/building/detect-dev-changes.ts
25
- function detectDevChanges(changedFiles, currentOutput) {
26
- if (currentOutput == null)
27
- return { type: "no-change" };
31
+ function detectDevChanges(config, changedFiles, currentOutput) {
32
+ const isConfigChange = some(
33
+ changedFiles,
34
+ (file) => file === config.userConfigMetadata.configFile
35
+ );
36
+ if (isConfigChange)
37
+ return { type: "full-restart" };
38
+ const isRunnerChange = some(
39
+ changedFiles,
40
+ (file) => file === config.runnerConfig.configFile
41
+ );
42
+ if (isRunnerChange)
43
+ return { type: "browser-restart" };
28
44
  const changedSteps = new Set(
29
45
  changedFiles.flatMap(
30
46
  (changedFile) => findEffectedSteps(changedFile, currentOutput)
@@ -56,7 +72,7 @@ function detectDevChanges(changedFiles, currentOutput) {
56
72
  unchangedOutput.publicAssets.push(asset);
57
73
  }
58
74
  }
59
- const isOnlyHtmlChanges = changedFiles.length > 0 && every(changedFiles, ([_, file]) => file.endsWith(".html"));
75
+ const isOnlyHtmlChanges = changedFiles.length > 0 && every(changedFiles, (file) => file.endsWith(".html"));
60
76
  if (isOnlyHtmlChanges) {
61
77
  return {
62
78
  type: "html-reload",
@@ -84,7 +100,7 @@ function detectDevChanges(changedFiles, currentOutput) {
84
100
  }
85
101
  function findEffectedSteps(changedFile, currentOutput) {
86
102
  const changes = [];
87
- const changedPath = normalizePath(changedFile[1]);
103
+ const changedPath = normalizePath(changedFile);
88
104
  const isChunkEffected = (chunk) => (
89
105
  // If it's an HTML file with the same path, is is effected because HTML files need to be pre-rendered
90
106
  // fileName is normalized, relative bundle path
@@ -127,7 +143,7 @@ function resolvePerBrowserOption(option, browser) {
127
143
  }
128
144
 
129
145
  // src/core/utils/building/find-entrypoints.ts
130
- import { relative as relative5, resolve as resolve12 } from "path";
146
+ import { relative as relative6, resolve as resolve13 } from "path";
131
147
  import fs12 from "fs-extra";
132
148
  import { minimatch } from "minimatch";
133
149
  import { parseHTML as parseHTML2 } from "linkedom";
@@ -1172,6 +1188,9 @@ async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
1172
1188
  async listen() {
1173
1189
  await viteServer.listen(info.port);
1174
1190
  },
1191
+ async close() {
1192
+ await viteServer.close();
1193
+ },
1175
1194
  transformHtml(...args) {
1176
1195
  return viteServer.transformIndexHtml(...args);
1177
1196
  },
@@ -1237,6 +1256,7 @@ async function getInternalConfig(inlineConfig, command, server) {
1237
1256
  const typesDir = path4.resolve(wxtDir, "types");
1238
1257
  const outBaseDir = path4.resolve(root, mergedConfig.outDir ?? ".output");
1239
1258
  const outDir = path4.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
1259
+ const reloadCommand = mergedConfig.dev?.reloadCommand ?? "Alt+R";
1240
1260
  const runnerConfig = await loadConfig({
1241
1261
  name: "web-ext",
1242
1262
  cwd: root,
@@ -1289,7 +1309,10 @@ async function getInternalConfig(inlineConfig, command, server) {
1289
1309
  experimental: {
1290
1310
  includeBrowserPolyfill: mergedConfig.experimental?.includeBrowserPolyfill ?? true
1291
1311
  },
1292
- server
1312
+ server,
1313
+ dev: {
1314
+ reloadCommand
1315
+ }
1293
1316
  };
1294
1317
  const builder = await createViteBuilder(
1295
1318
  inlineConfig,
@@ -1356,7 +1379,11 @@ function mergeInlineConfig(inlineConfig, userConfig) {
1356
1379
  ...inlineConfig.experimental
1357
1380
  },
1358
1381
  vite: void 0,
1359
- transformManifest: void 0
1382
+ transformManifest: void 0,
1383
+ dev: {
1384
+ ...userConfig.dev,
1385
+ ...inlineConfig.dev
1386
+ }
1360
1387
  };
1361
1388
  }
1362
1389
  function resolveInternalZipConfig(root, mergedConfig) {
@@ -1768,6 +1795,7 @@ async function writeManifest(manifest, output, config) {
1768
1795
  });
1769
1796
  }
1770
1797
  async function generateManifest(entrypoints, buildOutput, config) {
1798
+ const warnings = [];
1771
1799
  const pkg = await getPackageJson(config);
1772
1800
  let versionName = config.manifest.version_name ?? config.manifest.version ?? pkg?.version;
1773
1801
  if (versionName == null) {
@@ -1785,21 +1813,26 @@ async function generateManifest(entrypoints, buildOutput, config) {
1785
1813
  short_name: pkg?.shortName,
1786
1814
  icons: discoverIcons(buildOutput)
1787
1815
  };
1788
- if (config.command === "serve") {
1789
- baseManifest.commands = {
1790
- "wxt:reload-extension": {
1791
- description: "Reload the extension during development",
1792
- suggested_key: {
1793
- default: "Alt+R"
1794
- }
1795
- }
1796
- };
1797
- }
1798
1816
  const userManifest = config.manifest;
1799
1817
  const manifest = defu3(
1800
1818
  userManifest,
1801
1819
  baseManifest
1802
1820
  );
1821
+ if (config.command === "serve" && config.dev.reloadCommand) {
1822
+ if (manifest.commands && Object.keys(manifest.commands).length >= 4) {
1823
+ warnings.push([
1824
+ "Extension already has 4 registered commands, WXT's reload command is disabled"
1825
+ ]);
1826
+ } else {
1827
+ manifest.commands ??= {};
1828
+ manifest.commands["wxt:reload-extension"] = {
1829
+ description: "Reload the extension during development",
1830
+ suggested_key: {
1831
+ default: config.dev.reloadCommand
1832
+ }
1833
+ };
1834
+ }
1835
+ }
1803
1836
  manifest.version = version2;
1804
1837
  manifest.version_name = // Firefox doesn't support version_name
1805
1838
  config.browser === "firefox" || versionName === version2 ? void 0 : versionName;
@@ -1818,7 +1851,10 @@ async function generateManifest(entrypoints, buildOutput, config) {
1818
1851
  "Manifest 'version' is missing. Either:\n1. Add a version in your <rootDir>/package.json\n2. Pass the version via the manifest option in your wxt.config.ts"
1819
1852
  );
1820
1853
  }
1821
- return finalManifest;
1854
+ return {
1855
+ manifest: finalManifest,
1856
+ warnings
1857
+ };
1822
1858
  }
1823
1859
  function simplifyVersion(versionName) {
1824
1860
  const version2 = /^((0|[1-9][0-9]{0,8})([.](0|[1-9][0-9]{0,8})){0,3}).*$/.exec(
@@ -2179,11 +2215,7 @@ async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput
2179
2215
  steps: [...existingOutput.steps, ...newOutput.steps],
2180
2216
  publicAssets: [...existingOutput.publicAssets, ...newOutput.publicAssets]
2181
2217
  };
2182
- const newManifest = await generateManifest(
2183
- allEntrypoints,
2184
- mergedOutput,
2185
- config
2186
- );
2218
+ const { manifest: newManifest, warnings: manifestWarnings } = await generateManifest(allEntrypoints, mergedOutput, config);
2187
2219
  const finalOutput = {
2188
2220
  manifest: newManifest,
2189
2221
  ...newOutput
@@ -2199,11 +2231,76 @@ async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput
2199
2231
  ...finalOutput.publicAssets
2200
2232
  ]
2201
2233
  },
2202
- manifest: newManifest
2234
+ manifest: newManifest,
2235
+ warnings: manifestWarnings
2203
2236
  };
2204
2237
  }
2205
2238
 
2206
2239
  // src/core/utils/building/internal-build.ts
2240
+ import managePath from "manage-path";
2241
+ import { resolve as resolve12, relative as relative5 } from "node:path";
2242
+
2243
+ // src/core/utils/validation.ts
2244
+ function validateEntrypoints(entrypoints) {
2245
+ const errors = entrypoints.flatMap((entrypoint) => {
2246
+ switch (entrypoint.type) {
2247
+ case "content-script":
2248
+ return validateContentScriptEntrypoint(entrypoint);
2249
+ default:
2250
+ return validateBaseEntrypoint(entrypoint);
2251
+ }
2252
+ });
2253
+ let errorCount = 0;
2254
+ let warningCount = 0;
2255
+ for (const err of errors) {
2256
+ if (err.type === "warning")
2257
+ warningCount++;
2258
+ else
2259
+ errorCount++;
2260
+ }
2261
+ return {
2262
+ errors,
2263
+ errorCount,
2264
+ warningCount
2265
+ };
2266
+ }
2267
+ function validateContentScriptEntrypoint(definition) {
2268
+ const errors = validateBaseEntrypoint(definition);
2269
+ if (definition.options.matches == null) {
2270
+ errors.push({
2271
+ type: "error",
2272
+ message: "`matches` is required",
2273
+ value: definition.options.matches,
2274
+ entrypoint: definition
2275
+ });
2276
+ }
2277
+ return errors;
2278
+ }
2279
+ function validateBaseEntrypoint(definition) {
2280
+ const errors = [];
2281
+ if (definition.options.exclude != null && !Array.isArray(definition.options.exclude)) {
2282
+ errors.push({
2283
+ type: "error",
2284
+ message: "`exclude` must be an array of browser names",
2285
+ value: definition.options.exclude,
2286
+ entrypoint: definition
2287
+ });
2288
+ }
2289
+ if (definition.options.include != null && !Array.isArray(definition.options.include)) {
2290
+ errors.push({
2291
+ type: "error",
2292
+ message: "`include` must be an array of browser names",
2293
+ value: definition.options.include,
2294
+ entrypoint: definition
2295
+ });
2296
+ }
2297
+ return errors;
2298
+ }
2299
+ var ValidationError = class extends Error {
2300
+ };
2301
+
2302
+ // src/core/utils/building/internal-build.ts
2303
+ import consola3 from "consola";
2207
2304
  async function internalBuild(config) {
2208
2305
  const verb = config.command === "serve" ? "Pre-rendering" : "Building";
2209
2306
  const target = `${config.browser}-mv${config.manifestVersion}`;
@@ -2217,14 +2314,31 @@ async function internalBuild(config) {
2217
2314
  await fs11.ensureDir(config.outDir);
2218
2315
  const entrypoints = await findEntrypoints(config);
2219
2316
  config.logger.debug("Detected entrypoints:", entrypoints);
2317
+ const validationResults = validateEntrypoints(entrypoints);
2318
+ if (validationResults.errorCount + validationResults.warningCount > 0) {
2319
+ printValidationResults(config, validationResults);
2320
+ }
2321
+ if (validationResults.errorCount > 0) {
2322
+ throw new ValidationError(`Entrypoint validation failed`, {
2323
+ cause: validationResults
2324
+ });
2325
+ }
2220
2326
  const groups = groupEntrypoints(entrypoints);
2221
- const { output } = await rebuild(config, entrypoints, groups, void 0);
2327
+ const { output, warnings } = await rebuild(
2328
+ config,
2329
+ entrypoints,
2330
+ groups,
2331
+ void 0
2332
+ );
2222
2333
  await printBuildSummary(
2223
2334
  config.logger.success,
2224
2335
  `Built extension in ${formatDuration(Date.now() - startTime)}`,
2225
2336
  output,
2226
2337
  config
2227
2338
  );
2339
+ for (const warning of warnings) {
2340
+ config.logger.warn(...warning);
2341
+ }
2228
2342
  if (config.analysis.enabled) {
2229
2343
  await combineAnalysisStats(config);
2230
2344
  config.logger.info(
@@ -2241,11 +2355,35 @@ async function combineAnalysisStats(config) {
2241
2355
  absolute: true
2242
2356
  });
2243
2357
  const absolutePaths = unixFiles.map(unnormalizePath);
2358
+ const alterPath = managePath(process.env);
2359
+ alterPath.push(resolve12(config.root, "node_modules/wxt/node_modules/.bin"));
2244
2360
  await execaCommand(
2245
2361
  `rollup-plugin-visualizer ${absolutePaths.join(" ")} --template ${config.analysis.template}`,
2246
2362
  { cwd: config.root, stdio: "inherit" }
2247
2363
  );
2248
2364
  }
2365
+ function printValidationResults(config, { errorCount, errors, warningCount }) {
2366
+ (errorCount > 0 ? config.logger.error : config.logger.warn)(
2367
+ `Entrypoint validation failed: ${errorCount} error${errorCount === 1 ? "" : "s"}, ${warningCount} warning${warningCount === 1 ? "" : "s"}`
2368
+ );
2369
+ const cwd = process.cwd();
2370
+ const entrypointErrors = errors.reduce((map, error) => {
2371
+ const entryErrors = map.get(error.entrypoint) ?? [];
2372
+ entryErrors.push(error);
2373
+ map.set(error.entrypoint, entryErrors);
2374
+ return map;
2375
+ }, /* @__PURE__ */ new Map());
2376
+ Array.from(entrypointErrors.entries()).forEach(([entrypoint, errors2]) => {
2377
+ consola3.log(relative5(cwd, entrypoint.inputPath));
2378
+ console.log();
2379
+ errors2.forEach((err) => {
2380
+ const type = err.type === "error" ? pc4.red("ERROR") : pc4.yellow("WARN");
2381
+ const recieved = pc4.dim(`(recieved: ${JSON.stringify(err.value)})`);
2382
+ consola3.log(` - ${type} ${err.message} ${recieved}`);
2383
+ });
2384
+ console.log();
2385
+ });
2386
+ }
2249
2387
 
2250
2388
  // src/core/utils/building/find-entrypoints.ts
2251
2389
  import glob3 from "fast-glob";
@@ -2257,7 +2395,7 @@ async function findEntrypoints(config) {
2257
2395
  relativePaths.sort();
2258
2396
  const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
2259
2397
  const entrypointInfos = relativePaths.reduce((results, relativePath) => {
2260
- const inputPath = resolve12(config.entrypointsDir, relativePath);
2398
+ const inputPath = resolve13(config.entrypointsDir, relativePath);
2261
2399
  const name = getEntrypointName(config.entrypointsDir, inputPath);
2262
2400
  const matchingGlob = pathGlobs.find(
2263
2401
  (glob4) => minimatch(relativePath, glob4)
@@ -2297,7 +2435,7 @@ async function findEntrypoints(config) {
2297
2435
  return {
2298
2436
  ...info,
2299
2437
  type,
2300
- outputDir: resolve12(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2438
+ outputDir: resolve13(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2301
2439
  options: {
2302
2440
  include: void 0,
2303
2441
  exclude: void 0
@@ -2370,7 +2508,7 @@ function preventDuplicateEntrypointNames(config, files) {
2370
2508
  if (absolutePaths.length > 1) {
2371
2509
  lines.push(`- ${name}`);
2372
2510
  absolutePaths.forEach((absolutePath) => {
2373
- lines.push(` - ${relative5(config.root, absolutePath)}`);
2511
+ lines.push(` - ${relative6(config.root, absolutePath)}`);
2374
2512
  });
2375
2513
  }
2376
2514
  return lines;
@@ -2535,7 +2673,7 @@ async function getContentScriptEntrypoint(config, { inputPath, name, skipped })
2535
2673
  type: "content-script",
2536
2674
  name,
2537
2675
  inputPath,
2538
- outputDir: resolve12(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2676
+ outputDir: resolve13(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2539
2677
  options,
2540
2678
  skipped
2541
2679
  };
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }