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.
- package/dist/{chunk-YECUTQH3.js → chunk-NDW6LQ5D.js} +137 -16
- package/dist/cli.js +222 -58
- package/dist/{external-biT0d3qK.d.cts → external-mJ1bW7iy.d.cts} +18 -2
- package/dist/{external-biT0d3qK.d.ts → external-mJ1bW7iy.d.ts} +18 -2
- package/dist/index.cjs +234 -73
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +56 -16
- package/dist/storage.cjs +11 -1
- package/dist/storage.js +11 -1
- package/dist/testing.cjs +8 -0
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/package.json +5 -2
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ import "./chunk-73I7FAJU.js";
|
|
|
5
5
|
import cac from "cac";
|
|
6
6
|
|
|
7
7
|
// package.json
|
|
8
|
-
var version = "0.14.
|
|
8
|
+
var version = "0.14.7";
|
|
9
9
|
|
|
10
10
|
// src/core/utils/fs.ts
|
|
11
11
|
import fs from "fs-extra";
|
|
@@ -45,9 +45,14 @@ async function buildEntrypoints(groups, config, spinner) {
|
|
|
45
45
|
const steps = [];
|
|
46
46
|
for (let i = 0; i < groups.length; i++) {
|
|
47
47
|
const group = groups[i];
|
|
48
|
-
const groupNames = [group].flat().map((e) => e.name)
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
const groupNames = [group].flat().map((e) => e.name);
|
|
49
|
+
const groupNameColored = groupNames.join(pc.dim(", "));
|
|
50
|
+
spinner.text = pc.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNameColored}`;
|
|
51
|
+
try {
|
|
52
|
+
steps.push(await config.builder.build(group));
|
|
53
|
+
} catch (err) {
|
|
54
|
+
throw Error(`Failed to build ${groupNames.join(", ")}`, { cause: err });
|
|
55
|
+
}
|
|
51
56
|
}
|
|
52
57
|
const publicAssets = await copyPublicDirectory(config);
|
|
53
58
|
return { publicAssets, steps };
|
|
@@ -77,11 +82,27 @@ function every(array, predicate) {
|
|
|
77
82
|
return false;
|
|
78
83
|
return true;
|
|
79
84
|
}
|
|
85
|
+
function some(array, predicate) {
|
|
86
|
+
for (let i = 0; i < array.length; i++)
|
|
87
|
+
if (predicate(array[i], i))
|
|
88
|
+
return true;
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
80
91
|
|
|
81
92
|
// src/core/utils/building/detect-dev-changes.ts
|
|
82
|
-
function detectDevChanges(changedFiles, currentOutput) {
|
|
83
|
-
|
|
84
|
-
|
|
93
|
+
function detectDevChanges(config, changedFiles, currentOutput) {
|
|
94
|
+
const isConfigChange = some(
|
|
95
|
+
changedFiles,
|
|
96
|
+
(file) => file === config.userConfigMetadata.configFile
|
|
97
|
+
);
|
|
98
|
+
if (isConfigChange)
|
|
99
|
+
return { type: "full-restart" };
|
|
100
|
+
const isRunnerChange = some(
|
|
101
|
+
changedFiles,
|
|
102
|
+
(file) => file === config.runnerConfig.configFile
|
|
103
|
+
);
|
|
104
|
+
if (isRunnerChange)
|
|
105
|
+
return { type: "browser-restart" };
|
|
85
106
|
const changedSteps = new Set(
|
|
86
107
|
changedFiles.flatMap(
|
|
87
108
|
(changedFile) => findEffectedSteps(changedFile, currentOutput)
|
|
@@ -113,7 +134,7 @@ function detectDevChanges(changedFiles, currentOutput) {
|
|
|
113
134
|
unchangedOutput.publicAssets.push(asset);
|
|
114
135
|
}
|
|
115
136
|
}
|
|
116
|
-
const isOnlyHtmlChanges = changedFiles.length > 0 && every(changedFiles, (
|
|
137
|
+
const isOnlyHtmlChanges = changedFiles.length > 0 && every(changedFiles, (file) => file.endsWith(".html"));
|
|
117
138
|
if (isOnlyHtmlChanges) {
|
|
118
139
|
return {
|
|
119
140
|
type: "html-reload",
|
|
@@ -141,7 +162,7 @@ function detectDevChanges(changedFiles, currentOutput) {
|
|
|
141
162
|
}
|
|
142
163
|
function findEffectedSteps(changedFile, currentOutput) {
|
|
143
164
|
const changes = [];
|
|
144
|
-
const changedPath = normalizePath(changedFile
|
|
165
|
+
const changedPath = normalizePath(changedFile);
|
|
145
166
|
const isChunkEffected = (chunk) => (
|
|
146
167
|
// If it's an HTML file with the same path, is is effected because HTML files need to be pre-rendered
|
|
147
168
|
// fileName is normalized, relative bundle path
|
|
@@ -1489,6 +1510,9 @@ async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
|
|
|
1489
1510
|
async listen() {
|
|
1490
1511
|
await viteServer.listen(info.port);
|
|
1491
1512
|
},
|
|
1513
|
+
async close() {
|
|
1514
|
+
await viteServer.close();
|
|
1515
|
+
},
|
|
1492
1516
|
transformHtml(...args) {
|
|
1493
1517
|
return viteServer.transformIndexHtml(...args);
|
|
1494
1518
|
},
|
|
@@ -1823,15 +1847,15 @@ async function importEntrypointFile(path7, config) {
|
|
|
1823
1847
|
const res = await jiti(path7);
|
|
1824
1848
|
return res.default;
|
|
1825
1849
|
} catch (err) {
|
|
1850
|
+
const filePath = relative5(config.root, path7);
|
|
1826
1851
|
if (err instanceof ReferenceError) {
|
|
1827
1852
|
const variableName = err.message.replace(" is not defined", "");
|
|
1828
|
-
const filePath = relative5(config.root, path7);
|
|
1829
1853
|
throw Error(
|
|
1830
1854
|
`${filePath}: Cannot use imported variable "${variableName}" outside the main function. See https://wxt.dev/guide/entrypoints.html#side-effects`,
|
|
1831
1855
|
{ cause: err }
|
|
1832
1856
|
);
|
|
1833
1857
|
} else {
|
|
1834
|
-
throw err;
|
|
1858
|
+
throw Error(`Failed to load entrypoint: ${filePath}`, { cause: err });
|
|
1835
1859
|
}
|
|
1836
1860
|
}
|
|
1837
1861
|
}
|
|
@@ -2539,6 +2563,70 @@ async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput
|
|
|
2539
2563
|
}
|
|
2540
2564
|
|
|
2541
2565
|
// src/core/utils/building/internal-build.ts
|
|
2566
|
+
import managePath from "manage-path";
|
|
2567
|
+
import { resolve as resolve13, relative as relative6 } from "node:path";
|
|
2568
|
+
|
|
2569
|
+
// src/core/utils/validation.ts
|
|
2570
|
+
function validateEntrypoints(entrypoints) {
|
|
2571
|
+
const errors = entrypoints.flatMap((entrypoint) => {
|
|
2572
|
+
switch (entrypoint.type) {
|
|
2573
|
+
case "content-script":
|
|
2574
|
+
return validateContentScriptEntrypoint(entrypoint);
|
|
2575
|
+
default:
|
|
2576
|
+
return validateBaseEntrypoint(entrypoint);
|
|
2577
|
+
}
|
|
2578
|
+
});
|
|
2579
|
+
let errorCount = 0;
|
|
2580
|
+
let warningCount = 0;
|
|
2581
|
+
for (const err of errors) {
|
|
2582
|
+
if (err.type === "warning")
|
|
2583
|
+
warningCount++;
|
|
2584
|
+
else
|
|
2585
|
+
errorCount++;
|
|
2586
|
+
}
|
|
2587
|
+
return {
|
|
2588
|
+
errors,
|
|
2589
|
+
errorCount,
|
|
2590
|
+
warningCount
|
|
2591
|
+
};
|
|
2592
|
+
}
|
|
2593
|
+
function validateContentScriptEntrypoint(definition) {
|
|
2594
|
+
const errors = validateBaseEntrypoint(definition);
|
|
2595
|
+
if (definition.options.matches == null) {
|
|
2596
|
+
errors.push({
|
|
2597
|
+
type: "error",
|
|
2598
|
+
message: "`matches` is required",
|
|
2599
|
+
value: definition.options.matches,
|
|
2600
|
+
entrypoint: definition
|
|
2601
|
+
});
|
|
2602
|
+
}
|
|
2603
|
+
return errors;
|
|
2604
|
+
}
|
|
2605
|
+
function validateBaseEntrypoint(definition) {
|
|
2606
|
+
const errors = [];
|
|
2607
|
+
if (definition.options.exclude != null && !Array.isArray(definition.options.exclude)) {
|
|
2608
|
+
errors.push({
|
|
2609
|
+
type: "error",
|
|
2610
|
+
message: "`exclude` must be an array of browser names",
|
|
2611
|
+
value: definition.options.exclude,
|
|
2612
|
+
entrypoint: definition
|
|
2613
|
+
});
|
|
2614
|
+
}
|
|
2615
|
+
if (definition.options.include != null && !Array.isArray(definition.options.include)) {
|
|
2616
|
+
errors.push({
|
|
2617
|
+
type: "error",
|
|
2618
|
+
message: "`include` must be an array of browser names",
|
|
2619
|
+
value: definition.options.include,
|
|
2620
|
+
entrypoint: definition
|
|
2621
|
+
});
|
|
2622
|
+
}
|
|
2623
|
+
return errors;
|
|
2624
|
+
}
|
|
2625
|
+
var ValidationError = class extends Error {
|
|
2626
|
+
};
|
|
2627
|
+
|
|
2628
|
+
// src/core/utils/building/internal-build.ts
|
|
2629
|
+
import consola3 from "consola";
|
|
2542
2630
|
async function internalBuild(config) {
|
|
2543
2631
|
const verb = config.command === "serve" ? "Pre-rendering" : "Building";
|
|
2544
2632
|
const target = `${config.browser}-mv${config.manifestVersion}`;
|
|
@@ -2552,6 +2640,15 @@ async function internalBuild(config) {
|
|
|
2552
2640
|
await fs12.ensureDir(config.outDir);
|
|
2553
2641
|
const entrypoints = await findEntrypoints(config);
|
|
2554
2642
|
config.logger.debug("Detected entrypoints:", entrypoints);
|
|
2643
|
+
const validationResults = validateEntrypoints(entrypoints);
|
|
2644
|
+
if (validationResults.errorCount + validationResults.warningCount > 0) {
|
|
2645
|
+
printValidationResults(config, validationResults);
|
|
2646
|
+
}
|
|
2647
|
+
if (validationResults.errorCount > 0) {
|
|
2648
|
+
throw new ValidationError(`Entrypoint validation failed`, {
|
|
2649
|
+
cause: validationResults
|
|
2650
|
+
});
|
|
2651
|
+
}
|
|
2555
2652
|
const groups = groupEntrypoints(entrypoints);
|
|
2556
2653
|
const { output, warnings } = await rebuild(
|
|
2557
2654
|
config,
|
|
@@ -2584,11 +2681,35 @@ async function combineAnalysisStats(config) {
|
|
|
2584
2681
|
absolute: true
|
|
2585
2682
|
});
|
|
2586
2683
|
const absolutePaths = unixFiles.map(unnormalizePath);
|
|
2684
|
+
const alterPath = managePath(process.env);
|
|
2685
|
+
alterPath.push(resolve13(config.root, "node_modules/wxt/node_modules/.bin"));
|
|
2587
2686
|
await execaCommand(
|
|
2588
2687
|
`rollup-plugin-visualizer ${absolutePaths.join(" ")} --template ${config.analysis.template}`,
|
|
2589
2688
|
{ cwd: config.root, stdio: "inherit" }
|
|
2590
2689
|
);
|
|
2591
2690
|
}
|
|
2691
|
+
function printValidationResults(config, { errorCount, errors, warningCount }) {
|
|
2692
|
+
(errorCount > 0 ? config.logger.error : config.logger.warn)(
|
|
2693
|
+
`Entrypoint validation failed: ${errorCount} error${errorCount === 1 ? "" : "s"}, ${warningCount} warning${warningCount === 1 ? "" : "s"}`
|
|
2694
|
+
);
|
|
2695
|
+
const cwd = process.cwd();
|
|
2696
|
+
const entrypointErrors = errors.reduce((map, error) => {
|
|
2697
|
+
const entryErrors = map.get(error.entrypoint) ?? [];
|
|
2698
|
+
entryErrors.push(error);
|
|
2699
|
+
map.set(error.entrypoint, entryErrors);
|
|
2700
|
+
return map;
|
|
2701
|
+
}, /* @__PURE__ */ new Map());
|
|
2702
|
+
Array.from(entrypointErrors.entries()).forEach(([entrypoint, errors2]) => {
|
|
2703
|
+
consola3.log(relative6(cwd, entrypoint.inputPath));
|
|
2704
|
+
console.log();
|
|
2705
|
+
errors2.forEach((err) => {
|
|
2706
|
+
const type = err.type === "error" ? pc5.red("ERROR") : pc5.yellow("WARN");
|
|
2707
|
+
const recieved = pc5.dim(`(recieved: ${JSON.stringify(err.value)})`);
|
|
2708
|
+
consola3.log(` - ${type} ${err.message} ${recieved}`);
|
|
2709
|
+
});
|
|
2710
|
+
console.log();
|
|
2711
|
+
});
|
|
2712
|
+
}
|
|
2592
2713
|
|
|
2593
2714
|
// src/core/build.ts
|
|
2594
2715
|
async function build(config) {
|
|
@@ -2600,17 +2721,17 @@ async function build(config) {
|
|
|
2600
2721
|
import path5 from "node:path";
|
|
2601
2722
|
import glob4 from "fast-glob";
|
|
2602
2723
|
import fs13 from "fs-extra";
|
|
2603
|
-
import { consola as
|
|
2724
|
+
import { consola as consola4 } from "consola";
|
|
2604
2725
|
import pc6 from "picocolors";
|
|
2605
2726
|
async function clean(root = process.cwd()) {
|
|
2606
|
-
|
|
2727
|
+
consola4.info("Cleaning Project");
|
|
2607
2728
|
const tempDirs = [
|
|
2608
2729
|
"node_modules/.vite",
|
|
2609
2730
|
"node_modules/.cache",
|
|
2610
2731
|
"**/.wxt",
|
|
2611
2732
|
".output/*"
|
|
2612
2733
|
];
|
|
2613
|
-
|
|
2734
|
+
consola4.debug("Looking for:", tempDirs.map(pc6.cyan).join(", "));
|
|
2614
2735
|
const directories = await glob4(tempDirs, {
|
|
2615
2736
|
cwd: path5.resolve(root),
|
|
2616
2737
|
absolute: true,
|
|
@@ -2618,26 +2739,26 @@ async function clean(root = process.cwd()) {
|
|
|
2618
2739
|
deep: 2
|
|
2619
2740
|
});
|
|
2620
2741
|
if (directories.length === 0) {
|
|
2621
|
-
|
|
2742
|
+
consola4.debug("No generated files found.");
|
|
2622
2743
|
return;
|
|
2623
2744
|
}
|
|
2624
|
-
|
|
2745
|
+
consola4.debug(
|
|
2625
2746
|
"Found:",
|
|
2626
2747
|
directories.map((dir) => pc6.cyan(path5.relative(root, dir))).join(", ")
|
|
2627
2748
|
);
|
|
2628
2749
|
for (const directory of directories) {
|
|
2629
2750
|
await fs13.rm(directory, { force: true, recursive: true });
|
|
2630
|
-
|
|
2751
|
+
consola4.debug("Deleted " + pc6.cyan(path5.relative(root, directory)));
|
|
2631
2752
|
}
|
|
2632
2753
|
}
|
|
2633
2754
|
|
|
2634
2755
|
// src/core/runners/wsl.ts
|
|
2635
|
-
import { relative as
|
|
2756
|
+
import { relative as relative7 } from "node:path";
|
|
2636
2757
|
function createWslRunner() {
|
|
2637
2758
|
return {
|
|
2638
2759
|
async openBrowser(config) {
|
|
2639
2760
|
config.logger.warn(
|
|
2640
|
-
`Cannot open browser when using WSL. Load "${
|
|
2761
|
+
`Cannot open browser when using WSL. Load "${relative7(
|
|
2641
2762
|
process.cwd(),
|
|
2642
2763
|
config.outDir
|
|
2643
2764
|
)}" as an unpacked extension manually`
|
|
@@ -2653,7 +2774,7 @@ function createWebExtRunner() {
|
|
|
2653
2774
|
let runner;
|
|
2654
2775
|
return {
|
|
2655
2776
|
async openBrowser(config) {
|
|
2656
|
-
|
|
2777
|
+
const startTime = Date.now();
|
|
2657
2778
|
if (config.browser === "firefox" && config.manifestVersion === 3) {
|
|
2658
2779
|
throw Error(
|
|
2659
2780
|
"Dev mode does not support Firefox MV3. For alternatives, see https://github.com/wxt-dev/wxt/issues/230#issuecomment-1806881653"
|
|
@@ -2698,7 +2819,8 @@ function createWebExtRunner() {
|
|
|
2698
2819
|
config.logger.debug("web-ext options:", options);
|
|
2699
2820
|
const webExt = await import("web-ext-run");
|
|
2700
2821
|
runner = await webExt.default.cmd.run(finalConfig, options);
|
|
2701
|
-
|
|
2822
|
+
const duration = Date.now() - startTime;
|
|
2823
|
+
config.logger.success(`Opened browser in ${formatDuration(duration)}`);
|
|
2702
2824
|
},
|
|
2703
2825
|
async closeBrowser() {
|
|
2704
2826
|
return await runner?.exit();
|
|
@@ -2709,12 +2831,12 @@ var WARN_LOG_LEVEL = 40;
|
|
|
2709
2831
|
var ERROR_LOG_LEVEL = 50;
|
|
2710
2832
|
|
|
2711
2833
|
// src/core/runners/safari.ts
|
|
2712
|
-
import { relative as
|
|
2834
|
+
import { relative as relative8 } from "node:path";
|
|
2713
2835
|
function createSafariRunner() {
|
|
2714
2836
|
return {
|
|
2715
2837
|
async openBrowser(config) {
|
|
2716
2838
|
config.logger.warn(
|
|
2717
|
-
`Cannot Safari using web-ext. Load "${
|
|
2839
|
+
`Cannot Safari using web-ext. Load "${relative8(
|
|
2718
2840
|
process.cwd(),
|
|
2719
2841
|
config.outDir
|
|
2720
2842
|
)}" as an unpacked extension manually`
|
|
@@ -2726,12 +2848,12 @@ function createSafariRunner() {
|
|
|
2726
2848
|
}
|
|
2727
2849
|
|
|
2728
2850
|
// src/core/runners/manual.ts
|
|
2729
|
-
import { relative as
|
|
2851
|
+
import { relative as relative9 } from "node:path";
|
|
2730
2852
|
function createManualRunner() {
|
|
2731
2853
|
return {
|
|
2732
2854
|
async openBrowser(config) {
|
|
2733
2855
|
config.logger.info(
|
|
2734
|
-
`Load "${
|
|
2856
|
+
`Load "${relative9(
|
|
2735
2857
|
process.cwd(),
|
|
2736
2858
|
config.outDir
|
|
2737
2859
|
)}" as an unpacked extension manually`
|
|
@@ -2760,10 +2882,10 @@ async function createExtensionRunner(config) {
|
|
|
2760
2882
|
}
|
|
2761
2883
|
|
|
2762
2884
|
// src/core/create-server.ts
|
|
2763
|
-
import { consola as
|
|
2885
|
+
import { consola as consola5 } from "consola";
|
|
2764
2886
|
import { Mutex } from "async-mutex";
|
|
2765
2887
|
import pc7 from "picocolors";
|
|
2766
|
-
import { relative as
|
|
2888
|
+
import { relative as relative10 } from "node:path";
|
|
2767
2889
|
async function createServer(inlineConfig) {
|
|
2768
2890
|
const port = await getPort();
|
|
2769
2891
|
const hostname = "localhost";
|
|
@@ -2773,19 +2895,36 @@ async function createServer(inlineConfig) {
|
|
|
2773
2895
|
hostname,
|
|
2774
2896
|
origin
|
|
2775
2897
|
};
|
|
2898
|
+
const buildAndOpenBrowser = async () => {
|
|
2899
|
+
server.currentOutput = await internalBuild(config);
|
|
2900
|
+
await runner.openBrowser(config);
|
|
2901
|
+
};
|
|
2902
|
+
const closeAndRecreateRunner = async () => {
|
|
2903
|
+
await runner.closeBrowser();
|
|
2904
|
+
config = await getLatestConfig();
|
|
2905
|
+
runner = await createExtensionRunner(config);
|
|
2906
|
+
};
|
|
2776
2907
|
const server = {
|
|
2777
2908
|
...serverInfo,
|
|
2778
|
-
watcher
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2909
|
+
get watcher() {
|
|
2910
|
+
return builderServer.watcher;
|
|
2911
|
+
},
|
|
2912
|
+
get ws() {
|
|
2913
|
+
return builderServer.ws;
|
|
2914
|
+
},
|
|
2782
2915
|
currentOutput: void 0,
|
|
2783
|
-
// Filled out later down below
|
|
2784
2916
|
async start() {
|
|
2785
2917
|
await builderServer.listen();
|
|
2786
2918
|
config.logger.success(`Started dev server @ ${serverInfo.origin}`);
|
|
2787
|
-
|
|
2788
|
-
|
|
2919
|
+
await buildAndOpenBrowser();
|
|
2920
|
+
},
|
|
2921
|
+
async stop() {
|
|
2922
|
+
await runner.closeBrowser();
|
|
2923
|
+
await builderServer.close();
|
|
2924
|
+
},
|
|
2925
|
+
async restart() {
|
|
2926
|
+
await closeAndRecreateRunner();
|
|
2927
|
+
await buildAndOpenBrowser();
|
|
2789
2928
|
},
|
|
2790
2929
|
transformHtml(url, html, originalUrl) {
|
|
2791
2930
|
return builderServer.transformHtml(url, html, originalUrl);
|
|
@@ -2798,17 +2937,21 @@ async function createServer(inlineConfig) {
|
|
|
2798
2937
|
},
|
|
2799
2938
|
reloadExtension() {
|
|
2800
2939
|
server.ws.send("wxt:reload-extension");
|
|
2940
|
+
},
|
|
2941
|
+
async restartBrowser() {
|
|
2942
|
+
await closeAndRecreateRunner();
|
|
2943
|
+
await runner.openBrowser(config);
|
|
2801
2944
|
}
|
|
2802
2945
|
};
|
|
2803
2946
|
const getLatestConfig = () => getInternalConfig(inlineConfig ?? {}, "serve", server);
|
|
2804
2947
|
let config = await getLatestConfig();
|
|
2805
|
-
|
|
2948
|
+
let [runner, builderServer] = await Promise.all([
|
|
2806
2949
|
createExtensionRunner(config),
|
|
2807
2950
|
config.builder.createServer(server)
|
|
2808
2951
|
]);
|
|
2809
|
-
server.watcher = builderServer.watcher;
|
|
2810
|
-
server.ws = builderServer.ws;
|
|
2811
2952
|
server.ws.on("wxt:background-initialized", () => {
|
|
2953
|
+
if (server.currentOutput == null)
|
|
2954
|
+
return;
|
|
2812
2955
|
reloadContentScripts(server.currentOutput.steps, config, server);
|
|
2813
2956
|
});
|
|
2814
2957
|
const reloadOnChange = createFileReloader({
|
|
@@ -2836,18 +2979,34 @@ function createFileReloader(options) {
|
|
|
2836
2979
|
return;
|
|
2837
2980
|
changeQueue.push([event, path7]);
|
|
2838
2981
|
await fileChangedMutex.runExclusive(async () => {
|
|
2839
|
-
|
|
2982
|
+
if (server.currentOutput == null)
|
|
2983
|
+
return;
|
|
2984
|
+
const fileChanges = changeQueue.splice(0, changeQueue.length).map(([_, file]) => file);
|
|
2840
2985
|
if (fileChanges.length === 0)
|
|
2841
2986
|
return;
|
|
2842
|
-
const changes = detectDevChanges(
|
|
2987
|
+
const changes = detectDevChanges(
|
|
2988
|
+
config,
|
|
2989
|
+
fileChanges,
|
|
2990
|
+
server.currentOutput
|
|
2991
|
+
);
|
|
2843
2992
|
if (changes.type === "no-change")
|
|
2844
2993
|
return;
|
|
2994
|
+
if (changes.type === "full-restart") {
|
|
2995
|
+
config.logger.info("Config changed, restarting server...");
|
|
2996
|
+
server.restart();
|
|
2997
|
+
return;
|
|
2998
|
+
}
|
|
2999
|
+
if (changes.type === "browser-restart") {
|
|
3000
|
+
config.logger.info("Runner config changed, restarting browser...");
|
|
3001
|
+
server.restartBrowser();
|
|
3002
|
+
return;
|
|
3003
|
+
}
|
|
2845
3004
|
config.logger.info(
|
|
2846
|
-
`Changed: ${Array.from(new Set(fileChanges
|
|
3005
|
+
`Changed: ${Array.from(new Set(fileChanges)).map((file) => pc7.dim(relative10(config.root, file))).join(", ")}`
|
|
2847
3006
|
);
|
|
2848
3007
|
const rebuiltNames = changes.rebuildGroups.flat().map((entry) => {
|
|
2849
3008
|
return pc7.cyan(
|
|
2850
|
-
|
|
3009
|
+
relative10(config.outDir, getEntrypointOutputFile(entry, ""))
|
|
2851
3010
|
);
|
|
2852
3011
|
}).join(pc7.dim(", "));
|
|
2853
3012
|
const allEntrypoints = await findEntrypoints(config);
|
|
@@ -2870,13 +3029,15 @@ function createFileReloader(options) {
|
|
|
2870
3029
|
reloadContentScripts(changes.changedSteps, config, server);
|
|
2871
3030
|
break;
|
|
2872
3031
|
}
|
|
2873
|
-
|
|
3032
|
+
consola5.success(`Reloaded: ${rebuiltNames}`);
|
|
2874
3033
|
});
|
|
2875
3034
|
};
|
|
2876
3035
|
}
|
|
2877
3036
|
function reloadContentScripts(steps, config, server) {
|
|
2878
3037
|
if (config.manifestVersion === 3) {
|
|
2879
3038
|
steps.forEach((step) => {
|
|
3039
|
+
if (server.currentOutput == null)
|
|
3040
|
+
return;
|
|
2880
3041
|
const entry = step.entrypoints;
|
|
2881
3042
|
if (Array.isArray(entry) || entry.type !== "content-script")
|
|
2882
3043
|
return;
|
|
@@ -2913,13 +3074,13 @@ function reloadHtmlPages(groups, server, config) {
|
|
|
2913
3074
|
|
|
2914
3075
|
// src/core/initialize.ts
|
|
2915
3076
|
import prompts from "prompts";
|
|
2916
|
-
import { consola as
|
|
3077
|
+
import { consola as consola6 } from "consola";
|
|
2917
3078
|
import { downloadTemplate } from "giget";
|
|
2918
3079
|
import fs14 from "fs-extra";
|
|
2919
3080
|
import path6 from "node:path";
|
|
2920
3081
|
import pc8 from "picocolors";
|
|
2921
3082
|
async function initialize(options) {
|
|
2922
|
-
|
|
3083
|
+
consola6.info("Initalizing new project");
|
|
2923
3084
|
const templates = await listTemplates();
|
|
2924
3085
|
const defaultTemplate = templates.find(
|
|
2925
3086
|
(template) => template.name === options.template?.toLowerCase().trim()
|
|
@@ -2966,15 +3127,15 @@ async function initialize(options) {
|
|
|
2966
3127
|
await cloneProject(input);
|
|
2967
3128
|
const cdPath = path6.relative(process.cwd(), path6.resolve(input.directory));
|
|
2968
3129
|
console.log();
|
|
2969
|
-
|
|
3130
|
+
consola6.log(
|
|
2970
3131
|
`\u2728 WXT project created with the ${TEMPLATE_COLORS[input.template.name]?.(input.template.name) ?? input.template.name} template.`
|
|
2971
3132
|
);
|
|
2972
3133
|
console.log();
|
|
2973
|
-
|
|
3134
|
+
consola6.log("Next steps:");
|
|
2974
3135
|
let step = 0;
|
|
2975
3136
|
if (cdPath !== "")
|
|
2976
|
-
|
|
2977
|
-
|
|
3137
|
+
consola6.log(` ${++step}.`, pc8.cyan(`cd ${cdPath}`));
|
|
3138
|
+
consola6.log(` ${++step}.`, pc8.cyan(`${input.packageManager} install`));
|
|
2978
3139
|
console.log();
|
|
2979
3140
|
}
|
|
2980
3141
|
async function listTemplates() {
|
|
@@ -3019,7 +3180,7 @@ async function cloneProject({
|
|
|
3019
3180
|
path6.join(directory, "_gitignore"),
|
|
3020
3181
|
path6.join(directory, ".gitignore")
|
|
3021
3182
|
).catch(
|
|
3022
|
-
(err) =>
|
|
3183
|
+
(err) => consola6.warn("Failed to move _gitignore to .gitignore:", err)
|
|
3023
3184
|
);
|
|
3024
3185
|
spinner.succeed();
|
|
3025
3186
|
} catch (err) {
|
|
@@ -3050,7 +3211,7 @@ async function prepare(config) {
|
|
|
3050
3211
|
|
|
3051
3212
|
// src/core/zip.ts
|
|
3052
3213
|
import zipdir from "zip-dir";
|
|
3053
|
-
import { dirname as dirname5, relative as
|
|
3214
|
+
import { dirname as dirname5, relative as relative11, resolve as resolve14 } from "node:path";
|
|
3054
3215
|
import fs15 from "fs-extra";
|
|
3055
3216
|
import { minimatch as minimatch2 } from "minimatch";
|
|
3056
3217
|
async function zip(config) {
|
|
@@ -3068,7 +3229,7 @@ async function zip(config) {
|
|
|
3068
3229
|
).replaceAll("{{manifestVersion}}", `mv${internalConfig.manifestVersion}`);
|
|
3069
3230
|
await fs15.ensureDir(internalConfig.outBaseDir);
|
|
3070
3231
|
const outZipFilename = applyTemplate(internalConfig.zip.artifactTemplate);
|
|
3071
|
-
const outZipPath =
|
|
3232
|
+
const outZipPath = resolve14(internalConfig.outBaseDir, outZipFilename);
|
|
3072
3233
|
await zipdir(internalConfig.outDir, {
|
|
3073
3234
|
saveTo: outZipPath
|
|
3074
3235
|
});
|
|
@@ -3077,14 +3238,14 @@ async function zip(config) {
|
|
|
3077
3238
|
const sourcesZipFilename = applyTemplate(
|
|
3078
3239
|
internalConfig.zip.sourcesTemplate
|
|
3079
3240
|
);
|
|
3080
|
-
const sourcesZipPath =
|
|
3241
|
+
const sourcesZipPath = resolve14(
|
|
3081
3242
|
internalConfig.outBaseDir,
|
|
3082
3243
|
sourcesZipFilename
|
|
3083
3244
|
);
|
|
3084
3245
|
await zipdir(internalConfig.zip.sourcesRoot, {
|
|
3085
3246
|
saveTo: sourcesZipPath,
|
|
3086
3247
|
filter(path7) {
|
|
3087
|
-
const relativePath =
|
|
3248
|
+
const relativePath = relative11(internalConfig.zip.sourcesRoot, path7);
|
|
3088
3249
|
const matchedPattern = internalConfig.zip.ignoredSources.find(
|
|
3089
3250
|
(pattern) => minimatch2(relativePath, pattern)
|
|
3090
3251
|
);
|
|
@@ -3103,7 +3264,7 @@ async function zip(config) {
|
|
|
3103
3264
|
}
|
|
3104
3265
|
|
|
3105
3266
|
// src/cli.ts
|
|
3106
|
-
import
|
|
3267
|
+
import consola7, { LogLevels as LogLevels2 } from "consola";
|
|
3107
3268
|
process.env.VITE_CJS_IGNORE_WARNING = "true";
|
|
3108
3269
|
var cli = cac("wxt");
|
|
3109
3270
|
cli.help();
|
|
@@ -3193,21 +3354,24 @@ function wrapAction(cb, options) {
|
|
|
3193
3354
|
return async (...args) => {
|
|
3194
3355
|
const isDebug = !!args.find((arg) => arg?.debug);
|
|
3195
3356
|
if (isDebug) {
|
|
3196
|
-
|
|
3357
|
+
consola7.level = LogLevels2.debug;
|
|
3197
3358
|
}
|
|
3198
3359
|
const startTime = Date.now();
|
|
3199
3360
|
try {
|
|
3200
3361
|
printHeader();
|
|
3201
3362
|
const status = await cb(...args);
|
|
3202
3363
|
if (!status?.isOngoing && !options?.disableFinishedLog)
|
|
3203
|
-
|
|
3364
|
+
consola7.success(
|
|
3204
3365
|
`Finished in ${formatDuration(Date.now() - startTime)}`
|
|
3205
3366
|
);
|
|
3206
3367
|
} catch (err) {
|
|
3207
|
-
|
|
3368
|
+
consola7.fail(
|
|
3208
3369
|
`Command failed after ${formatDuration(Date.now() - startTime)}`
|
|
3209
3370
|
);
|
|
3210
|
-
|
|
3371
|
+
if (err instanceof ValidationError) {
|
|
3372
|
+
} else {
|
|
3373
|
+
consola7.error(err);
|
|
3374
|
+
}
|
|
3211
3375
|
process.exit(1);
|
|
3212
3376
|
}
|
|
3213
3377
|
};
|
|
@@ -388,15 +388,23 @@ interface BuildStepOutput {
|
|
|
388
388
|
entrypoints: EntrypointGroup;
|
|
389
389
|
chunks: OutputFile[];
|
|
390
390
|
}
|
|
391
|
-
interface WxtDevServer extends Omit<WxtBuilderServer, 'listen'>, ServerInfo {
|
|
391
|
+
interface WxtDevServer extends Omit<WxtBuilderServer, 'listen' | 'close'>, ServerInfo {
|
|
392
392
|
/**
|
|
393
393
|
* Stores the current build output of the server.
|
|
394
394
|
*/
|
|
395
|
-
currentOutput: BuildOutput;
|
|
395
|
+
currentOutput: BuildOutput | undefined;
|
|
396
396
|
/**
|
|
397
397
|
* Start the server.
|
|
398
398
|
*/
|
|
399
399
|
start(): Promise<void>;
|
|
400
|
+
/**
|
|
401
|
+
* Stop the server.
|
|
402
|
+
*/
|
|
403
|
+
stop(): Promise<void>;
|
|
404
|
+
/**
|
|
405
|
+
* Close the browser, stop the server, rebuild the entire extension, and start the server again.
|
|
406
|
+
*/
|
|
407
|
+
restart(): Promise<void>;
|
|
400
408
|
/**
|
|
401
409
|
* Transform the HTML for dev mode.
|
|
402
410
|
*/
|
|
@@ -423,6 +431,10 @@ interface WxtDevServer extends Omit<WxtBuilderServer, 'listen'>, ServerInfo {
|
|
|
423
431
|
* @param contentScript The manifest definition for a content script
|
|
424
432
|
*/
|
|
425
433
|
reloadContentScript: (contentScript: Omit<Scripting.RegisteredContentScript, 'id'>) => void;
|
|
434
|
+
/**
|
|
435
|
+
* Grab the latest runner config and restart the browser.
|
|
436
|
+
*/
|
|
437
|
+
restartBrowser: () => void;
|
|
426
438
|
}
|
|
427
439
|
type TargetBrowser = string;
|
|
428
440
|
type TargetManifestVersion = 2 | 3;
|
|
@@ -704,6 +716,10 @@ interface WxtBuilderServer {
|
|
|
704
716
|
* Start the server.
|
|
705
717
|
*/
|
|
706
718
|
listen(): Promise<void>;
|
|
719
|
+
/**
|
|
720
|
+
* Stop the server.
|
|
721
|
+
*/
|
|
722
|
+
close(): Promise<void>;
|
|
707
723
|
/**
|
|
708
724
|
* Transform the HTML for dev mode.
|
|
709
725
|
*/
|
|
@@ -388,15 +388,23 @@ interface BuildStepOutput {
|
|
|
388
388
|
entrypoints: EntrypointGroup;
|
|
389
389
|
chunks: OutputFile[];
|
|
390
390
|
}
|
|
391
|
-
interface WxtDevServer extends Omit<WxtBuilderServer, 'listen'>, ServerInfo {
|
|
391
|
+
interface WxtDevServer extends Omit<WxtBuilderServer, 'listen' | 'close'>, ServerInfo {
|
|
392
392
|
/**
|
|
393
393
|
* Stores the current build output of the server.
|
|
394
394
|
*/
|
|
395
|
-
currentOutput: BuildOutput;
|
|
395
|
+
currentOutput: BuildOutput | undefined;
|
|
396
396
|
/**
|
|
397
397
|
* Start the server.
|
|
398
398
|
*/
|
|
399
399
|
start(): Promise<void>;
|
|
400
|
+
/**
|
|
401
|
+
* Stop the server.
|
|
402
|
+
*/
|
|
403
|
+
stop(): Promise<void>;
|
|
404
|
+
/**
|
|
405
|
+
* Close the browser, stop the server, rebuild the entire extension, and start the server again.
|
|
406
|
+
*/
|
|
407
|
+
restart(): Promise<void>;
|
|
400
408
|
/**
|
|
401
409
|
* Transform the HTML for dev mode.
|
|
402
410
|
*/
|
|
@@ -423,6 +431,10 @@ interface WxtDevServer extends Omit<WxtBuilderServer, 'listen'>, ServerInfo {
|
|
|
423
431
|
* @param contentScript The manifest definition for a content script
|
|
424
432
|
*/
|
|
425
433
|
reloadContentScript: (contentScript: Omit<Scripting.RegisteredContentScript, 'id'>) => void;
|
|
434
|
+
/**
|
|
435
|
+
* Grab the latest runner config and restart the browser.
|
|
436
|
+
*/
|
|
437
|
+
restartBrowser: () => void;
|
|
426
438
|
}
|
|
427
439
|
type TargetBrowser = string;
|
|
428
440
|
type TargetManifestVersion = 2 | 3;
|
|
@@ -704,6 +716,10 @@ interface WxtBuilderServer {
|
|
|
704
716
|
* Start the server.
|
|
705
717
|
*/
|
|
706
718
|
listen(): Promise<void>;
|
|
719
|
+
/**
|
|
720
|
+
* Stop the server.
|
|
721
|
+
*/
|
|
722
|
+
close(): Promise<void>;
|
|
707
723
|
/**
|
|
708
724
|
* Transform the HTML for dev mode.
|
|
709
725
|
*/
|