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.
- package/dist/{chunk-LETSPJCU.js → chunk-XDRW7AKZ.js} +169 -31
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +254 -73
- package/dist/{external-QOQPHF1G.d.cts → external-mJ1bW7iy.d.cts} +36 -2
- package/dist/{external-QOQPHF1G.d.ts → external-mJ1bW7iy.d.ts} +36 -2
- package/dist/index.cjs +266 -88
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +56 -16
- package/dist/testing.cjs +18 -2
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/package.json +4 -1
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.6";
|
|
9
9
|
|
|
10
10
|
// src/core/utils/fs.ts
|
|
11
11
|
import fs from "fs-extra";
|
|
@@ -77,11 +77,27 @@ function every(array, predicate) {
|
|
|
77
77
|
return false;
|
|
78
78
|
return true;
|
|
79
79
|
}
|
|
80
|
+
function some(array, predicate) {
|
|
81
|
+
for (let i = 0; i < array.length; i++)
|
|
82
|
+
if (predicate(array[i], i))
|
|
83
|
+
return true;
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
80
86
|
|
|
81
87
|
// src/core/utils/building/detect-dev-changes.ts
|
|
82
|
-
function detectDevChanges(changedFiles, currentOutput) {
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
function detectDevChanges(config, changedFiles, currentOutput) {
|
|
89
|
+
const isConfigChange = some(
|
|
90
|
+
changedFiles,
|
|
91
|
+
(file) => file === config.userConfigMetadata.configFile
|
|
92
|
+
);
|
|
93
|
+
if (isConfigChange)
|
|
94
|
+
return { type: "full-restart" };
|
|
95
|
+
const isRunnerChange = some(
|
|
96
|
+
changedFiles,
|
|
97
|
+
(file) => file === config.runnerConfig.configFile
|
|
98
|
+
);
|
|
99
|
+
if (isRunnerChange)
|
|
100
|
+
return { type: "browser-restart" };
|
|
85
101
|
const changedSteps = new Set(
|
|
86
102
|
changedFiles.flatMap(
|
|
87
103
|
(changedFile) => findEffectedSteps(changedFile, currentOutput)
|
|
@@ -113,7 +129,7 @@ function detectDevChanges(changedFiles, currentOutput) {
|
|
|
113
129
|
unchangedOutput.publicAssets.push(asset);
|
|
114
130
|
}
|
|
115
131
|
}
|
|
116
|
-
const isOnlyHtmlChanges = changedFiles.length > 0 && every(changedFiles, (
|
|
132
|
+
const isOnlyHtmlChanges = changedFiles.length > 0 && every(changedFiles, (file) => file.endsWith(".html"));
|
|
117
133
|
if (isOnlyHtmlChanges) {
|
|
118
134
|
return {
|
|
119
135
|
type: "html-reload",
|
|
@@ -141,7 +157,7 @@ function detectDevChanges(changedFiles, currentOutput) {
|
|
|
141
157
|
}
|
|
142
158
|
function findEffectedSteps(changedFile, currentOutput) {
|
|
143
159
|
const changes = [];
|
|
144
|
-
const changedPath = normalizePath(changedFile
|
|
160
|
+
const changedPath = normalizePath(changedFile);
|
|
145
161
|
const isChunkEffected = (chunk) => (
|
|
146
162
|
// If it's an HTML file with the same path, is is effected because HTML files need to be pre-rendered
|
|
147
163
|
// fileName is normalized, relative bundle path
|
|
@@ -1489,6 +1505,9 @@ async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
|
|
|
1489
1505
|
async listen() {
|
|
1490
1506
|
await viteServer.listen(info.port);
|
|
1491
1507
|
},
|
|
1508
|
+
async close() {
|
|
1509
|
+
await viteServer.close();
|
|
1510
|
+
},
|
|
1492
1511
|
transformHtml(...args) {
|
|
1493
1512
|
return viteServer.transformIndexHtml(...args);
|
|
1494
1513
|
},
|
|
@@ -1554,6 +1573,7 @@ async function getInternalConfig(inlineConfig, command, server) {
|
|
|
1554
1573
|
const typesDir = path3.resolve(wxtDir, "types");
|
|
1555
1574
|
const outBaseDir = path3.resolve(root, mergedConfig.outDir ?? ".output");
|
|
1556
1575
|
const outDir = path3.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
|
|
1576
|
+
const reloadCommand = mergedConfig.dev?.reloadCommand ?? "Alt+R";
|
|
1557
1577
|
const runnerConfig = await loadConfig({
|
|
1558
1578
|
name: "web-ext",
|
|
1559
1579
|
cwd: root,
|
|
@@ -1606,7 +1626,10 @@ async function getInternalConfig(inlineConfig, command, server) {
|
|
|
1606
1626
|
experimental: {
|
|
1607
1627
|
includeBrowserPolyfill: mergedConfig.experimental?.includeBrowserPolyfill ?? true
|
|
1608
1628
|
},
|
|
1609
|
-
server
|
|
1629
|
+
server,
|
|
1630
|
+
dev: {
|
|
1631
|
+
reloadCommand
|
|
1632
|
+
}
|
|
1610
1633
|
};
|
|
1611
1634
|
const builder = await createViteBuilder(
|
|
1612
1635
|
inlineConfig,
|
|
@@ -1673,7 +1696,11 @@ function mergeInlineConfig(inlineConfig, userConfig) {
|
|
|
1673
1696
|
...inlineConfig.experimental
|
|
1674
1697
|
},
|
|
1675
1698
|
vite: void 0,
|
|
1676
|
-
transformManifest: void 0
|
|
1699
|
+
transformManifest: void 0,
|
|
1700
|
+
dev: {
|
|
1701
|
+
...userConfig.dev,
|
|
1702
|
+
...inlineConfig.dev
|
|
1703
|
+
}
|
|
1677
1704
|
};
|
|
1678
1705
|
}
|
|
1679
1706
|
function resolveInternalZipConfig(root, mergedConfig) {
|
|
@@ -2089,6 +2116,7 @@ async function writeManifest(manifest, output, config) {
|
|
|
2089
2116
|
});
|
|
2090
2117
|
}
|
|
2091
2118
|
async function generateManifest(entrypoints, buildOutput, config) {
|
|
2119
|
+
const warnings = [];
|
|
2092
2120
|
const pkg = await getPackageJson(config);
|
|
2093
2121
|
let versionName = config.manifest.version_name ?? config.manifest.version ?? pkg?.version;
|
|
2094
2122
|
if (versionName == null) {
|
|
@@ -2106,21 +2134,26 @@ async function generateManifest(entrypoints, buildOutput, config) {
|
|
|
2106
2134
|
short_name: pkg?.shortName,
|
|
2107
2135
|
icons: discoverIcons(buildOutput)
|
|
2108
2136
|
};
|
|
2109
|
-
if (config.command === "serve") {
|
|
2110
|
-
baseManifest.commands = {
|
|
2111
|
-
"wxt:reload-extension": {
|
|
2112
|
-
description: "Reload the extension during development",
|
|
2113
|
-
suggested_key: {
|
|
2114
|
-
default: "Alt+R"
|
|
2115
|
-
}
|
|
2116
|
-
}
|
|
2117
|
-
};
|
|
2118
|
-
}
|
|
2119
2137
|
const userManifest = config.manifest;
|
|
2120
2138
|
const manifest = defu3(
|
|
2121
2139
|
userManifest,
|
|
2122
2140
|
baseManifest
|
|
2123
2141
|
);
|
|
2142
|
+
if (config.command === "serve" && config.dev.reloadCommand) {
|
|
2143
|
+
if (manifest.commands && Object.keys(manifest.commands).length >= 4) {
|
|
2144
|
+
warnings.push([
|
|
2145
|
+
"Extension already has 4 registered commands, WXT's reload command is disabled"
|
|
2146
|
+
]);
|
|
2147
|
+
} else {
|
|
2148
|
+
manifest.commands ??= {};
|
|
2149
|
+
manifest.commands["wxt:reload-extension"] = {
|
|
2150
|
+
description: "Reload the extension during development",
|
|
2151
|
+
suggested_key: {
|
|
2152
|
+
default: config.dev.reloadCommand
|
|
2153
|
+
}
|
|
2154
|
+
};
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2124
2157
|
manifest.version = version2;
|
|
2125
2158
|
manifest.version_name = // Firefox doesn't support version_name
|
|
2126
2159
|
config.browser === "firefox" || versionName === version2 ? void 0 : versionName;
|
|
@@ -2139,7 +2172,10 @@ async function generateManifest(entrypoints, buildOutput, config) {
|
|
|
2139
2172
|
"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"
|
|
2140
2173
|
);
|
|
2141
2174
|
}
|
|
2142
|
-
return
|
|
2175
|
+
return {
|
|
2176
|
+
manifest: finalManifest,
|
|
2177
|
+
warnings
|
|
2178
|
+
};
|
|
2143
2179
|
}
|
|
2144
2180
|
function simplifyVersion(versionName) {
|
|
2145
2181
|
const version2 = /^((0|[1-9][0-9]{0,8})([.](0|[1-9][0-9]{0,8})){0,3}).*$/.exec(
|
|
@@ -2500,11 +2536,7 @@ async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput
|
|
|
2500
2536
|
steps: [...existingOutput.steps, ...newOutput.steps],
|
|
2501
2537
|
publicAssets: [...existingOutput.publicAssets, ...newOutput.publicAssets]
|
|
2502
2538
|
};
|
|
2503
|
-
const newManifest = await generateManifest(
|
|
2504
|
-
allEntrypoints,
|
|
2505
|
-
mergedOutput,
|
|
2506
|
-
config
|
|
2507
|
-
);
|
|
2539
|
+
const { manifest: newManifest, warnings: manifestWarnings } = await generateManifest(allEntrypoints, mergedOutput, config);
|
|
2508
2540
|
const finalOutput = {
|
|
2509
2541
|
manifest: newManifest,
|
|
2510
2542
|
...newOutput
|
|
@@ -2520,11 +2552,76 @@ async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput
|
|
|
2520
2552
|
...finalOutput.publicAssets
|
|
2521
2553
|
]
|
|
2522
2554
|
},
|
|
2523
|
-
manifest: newManifest
|
|
2555
|
+
manifest: newManifest,
|
|
2556
|
+
warnings: manifestWarnings
|
|
2524
2557
|
};
|
|
2525
2558
|
}
|
|
2526
2559
|
|
|
2527
2560
|
// src/core/utils/building/internal-build.ts
|
|
2561
|
+
import managePath from "manage-path";
|
|
2562
|
+
import { resolve as resolve13, relative as relative6 } from "node:path";
|
|
2563
|
+
|
|
2564
|
+
// src/core/utils/validation.ts
|
|
2565
|
+
function validateEntrypoints(entrypoints) {
|
|
2566
|
+
const errors = entrypoints.flatMap((entrypoint) => {
|
|
2567
|
+
switch (entrypoint.type) {
|
|
2568
|
+
case "content-script":
|
|
2569
|
+
return validateContentScriptEntrypoint(entrypoint);
|
|
2570
|
+
default:
|
|
2571
|
+
return validateBaseEntrypoint(entrypoint);
|
|
2572
|
+
}
|
|
2573
|
+
});
|
|
2574
|
+
let errorCount = 0;
|
|
2575
|
+
let warningCount = 0;
|
|
2576
|
+
for (const err of errors) {
|
|
2577
|
+
if (err.type === "warning")
|
|
2578
|
+
warningCount++;
|
|
2579
|
+
else
|
|
2580
|
+
errorCount++;
|
|
2581
|
+
}
|
|
2582
|
+
return {
|
|
2583
|
+
errors,
|
|
2584
|
+
errorCount,
|
|
2585
|
+
warningCount
|
|
2586
|
+
};
|
|
2587
|
+
}
|
|
2588
|
+
function validateContentScriptEntrypoint(definition) {
|
|
2589
|
+
const errors = validateBaseEntrypoint(definition);
|
|
2590
|
+
if (definition.options.matches == null) {
|
|
2591
|
+
errors.push({
|
|
2592
|
+
type: "error",
|
|
2593
|
+
message: "`matches` is required",
|
|
2594
|
+
value: definition.options.matches,
|
|
2595
|
+
entrypoint: definition
|
|
2596
|
+
});
|
|
2597
|
+
}
|
|
2598
|
+
return errors;
|
|
2599
|
+
}
|
|
2600
|
+
function validateBaseEntrypoint(definition) {
|
|
2601
|
+
const errors = [];
|
|
2602
|
+
if (definition.options.exclude != null && !Array.isArray(definition.options.exclude)) {
|
|
2603
|
+
errors.push({
|
|
2604
|
+
type: "error",
|
|
2605
|
+
message: "`exclude` must be an array of browser names",
|
|
2606
|
+
value: definition.options.exclude,
|
|
2607
|
+
entrypoint: definition
|
|
2608
|
+
});
|
|
2609
|
+
}
|
|
2610
|
+
if (definition.options.include != null && !Array.isArray(definition.options.include)) {
|
|
2611
|
+
errors.push({
|
|
2612
|
+
type: "error",
|
|
2613
|
+
message: "`include` must be an array of browser names",
|
|
2614
|
+
value: definition.options.include,
|
|
2615
|
+
entrypoint: definition
|
|
2616
|
+
});
|
|
2617
|
+
}
|
|
2618
|
+
return errors;
|
|
2619
|
+
}
|
|
2620
|
+
var ValidationError = class extends Error {
|
|
2621
|
+
};
|
|
2622
|
+
|
|
2623
|
+
// src/core/utils/building/internal-build.ts
|
|
2624
|
+
import consola3 from "consola";
|
|
2528
2625
|
async function internalBuild(config) {
|
|
2529
2626
|
const verb = config.command === "serve" ? "Pre-rendering" : "Building";
|
|
2530
2627
|
const target = `${config.browser}-mv${config.manifestVersion}`;
|
|
@@ -2538,14 +2635,31 @@ async function internalBuild(config) {
|
|
|
2538
2635
|
await fs12.ensureDir(config.outDir);
|
|
2539
2636
|
const entrypoints = await findEntrypoints(config);
|
|
2540
2637
|
config.logger.debug("Detected entrypoints:", entrypoints);
|
|
2638
|
+
const validationResults = validateEntrypoints(entrypoints);
|
|
2639
|
+
if (validationResults.errorCount + validationResults.warningCount > 0) {
|
|
2640
|
+
printValidationResults(config, validationResults);
|
|
2641
|
+
}
|
|
2642
|
+
if (validationResults.errorCount > 0) {
|
|
2643
|
+
throw new ValidationError(`Entrypoint validation failed`, {
|
|
2644
|
+
cause: validationResults
|
|
2645
|
+
});
|
|
2646
|
+
}
|
|
2541
2647
|
const groups = groupEntrypoints(entrypoints);
|
|
2542
|
-
const { output } = await rebuild(
|
|
2648
|
+
const { output, warnings } = await rebuild(
|
|
2649
|
+
config,
|
|
2650
|
+
entrypoints,
|
|
2651
|
+
groups,
|
|
2652
|
+
void 0
|
|
2653
|
+
);
|
|
2543
2654
|
await printBuildSummary(
|
|
2544
2655
|
config.logger.success,
|
|
2545
2656
|
`Built extension in ${formatDuration(Date.now() - startTime)}`,
|
|
2546
2657
|
output,
|
|
2547
2658
|
config
|
|
2548
2659
|
);
|
|
2660
|
+
for (const warning of warnings) {
|
|
2661
|
+
config.logger.warn(...warning);
|
|
2662
|
+
}
|
|
2549
2663
|
if (config.analysis.enabled) {
|
|
2550
2664
|
await combineAnalysisStats(config);
|
|
2551
2665
|
config.logger.info(
|
|
@@ -2562,11 +2676,35 @@ async function combineAnalysisStats(config) {
|
|
|
2562
2676
|
absolute: true
|
|
2563
2677
|
});
|
|
2564
2678
|
const absolutePaths = unixFiles.map(unnormalizePath);
|
|
2679
|
+
const alterPath = managePath(process.env);
|
|
2680
|
+
alterPath.push(resolve13(config.root, "node_modules/wxt/node_modules/.bin"));
|
|
2565
2681
|
await execaCommand(
|
|
2566
2682
|
`rollup-plugin-visualizer ${absolutePaths.join(" ")} --template ${config.analysis.template}`,
|
|
2567
2683
|
{ cwd: config.root, stdio: "inherit" }
|
|
2568
2684
|
);
|
|
2569
2685
|
}
|
|
2686
|
+
function printValidationResults(config, { errorCount, errors, warningCount }) {
|
|
2687
|
+
(errorCount > 0 ? config.logger.error : config.logger.warn)(
|
|
2688
|
+
`Entrypoint validation failed: ${errorCount} error${errorCount === 1 ? "" : "s"}, ${warningCount} warning${warningCount === 1 ? "" : "s"}`
|
|
2689
|
+
);
|
|
2690
|
+
const cwd = process.cwd();
|
|
2691
|
+
const entrypointErrors = errors.reduce((map, error) => {
|
|
2692
|
+
const entryErrors = map.get(error.entrypoint) ?? [];
|
|
2693
|
+
entryErrors.push(error);
|
|
2694
|
+
map.set(error.entrypoint, entryErrors);
|
|
2695
|
+
return map;
|
|
2696
|
+
}, /* @__PURE__ */ new Map());
|
|
2697
|
+
Array.from(entrypointErrors.entries()).forEach(([entrypoint, errors2]) => {
|
|
2698
|
+
consola3.log(relative6(cwd, entrypoint.inputPath));
|
|
2699
|
+
console.log();
|
|
2700
|
+
errors2.forEach((err) => {
|
|
2701
|
+
const type = err.type === "error" ? pc5.red("ERROR") : pc5.yellow("WARN");
|
|
2702
|
+
const recieved = pc5.dim(`(recieved: ${JSON.stringify(err.value)})`);
|
|
2703
|
+
consola3.log(` - ${type} ${err.message} ${recieved}`);
|
|
2704
|
+
});
|
|
2705
|
+
console.log();
|
|
2706
|
+
});
|
|
2707
|
+
}
|
|
2570
2708
|
|
|
2571
2709
|
// src/core/build.ts
|
|
2572
2710
|
async function build(config) {
|
|
@@ -2578,17 +2716,17 @@ async function build(config) {
|
|
|
2578
2716
|
import path5 from "node:path";
|
|
2579
2717
|
import glob4 from "fast-glob";
|
|
2580
2718
|
import fs13 from "fs-extra";
|
|
2581
|
-
import { consola as
|
|
2719
|
+
import { consola as consola4 } from "consola";
|
|
2582
2720
|
import pc6 from "picocolors";
|
|
2583
2721
|
async function clean(root = process.cwd()) {
|
|
2584
|
-
|
|
2722
|
+
consola4.info("Cleaning Project");
|
|
2585
2723
|
const tempDirs = [
|
|
2586
2724
|
"node_modules/.vite",
|
|
2587
2725
|
"node_modules/.cache",
|
|
2588
2726
|
"**/.wxt",
|
|
2589
2727
|
".output/*"
|
|
2590
2728
|
];
|
|
2591
|
-
|
|
2729
|
+
consola4.debug("Looking for:", tempDirs.map(pc6.cyan).join(", "));
|
|
2592
2730
|
const directories = await glob4(tempDirs, {
|
|
2593
2731
|
cwd: path5.resolve(root),
|
|
2594
2732
|
absolute: true,
|
|
@@ -2596,26 +2734,26 @@ async function clean(root = process.cwd()) {
|
|
|
2596
2734
|
deep: 2
|
|
2597
2735
|
});
|
|
2598
2736
|
if (directories.length === 0) {
|
|
2599
|
-
|
|
2737
|
+
consola4.debug("No generated files found.");
|
|
2600
2738
|
return;
|
|
2601
2739
|
}
|
|
2602
|
-
|
|
2740
|
+
consola4.debug(
|
|
2603
2741
|
"Found:",
|
|
2604
2742
|
directories.map((dir) => pc6.cyan(path5.relative(root, dir))).join(", ")
|
|
2605
2743
|
);
|
|
2606
2744
|
for (const directory of directories) {
|
|
2607
2745
|
await fs13.rm(directory, { force: true, recursive: true });
|
|
2608
|
-
|
|
2746
|
+
consola4.debug("Deleted " + pc6.cyan(path5.relative(root, directory)));
|
|
2609
2747
|
}
|
|
2610
2748
|
}
|
|
2611
2749
|
|
|
2612
2750
|
// src/core/runners/wsl.ts
|
|
2613
|
-
import { relative as
|
|
2751
|
+
import { relative as relative7 } from "node:path";
|
|
2614
2752
|
function createWslRunner() {
|
|
2615
2753
|
return {
|
|
2616
2754
|
async openBrowser(config) {
|
|
2617
2755
|
config.logger.warn(
|
|
2618
|
-
`Cannot open browser when using WSL. Load "${
|
|
2756
|
+
`Cannot open browser when using WSL. Load "${relative7(
|
|
2619
2757
|
process.cwd(),
|
|
2620
2758
|
config.outDir
|
|
2621
2759
|
)}" as an unpacked extension manually`
|
|
@@ -2631,7 +2769,7 @@ function createWebExtRunner() {
|
|
|
2631
2769
|
let runner;
|
|
2632
2770
|
return {
|
|
2633
2771
|
async openBrowser(config) {
|
|
2634
|
-
|
|
2772
|
+
const startTime = Date.now();
|
|
2635
2773
|
if (config.browser === "firefox" && config.manifestVersion === 3) {
|
|
2636
2774
|
throw Error(
|
|
2637
2775
|
"Dev mode does not support Firefox MV3. For alternatives, see https://github.com/wxt-dev/wxt/issues/230#issuecomment-1806881653"
|
|
@@ -2676,7 +2814,8 @@ function createWebExtRunner() {
|
|
|
2676
2814
|
config.logger.debug("web-ext options:", options);
|
|
2677
2815
|
const webExt = await import("web-ext-run");
|
|
2678
2816
|
runner = await webExt.default.cmd.run(finalConfig, options);
|
|
2679
|
-
|
|
2817
|
+
const duration = Date.now() - startTime;
|
|
2818
|
+
config.logger.success(`Opened browser in ${formatDuration(duration)}`);
|
|
2680
2819
|
},
|
|
2681
2820
|
async closeBrowser() {
|
|
2682
2821
|
return await runner?.exit();
|
|
@@ -2687,12 +2826,12 @@ var WARN_LOG_LEVEL = 40;
|
|
|
2687
2826
|
var ERROR_LOG_LEVEL = 50;
|
|
2688
2827
|
|
|
2689
2828
|
// src/core/runners/safari.ts
|
|
2690
|
-
import { relative as
|
|
2829
|
+
import { relative as relative8 } from "node:path";
|
|
2691
2830
|
function createSafariRunner() {
|
|
2692
2831
|
return {
|
|
2693
2832
|
async openBrowser(config) {
|
|
2694
2833
|
config.logger.warn(
|
|
2695
|
-
`Cannot Safari using web-ext. Load "${
|
|
2834
|
+
`Cannot Safari using web-ext. Load "${relative8(
|
|
2696
2835
|
process.cwd(),
|
|
2697
2836
|
config.outDir
|
|
2698
2837
|
)}" as an unpacked extension manually`
|
|
@@ -2704,12 +2843,12 @@ function createSafariRunner() {
|
|
|
2704
2843
|
}
|
|
2705
2844
|
|
|
2706
2845
|
// src/core/runners/manual.ts
|
|
2707
|
-
import { relative as
|
|
2846
|
+
import { relative as relative9 } from "node:path";
|
|
2708
2847
|
function createManualRunner() {
|
|
2709
2848
|
return {
|
|
2710
2849
|
async openBrowser(config) {
|
|
2711
2850
|
config.logger.info(
|
|
2712
|
-
`Load "${
|
|
2851
|
+
`Load "${relative9(
|
|
2713
2852
|
process.cwd(),
|
|
2714
2853
|
config.outDir
|
|
2715
2854
|
)}" as an unpacked extension manually`
|
|
@@ -2738,10 +2877,10 @@ async function createExtensionRunner(config) {
|
|
|
2738
2877
|
}
|
|
2739
2878
|
|
|
2740
2879
|
// src/core/create-server.ts
|
|
2741
|
-
import { consola as
|
|
2880
|
+
import { consola as consola5 } from "consola";
|
|
2742
2881
|
import { Mutex } from "async-mutex";
|
|
2743
2882
|
import pc7 from "picocolors";
|
|
2744
|
-
import { relative as
|
|
2883
|
+
import { relative as relative10 } from "node:path";
|
|
2745
2884
|
async function createServer(inlineConfig) {
|
|
2746
2885
|
const port = await getPort();
|
|
2747
2886
|
const hostname = "localhost";
|
|
@@ -2751,19 +2890,36 @@ async function createServer(inlineConfig) {
|
|
|
2751
2890
|
hostname,
|
|
2752
2891
|
origin
|
|
2753
2892
|
};
|
|
2893
|
+
const buildAndOpenBrowser = async () => {
|
|
2894
|
+
server.currentOutput = await internalBuild(config);
|
|
2895
|
+
await runner.openBrowser(config);
|
|
2896
|
+
};
|
|
2897
|
+
const closeAndRecreateRunner = async () => {
|
|
2898
|
+
await runner.closeBrowser();
|
|
2899
|
+
config = await getLatestConfig();
|
|
2900
|
+
runner = await createExtensionRunner(config);
|
|
2901
|
+
};
|
|
2754
2902
|
const server = {
|
|
2755
2903
|
...serverInfo,
|
|
2756
|
-
watcher
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2904
|
+
get watcher() {
|
|
2905
|
+
return builderServer.watcher;
|
|
2906
|
+
},
|
|
2907
|
+
get ws() {
|
|
2908
|
+
return builderServer.ws;
|
|
2909
|
+
},
|
|
2760
2910
|
currentOutput: void 0,
|
|
2761
|
-
// Filled out later down below
|
|
2762
2911
|
async start() {
|
|
2763
2912
|
await builderServer.listen();
|
|
2764
2913
|
config.logger.success(`Started dev server @ ${serverInfo.origin}`);
|
|
2765
|
-
|
|
2766
|
-
|
|
2914
|
+
await buildAndOpenBrowser();
|
|
2915
|
+
},
|
|
2916
|
+
async stop() {
|
|
2917
|
+
await runner.closeBrowser();
|
|
2918
|
+
await builderServer.close();
|
|
2919
|
+
},
|
|
2920
|
+
async restart() {
|
|
2921
|
+
await closeAndRecreateRunner();
|
|
2922
|
+
await buildAndOpenBrowser();
|
|
2767
2923
|
},
|
|
2768
2924
|
transformHtml(url, html, originalUrl) {
|
|
2769
2925
|
return builderServer.transformHtml(url, html, originalUrl);
|
|
@@ -2776,17 +2932,21 @@ async function createServer(inlineConfig) {
|
|
|
2776
2932
|
},
|
|
2777
2933
|
reloadExtension() {
|
|
2778
2934
|
server.ws.send("wxt:reload-extension");
|
|
2935
|
+
},
|
|
2936
|
+
async restartBrowser() {
|
|
2937
|
+
await closeAndRecreateRunner();
|
|
2938
|
+
await runner.openBrowser(config);
|
|
2779
2939
|
}
|
|
2780
2940
|
};
|
|
2781
2941
|
const getLatestConfig = () => getInternalConfig(inlineConfig ?? {}, "serve", server);
|
|
2782
2942
|
let config = await getLatestConfig();
|
|
2783
|
-
|
|
2943
|
+
let [runner, builderServer] = await Promise.all([
|
|
2784
2944
|
createExtensionRunner(config),
|
|
2785
2945
|
config.builder.createServer(server)
|
|
2786
2946
|
]);
|
|
2787
|
-
server.watcher = builderServer.watcher;
|
|
2788
|
-
server.ws = builderServer.ws;
|
|
2789
2947
|
server.ws.on("wxt:background-initialized", () => {
|
|
2948
|
+
if (server.currentOutput == null)
|
|
2949
|
+
return;
|
|
2790
2950
|
reloadContentScripts(server.currentOutput.steps, config, server);
|
|
2791
2951
|
});
|
|
2792
2952
|
const reloadOnChange = createFileReloader({
|
|
@@ -2814,18 +2974,34 @@ function createFileReloader(options) {
|
|
|
2814
2974
|
return;
|
|
2815
2975
|
changeQueue.push([event, path7]);
|
|
2816
2976
|
await fileChangedMutex.runExclusive(async () => {
|
|
2817
|
-
|
|
2977
|
+
if (server.currentOutput == null)
|
|
2978
|
+
return;
|
|
2979
|
+
const fileChanges = changeQueue.splice(0, changeQueue.length).map(([_, file]) => file);
|
|
2818
2980
|
if (fileChanges.length === 0)
|
|
2819
2981
|
return;
|
|
2820
|
-
const changes = detectDevChanges(
|
|
2982
|
+
const changes = detectDevChanges(
|
|
2983
|
+
config,
|
|
2984
|
+
fileChanges,
|
|
2985
|
+
server.currentOutput
|
|
2986
|
+
);
|
|
2821
2987
|
if (changes.type === "no-change")
|
|
2822
2988
|
return;
|
|
2989
|
+
if (changes.type === "full-restart") {
|
|
2990
|
+
config.logger.info("Config changed, restarting server...");
|
|
2991
|
+
server.restart();
|
|
2992
|
+
return;
|
|
2993
|
+
}
|
|
2994
|
+
if (changes.type === "browser-restart") {
|
|
2995
|
+
config.logger.info("Runner config changed, restarting browser...");
|
|
2996
|
+
server.restartBrowser();
|
|
2997
|
+
return;
|
|
2998
|
+
}
|
|
2823
2999
|
config.logger.info(
|
|
2824
|
-
`Changed: ${Array.from(new Set(fileChanges
|
|
3000
|
+
`Changed: ${Array.from(new Set(fileChanges)).map((file) => pc7.dim(relative10(config.root, file))).join(", ")}`
|
|
2825
3001
|
);
|
|
2826
3002
|
const rebuiltNames = changes.rebuildGroups.flat().map((entry) => {
|
|
2827
3003
|
return pc7.cyan(
|
|
2828
|
-
|
|
3004
|
+
relative10(config.outDir, getEntrypointOutputFile(entry, ""))
|
|
2829
3005
|
);
|
|
2830
3006
|
}).join(pc7.dim(", "));
|
|
2831
3007
|
const allEntrypoints = await findEntrypoints(config);
|
|
@@ -2848,13 +3024,15 @@ function createFileReloader(options) {
|
|
|
2848
3024
|
reloadContentScripts(changes.changedSteps, config, server);
|
|
2849
3025
|
break;
|
|
2850
3026
|
}
|
|
2851
|
-
|
|
3027
|
+
consola5.success(`Reloaded: ${rebuiltNames}`);
|
|
2852
3028
|
});
|
|
2853
3029
|
};
|
|
2854
3030
|
}
|
|
2855
3031
|
function reloadContentScripts(steps, config, server) {
|
|
2856
3032
|
if (config.manifestVersion === 3) {
|
|
2857
3033
|
steps.forEach((step) => {
|
|
3034
|
+
if (server.currentOutput == null)
|
|
3035
|
+
return;
|
|
2858
3036
|
const entry = step.entrypoints;
|
|
2859
3037
|
if (Array.isArray(entry) || entry.type !== "content-script")
|
|
2860
3038
|
return;
|
|
@@ -2891,13 +3069,13 @@ function reloadHtmlPages(groups, server, config) {
|
|
|
2891
3069
|
|
|
2892
3070
|
// src/core/initialize.ts
|
|
2893
3071
|
import prompts from "prompts";
|
|
2894
|
-
import { consola as
|
|
3072
|
+
import { consola as consola6 } from "consola";
|
|
2895
3073
|
import { downloadTemplate } from "giget";
|
|
2896
3074
|
import fs14 from "fs-extra";
|
|
2897
3075
|
import path6 from "node:path";
|
|
2898
3076
|
import pc8 from "picocolors";
|
|
2899
3077
|
async function initialize(options) {
|
|
2900
|
-
|
|
3078
|
+
consola6.info("Initalizing new project");
|
|
2901
3079
|
const templates = await listTemplates();
|
|
2902
3080
|
const defaultTemplate = templates.find(
|
|
2903
3081
|
(template) => template.name === options.template?.toLowerCase().trim()
|
|
@@ -2944,15 +3122,15 @@ async function initialize(options) {
|
|
|
2944
3122
|
await cloneProject(input);
|
|
2945
3123
|
const cdPath = path6.relative(process.cwd(), path6.resolve(input.directory));
|
|
2946
3124
|
console.log();
|
|
2947
|
-
|
|
3125
|
+
consola6.log(
|
|
2948
3126
|
`\u2728 WXT project created with the ${TEMPLATE_COLORS[input.template.name]?.(input.template.name) ?? input.template.name} template.`
|
|
2949
3127
|
);
|
|
2950
3128
|
console.log();
|
|
2951
|
-
|
|
3129
|
+
consola6.log("Next steps:");
|
|
2952
3130
|
let step = 0;
|
|
2953
3131
|
if (cdPath !== "")
|
|
2954
|
-
|
|
2955
|
-
|
|
3132
|
+
consola6.log(` ${++step}.`, pc8.cyan(`cd ${cdPath}`));
|
|
3133
|
+
consola6.log(` ${++step}.`, pc8.cyan(`${input.packageManager} install`));
|
|
2956
3134
|
console.log();
|
|
2957
3135
|
}
|
|
2958
3136
|
async function listTemplates() {
|
|
@@ -2997,7 +3175,7 @@ async function cloneProject({
|
|
|
2997
3175
|
path6.join(directory, "_gitignore"),
|
|
2998
3176
|
path6.join(directory, ".gitignore")
|
|
2999
3177
|
).catch(
|
|
3000
|
-
(err) =>
|
|
3178
|
+
(err) => consola6.warn("Failed to move _gitignore to .gitignore:", err)
|
|
3001
3179
|
);
|
|
3002
3180
|
spinner.succeed();
|
|
3003
3181
|
} catch (err) {
|
|
@@ -3028,7 +3206,7 @@ async function prepare(config) {
|
|
|
3028
3206
|
|
|
3029
3207
|
// src/core/zip.ts
|
|
3030
3208
|
import zipdir from "zip-dir";
|
|
3031
|
-
import { dirname as dirname5, relative as
|
|
3209
|
+
import { dirname as dirname5, relative as relative11, resolve as resolve14 } from "node:path";
|
|
3032
3210
|
import fs15 from "fs-extra";
|
|
3033
3211
|
import { minimatch as minimatch2 } from "minimatch";
|
|
3034
3212
|
async function zip(config) {
|
|
@@ -3046,7 +3224,7 @@ async function zip(config) {
|
|
|
3046
3224
|
).replaceAll("{{manifestVersion}}", `mv${internalConfig.manifestVersion}`);
|
|
3047
3225
|
await fs15.ensureDir(internalConfig.outBaseDir);
|
|
3048
3226
|
const outZipFilename = applyTemplate(internalConfig.zip.artifactTemplate);
|
|
3049
|
-
const outZipPath =
|
|
3227
|
+
const outZipPath = resolve14(internalConfig.outBaseDir, outZipFilename);
|
|
3050
3228
|
await zipdir(internalConfig.outDir, {
|
|
3051
3229
|
saveTo: outZipPath
|
|
3052
3230
|
});
|
|
@@ -3055,14 +3233,14 @@ async function zip(config) {
|
|
|
3055
3233
|
const sourcesZipFilename = applyTemplate(
|
|
3056
3234
|
internalConfig.zip.sourcesTemplate
|
|
3057
3235
|
);
|
|
3058
|
-
const sourcesZipPath =
|
|
3236
|
+
const sourcesZipPath = resolve14(
|
|
3059
3237
|
internalConfig.outBaseDir,
|
|
3060
3238
|
sourcesZipFilename
|
|
3061
3239
|
);
|
|
3062
3240
|
await zipdir(internalConfig.zip.sourcesRoot, {
|
|
3063
3241
|
saveTo: sourcesZipPath,
|
|
3064
3242
|
filter(path7) {
|
|
3065
|
-
const relativePath =
|
|
3243
|
+
const relativePath = relative11(internalConfig.zip.sourcesRoot, path7);
|
|
3066
3244
|
const matchedPattern = internalConfig.zip.ignoredSources.find(
|
|
3067
3245
|
(pattern) => minimatch2(relativePath, pattern)
|
|
3068
3246
|
);
|
|
@@ -3081,7 +3259,7 @@ async function zip(config) {
|
|
|
3081
3259
|
}
|
|
3082
3260
|
|
|
3083
3261
|
// src/cli.ts
|
|
3084
|
-
import
|
|
3262
|
+
import consola7, { LogLevels as LogLevels2 } from "consola";
|
|
3085
3263
|
process.env.VITE_CJS_IGNORE_WARNING = "true";
|
|
3086
3264
|
var cli = cac("wxt");
|
|
3087
3265
|
cli.help();
|
|
@@ -3171,21 +3349,24 @@ function wrapAction(cb, options) {
|
|
|
3171
3349
|
return async (...args) => {
|
|
3172
3350
|
const isDebug = !!args.find((arg) => arg?.debug);
|
|
3173
3351
|
if (isDebug) {
|
|
3174
|
-
|
|
3352
|
+
consola7.level = LogLevels2.debug;
|
|
3175
3353
|
}
|
|
3176
3354
|
const startTime = Date.now();
|
|
3177
3355
|
try {
|
|
3178
3356
|
printHeader();
|
|
3179
3357
|
const status = await cb(...args);
|
|
3180
3358
|
if (!status?.isOngoing && !options?.disableFinishedLog)
|
|
3181
|
-
|
|
3359
|
+
consola7.success(
|
|
3182
3360
|
`Finished in ${formatDuration(Date.now() - startTime)}`
|
|
3183
3361
|
);
|
|
3184
3362
|
} catch (err) {
|
|
3185
|
-
|
|
3363
|
+
consola7.fail(
|
|
3186
3364
|
`Command failed after ${formatDuration(Date.now() - startTime)}`
|
|
3187
3365
|
);
|
|
3188
|
-
|
|
3366
|
+
if (err instanceof ValidationError) {
|
|
3367
|
+
} else {
|
|
3368
|
+
consola7.error(err);
|
|
3369
|
+
}
|
|
3189
3370
|
process.exit(1);
|
|
3190
3371
|
}
|
|
3191
3372
|
};
|