wxt 0.14.5 → 0.14.7

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.5";
2
+ var version = "0.14.7";
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";
@@ -157,9 +173,14 @@ async function buildEntrypoints(groups, config, spinner) {
157
173
  const steps = [];
158
174
  for (let i = 0; i < groups.length; i++) {
159
175
  const group = groups[i];
160
- const groupNames = [group].flat().map((e) => e.name).join(pc.dim(", "));
161
- spinner.text = pc.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNames}`;
162
- steps.push(await config.builder.build(group));
176
+ const groupNames = [group].flat().map((e) => e.name);
177
+ const groupNameColored = groupNames.join(pc.dim(", "));
178
+ spinner.text = pc.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNameColored}`;
179
+ try {
180
+ steps.push(await config.builder.build(group));
181
+ } catch (err) {
182
+ throw Error(`Failed to build ${groupNames.join(", ")}`, { cause: err });
183
+ }
163
184
  }
164
185
  const publicAssets = await copyPublicDirectory(config);
165
186
  return { publicAssets, steps };
@@ -1172,6 +1193,9 @@ async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
1172
1193
  async listen() {
1173
1194
  await viteServer.listen(info.port);
1174
1195
  },
1196
+ async close() {
1197
+ await viteServer.close();
1198
+ },
1175
1199
  transformHtml(...args) {
1176
1200
  return viteServer.transformIndexHtml(...args);
1177
1201
  },
@@ -1506,15 +1530,15 @@ async function importEntrypointFile(path6, config) {
1506
1530
  const res = await jiti(path6);
1507
1531
  return res.default;
1508
1532
  } catch (err) {
1533
+ const filePath = relative4(config.root, path6);
1509
1534
  if (err instanceof ReferenceError) {
1510
1535
  const variableName = err.message.replace(" is not defined", "");
1511
- const filePath = relative4(config.root, path6);
1512
1536
  throw Error(
1513
1537
  `${filePath}: Cannot use imported variable "${variableName}" outside the main function. See https://wxt.dev/guide/entrypoints.html#side-effects`,
1514
1538
  { cause: err }
1515
1539
  );
1516
1540
  } else {
1517
- throw err;
1541
+ throw Error(`Failed to load entrypoint: ${filePath}`, { cause: err });
1518
1542
  }
1519
1543
  }
1520
1544
  }
@@ -2218,6 +2242,70 @@ async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput
2218
2242
  }
2219
2243
 
2220
2244
  // src/core/utils/building/internal-build.ts
2245
+ import managePath from "manage-path";
2246
+ import { resolve as resolve12, relative as relative5 } from "node:path";
2247
+
2248
+ // src/core/utils/validation.ts
2249
+ function validateEntrypoints(entrypoints) {
2250
+ const errors = entrypoints.flatMap((entrypoint) => {
2251
+ switch (entrypoint.type) {
2252
+ case "content-script":
2253
+ return validateContentScriptEntrypoint(entrypoint);
2254
+ default:
2255
+ return validateBaseEntrypoint(entrypoint);
2256
+ }
2257
+ });
2258
+ let errorCount = 0;
2259
+ let warningCount = 0;
2260
+ for (const err of errors) {
2261
+ if (err.type === "warning")
2262
+ warningCount++;
2263
+ else
2264
+ errorCount++;
2265
+ }
2266
+ return {
2267
+ errors,
2268
+ errorCount,
2269
+ warningCount
2270
+ };
2271
+ }
2272
+ function validateContentScriptEntrypoint(definition) {
2273
+ const errors = validateBaseEntrypoint(definition);
2274
+ if (definition.options.matches == null) {
2275
+ errors.push({
2276
+ type: "error",
2277
+ message: "`matches` is required",
2278
+ value: definition.options.matches,
2279
+ entrypoint: definition
2280
+ });
2281
+ }
2282
+ return errors;
2283
+ }
2284
+ function validateBaseEntrypoint(definition) {
2285
+ const errors = [];
2286
+ if (definition.options.exclude != null && !Array.isArray(definition.options.exclude)) {
2287
+ errors.push({
2288
+ type: "error",
2289
+ message: "`exclude` must be an array of browser names",
2290
+ value: definition.options.exclude,
2291
+ entrypoint: definition
2292
+ });
2293
+ }
2294
+ if (definition.options.include != null && !Array.isArray(definition.options.include)) {
2295
+ errors.push({
2296
+ type: "error",
2297
+ message: "`include` must be an array of browser names",
2298
+ value: definition.options.include,
2299
+ entrypoint: definition
2300
+ });
2301
+ }
2302
+ return errors;
2303
+ }
2304
+ var ValidationError = class extends Error {
2305
+ };
2306
+
2307
+ // src/core/utils/building/internal-build.ts
2308
+ import consola3 from "consola";
2221
2309
  async function internalBuild(config) {
2222
2310
  const verb = config.command === "serve" ? "Pre-rendering" : "Building";
2223
2311
  const target = `${config.browser}-mv${config.manifestVersion}`;
@@ -2231,6 +2319,15 @@ async function internalBuild(config) {
2231
2319
  await fs11.ensureDir(config.outDir);
2232
2320
  const entrypoints = await findEntrypoints(config);
2233
2321
  config.logger.debug("Detected entrypoints:", entrypoints);
2322
+ const validationResults = validateEntrypoints(entrypoints);
2323
+ if (validationResults.errorCount + validationResults.warningCount > 0) {
2324
+ printValidationResults(config, validationResults);
2325
+ }
2326
+ if (validationResults.errorCount > 0) {
2327
+ throw new ValidationError(`Entrypoint validation failed`, {
2328
+ cause: validationResults
2329
+ });
2330
+ }
2234
2331
  const groups = groupEntrypoints(entrypoints);
2235
2332
  const { output, warnings } = await rebuild(
2236
2333
  config,
@@ -2263,11 +2360,35 @@ async function combineAnalysisStats(config) {
2263
2360
  absolute: true
2264
2361
  });
2265
2362
  const absolutePaths = unixFiles.map(unnormalizePath);
2363
+ const alterPath = managePath(process.env);
2364
+ alterPath.push(resolve12(config.root, "node_modules/wxt/node_modules/.bin"));
2266
2365
  await execaCommand(
2267
2366
  `rollup-plugin-visualizer ${absolutePaths.join(" ")} --template ${config.analysis.template}`,
2268
2367
  { cwd: config.root, stdio: "inherit" }
2269
2368
  );
2270
2369
  }
2370
+ function printValidationResults(config, { errorCount, errors, warningCount }) {
2371
+ (errorCount > 0 ? config.logger.error : config.logger.warn)(
2372
+ `Entrypoint validation failed: ${errorCount} error${errorCount === 1 ? "" : "s"}, ${warningCount} warning${warningCount === 1 ? "" : "s"}`
2373
+ );
2374
+ const cwd = process.cwd();
2375
+ const entrypointErrors = errors.reduce((map, error) => {
2376
+ const entryErrors = map.get(error.entrypoint) ?? [];
2377
+ entryErrors.push(error);
2378
+ map.set(error.entrypoint, entryErrors);
2379
+ return map;
2380
+ }, /* @__PURE__ */ new Map());
2381
+ Array.from(entrypointErrors.entries()).forEach(([entrypoint, errors2]) => {
2382
+ consola3.log(relative5(cwd, entrypoint.inputPath));
2383
+ console.log();
2384
+ errors2.forEach((err) => {
2385
+ const type = err.type === "error" ? pc4.red("ERROR") : pc4.yellow("WARN");
2386
+ const recieved = pc4.dim(`(recieved: ${JSON.stringify(err.value)})`);
2387
+ consola3.log(` - ${type} ${err.message} ${recieved}`);
2388
+ });
2389
+ console.log();
2390
+ });
2391
+ }
2271
2392
 
2272
2393
  // src/core/utils/building/find-entrypoints.ts
2273
2394
  import glob3 from "fast-glob";
@@ -2279,7 +2400,7 @@ async function findEntrypoints(config) {
2279
2400
  relativePaths.sort();
2280
2401
  const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
2281
2402
  const entrypointInfos = relativePaths.reduce((results, relativePath) => {
2282
- const inputPath = resolve12(config.entrypointsDir, relativePath);
2403
+ const inputPath = resolve13(config.entrypointsDir, relativePath);
2283
2404
  const name = getEntrypointName(config.entrypointsDir, inputPath);
2284
2405
  const matchingGlob = pathGlobs.find(
2285
2406
  (glob4) => minimatch(relativePath, glob4)
@@ -2319,7 +2440,7 @@ async function findEntrypoints(config) {
2319
2440
  return {
2320
2441
  ...info,
2321
2442
  type,
2322
- outputDir: resolve12(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2443
+ outputDir: resolve13(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2323
2444
  options: {
2324
2445
  include: void 0,
2325
2446
  exclude: void 0
@@ -2392,7 +2513,7 @@ function preventDuplicateEntrypointNames(config, files) {
2392
2513
  if (absolutePaths.length > 1) {
2393
2514
  lines.push(`- ${name}`);
2394
2515
  absolutePaths.forEach((absolutePath) => {
2395
- lines.push(` - ${relative5(config.root, absolutePath)}`);
2516
+ lines.push(` - ${relative6(config.root, absolutePath)}`);
2396
2517
  });
2397
2518
  }
2398
2519
  return lines;
@@ -2557,7 +2678,7 @@ async function getContentScriptEntrypoint(config, { inputPath, name, skipped })
2557
2678
  type: "content-script",
2558
2679
  name,
2559
2680
  inputPath,
2560
- outputDir: resolve12(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2681
+ outputDir: resolve13(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2561
2682
  options,
2562
2683
  skipped
2563
2684
  };