wxt 0.14.0 → 0.14.2-alpha2
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-JPUPWTMG.js +7 -0
- package/dist/{chunk-4BYWUUR2.js → chunk-Y6R4JWTX.js} +247 -107
- package/dist/cli.js +264 -122
- package/dist/{external-tVP-84Pg.d.cts → external-d6JYvU3i.d.cts} +6 -0
- package/dist/{external-tVP-84Pg.d.ts → external-d6JYvU3i.d.ts} +6 -0
- package/dist/i18n.cjs +69 -0
- package/dist/i18n.d.cts +30 -0
- package/dist/i18n.d.ts +30 -0
- package/dist/i18n.js +33 -0
- package/dist/index.cjs +303 -161
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -1
- package/dist/storage.js +3 -4
- package/dist/testing.cjs +23 -13
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/package.json +12 -1
- package/dist/cli.d.ts +0 -2
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.
|
|
7
|
+
var version = "0.14.2-alpha2";
|
|
8
8
|
|
|
9
9
|
// src/core/utils/fs.ts
|
|
10
10
|
import fs from "fs-extra";
|
|
@@ -13,11 +13,11 @@ import glob from "fast-glob";
|
|
|
13
13
|
// src/core/utils/paths.ts
|
|
14
14
|
import systemPath from "node:path";
|
|
15
15
|
import normalize from "normalize-path";
|
|
16
|
-
function normalizePath(
|
|
17
|
-
return normalize(
|
|
16
|
+
function normalizePath(path6) {
|
|
17
|
+
return normalize(path6);
|
|
18
18
|
}
|
|
19
|
-
function unnormalizePath(
|
|
20
|
-
return systemPath.normalize(
|
|
19
|
+
function unnormalizePath(path6) {
|
|
20
|
+
return systemPath.normalize(path6);
|
|
21
21
|
}
|
|
22
22
|
var CSS_EXTENSIONS = ["css", "scss", "sass", "less", "styl", "stylus"];
|
|
23
23
|
var CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
|
|
@@ -38,8 +38,145 @@ async function getPublicFiles(config) {
|
|
|
38
38
|
|
|
39
39
|
// src/core/utils/building/build-entrypoints.ts
|
|
40
40
|
import fs2 from "fs-extra";
|
|
41
|
-
import { dirname, resolve } from "path";
|
|
41
|
+
import { dirname, resolve, extname } from "node:path";
|
|
42
42
|
import pc from "picocolors";
|
|
43
|
+
|
|
44
|
+
// src/i18n/node.ts
|
|
45
|
+
import { readFile } from "node:fs/promises";
|
|
46
|
+
import JSON5 from "json5";
|
|
47
|
+
import YAML from "yaml";
|
|
48
|
+
async function readMessagesFile(file) {
|
|
49
|
+
const text = await readFile(file, "utf-8");
|
|
50
|
+
return readMessagesText(text);
|
|
51
|
+
}
|
|
52
|
+
function readMessagesText(text) {
|
|
53
|
+
const parsers = [
|
|
54
|
+
JSON.parse,
|
|
55
|
+
JSON5.parse,
|
|
56
|
+
YAML.parse
|
|
57
|
+
];
|
|
58
|
+
for (const parse of parsers) {
|
|
59
|
+
try {
|
|
60
|
+
const result = parse(text);
|
|
61
|
+
if (typeof result === "object") {
|
|
62
|
+
return readMessagesObject(result);
|
|
63
|
+
}
|
|
64
|
+
} catch {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
throw Error("I18n messages text is not valid JSON, JSON5, or YAML");
|
|
69
|
+
}
|
|
70
|
+
function readMessagesObject(input) {
|
|
71
|
+
const messagesFromInput = findEntries([], input);
|
|
72
|
+
return [...messagesFromInput, ...PREDEFINED_MESSAGES];
|
|
73
|
+
}
|
|
74
|
+
function convertMessagesToManifest(messages) {
|
|
75
|
+
return messages.filter((message) => !message.isBuiltin).reduce((schema, { name, entry }) => {
|
|
76
|
+
schema[name] = entry;
|
|
77
|
+
return schema;
|
|
78
|
+
}, {});
|
|
79
|
+
}
|
|
80
|
+
function findEntries(keyPath, input) {
|
|
81
|
+
const name = keyPath.join("_");
|
|
82
|
+
if (isBasicEntry(input))
|
|
83
|
+
return [
|
|
84
|
+
{
|
|
85
|
+
name,
|
|
86
|
+
entry: { message: input }
|
|
87
|
+
}
|
|
88
|
+
];
|
|
89
|
+
if (isManifestEntry(input))
|
|
90
|
+
return [
|
|
91
|
+
{
|
|
92
|
+
name,
|
|
93
|
+
entry: input
|
|
94
|
+
}
|
|
95
|
+
];
|
|
96
|
+
if (isPluralEntry(input))
|
|
97
|
+
return [
|
|
98
|
+
{
|
|
99
|
+
name,
|
|
100
|
+
entry: {
|
|
101
|
+
message: Object.values(input).join(" | ")
|
|
102
|
+
},
|
|
103
|
+
isPlural: true
|
|
104
|
+
}
|
|
105
|
+
];
|
|
106
|
+
return Object.entries(input).reduce((items, [key, child]) => {
|
|
107
|
+
const nestedEntries = findEntries(keyPath.concat(key), child);
|
|
108
|
+
return [...items, ...nestedEntries];
|
|
109
|
+
}, []);
|
|
110
|
+
}
|
|
111
|
+
function isBasicEntry(entry) {
|
|
112
|
+
return typeof entry === "string";
|
|
113
|
+
}
|
|
114
|
+
function isManifestEntry(entry) {
|
|
115
|
+
const keys = Object.keys(entry);
|
|
116
|
+
if (keys.length < 1 || keys.length > 3)
|
|
117
|
+
return false;
|
|
118
|
+
const knownKeys = /* @__PURE__ */ new Set(["message", "placeholders", "description"]);
|
|
119
|
+
const unknownKeys = keys.filter((key) => !knownKeys.has(key));
|
|
120
|
+
return unknownKeys.length === 0;
|
|
121
|
+
}
|
|
122
|
+
function isPluralEntry(entry) {
|
|
123
|
+
const keys = Object.keys(entry);
|
|
124
|
+
if (keys.length === 0)
|
|
125
|
+
return false;
|
|
126
|
+
const invalidKeys = keys.filter((key) => key !== "n" && isNaN(Number(key)));
|
|
127
|
+
return invalidKeys.length === 0;
|
|
128
|
+
}
|
|
129
|
+
var PREDEFINED_MESSAGES = [
|
|
130
|
+
{
|
|
131
|
+
name: "@@extension_id",
|
|
132
|
+
isBuiltin: true,
|
|
133
|
+
entry: {
|
|
134
|
+
message: "<browser.runtime.id>",
|
|
135
|
+
description: "The extension or app ID; you might use this string to construct URLs for resources inside the extension. Even unlocalized extensions can use this message.\nNote: You can't use this message in a manifest file."
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "@@ui_locale",
|
|
140
|
+
isBuiltin: true,
|
|
141
|
+
entry: {
|
|
142
|
+
message: "<browser.i18n.getUiLocale()>"
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: "@@bidi_dir",
|
|
147
|
+
isBuiltin: true,
|
|
148
|
+
entry: {
|
|
149
|
+
message: "<ltr|rtl>",
|
|
150
|
+
description: 'The text direction for the current locale, either "ltr" for left-to-right languages such as English or "rtl" for right-to-left languages such as Japanese.'
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: "@@bidi_reversed_dir",
|
|
155
|
+
isBuiltin: true,
|
|
156
|
+
entry: {
|
|
157
|
+
message: "<rtl|ltr>",
|
|
158
|
+
description: `If the @@bidi_dir is "ltr", then this is "rtl"; otherwise, it's "ltr".`
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: "@@bidi_start_edge",
|
|
163
|
+
isBuiltin: true,
|
|
164
|
+
entry: {
|
|
165
|
+
message: "<left|right>",
|
|
166
|
+
description: `If the @@bidi_dir is "ltr", then this is "left"; otherwise, it's "right".`
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: "@@bidi_end_edge",
|
|
171
|
+
isBuiltin: true,
|
|
172
|
+
entry: {
|
|
173
|
+
message: "<right|left>",
|
|
174
|
+
description: `If the @@bidi_dir is "ltr", then this is "right"; otherwise, it's "left".`
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
// src/core/utils/building/build-entrypoints.ts
|
|
43
180
|
async function buildEntrypoints(groups, config, spinner) {
|
|
44
181
|
const steps = [];
|
|
45
182
|
for (let i = 0; i < groups.length; i++) {
|
|
@@ -48,7 +185,10 @@ async function buildEntrypoints(groups, config, spinner) {
|
|
|
48
185
|
spinner.text = pc.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNames}`;
|
|
49
186
|
steps.push(await config.builder.build(group));
|
|
50
187
|
}
|
|
51
|
-
const publicAssets = await
|
|
188
|
+
const publicAssets = (await Promise.all([
|
|
189
|
+
copyPublicDirectory(config),
|
|
190
|
+
copyLocalesDirectory(config)
|
|
191
|
+
])).flat();
|
|
52
192
|
return { publicAssets, steps };
|
|
53
193
|
}
|
|
54
194
|
async function copyPublicDirectory(config) {
|
|
@@ -68,6 +208,28 @@ async function copyPublicDirectory(config) {
|
|
|
68
208
|
}
|
|
69
209
|
return publicAssets;
|
|
70
210
|
}
|
|
211
|
+
async function copyLocalesDirectory(config) {
|
|
212
|
+
const localesExist = await fs2.exists(config.localesDir);
|
|
213
|
+
if (!localesExist || config.manifest.default_locale == null)
|
|
214
|
+
return [];
|
|
215
|
+
const files = await fs2.readdir(config.localesDir);
|
|
216
|
+
return await Promise.all(
|
|
217
|
+
files.map(async (file) => {
|
|
218
|
+
const locale = file.replace(extname(file), "");
|
|
219
|
+
const fileName = unnormalizePath(`_locales/${locale}/messages.json`);
|
|
220
|
+
const srcPath = resolve(config.localesDir, file);
|
|
221
|
+
const outPath = resolve(config.outDir, fileName);
|
|
222
|
+
const messages = await readMessagesFile(srcPath);
|
|
223
|
+
const json = convertMessagesToManifest(messages);
|
|
224
|
+
await fs2.ensureDir(dirname(outPath));
|
|
225
|
+
await fs2.writeJson(outPath, json);
|
|
226
|
+
return {
|
|
227
|
+
fileName,
|
|
228
|
+
type: "asset"
|
|
229
|
+
};
|
|
230
|
+
})
|
|
231
|
+
);
|
|
232
|
+
}
|
|
71
233
|
|
|
72
234
|
// src/core/utils/arrays.ts
|
|
73
235
|
function every(array, predicate) {
|
|
@@ -166,7 +328,7 @@ import { relative as relative2, resolve as resolve3 } from "path";
|
|
|
166
328
|
import fs3 from "fs-extra";
|
|
167
329
|
import { minimatch } from "minimatch";
|
|
168
330
|
import { parseHTML } from "linkedom";
|
|
169
|
-
import
|
|
331
|
+
import JSON52 from "json5";
|
|
170
332
|
import glob2 from "fast-glob";
|
|
171
333
|
|
|
172
334
|
// src/core/utils/entrypoints.ts
|
|
@@ -204,7 +366,7 @@ async function findEntrypoints(config) {
|
|
|
204
366
|
const inputPath = resolve3(config.entrypointsDir, relativePath);
|
|
205
367
|
const name = getEntrypointName(config.entrypointsDir, inputPath);
|
|
206
368
|
const matchingGlob = pathGlobs.find(
|
|
207
|
-
(
|
|
369
|
+
(glob6) => minimatch(relativePath, glob6)
|
|
208
370
|
);
|
|
209
371
|
if (matchingGlob) {
|
|
210
372
|
const type = PATH_GLOB_TO_TYPE_MAP[matchingGlob];
|
|
@@ -323,11 +485,11 @@ function getHtmlBaseOptions(document) {
|
|
|
323
485
|
const options = {};
|
|
324
486
|
const includeContent = document.querySelector("meta[name='manifest.include']")?.getAttribute("content");
|
|
325
487
|
if (includeContent) {
|
|
326
|
-
options.include =
|
|
488
|
+
options.include = JSON52.parse(includeContent);
|
|
327
489
|
}
|
|
328
490
|
const excludeContent = document.querySelector("meta[name='manifest.exclude']")?.getAttribute("content");
|
|
329
491
|
if (excludeContent) {
|
|
330
|
-
options.exclude =
|
|
492
|
+
options.exclude = JSON52.parse(excludeContent);
|
|
331
493
|
}
|
|
332
494
|
return options;
|
|
333
495
|
}
|
|
@@ -341,7 +503,7 @@ async function getPopupEntrypoint(config, { inputPath, name }) {
|
|
|
341
503
|
const defaultIconContent = document.querySelector("meta[name='manifest.default_icon']")?.getAttribute("content");
|
|
342
504
|
if (defaultIconContent) {
|
|
343
505
|
try {
|
|
344
|
-
options.defaultIcon =
|
|
506
|
+
options.defaultIcon = JSON52.parse(defaultIconContent);
|
|
345
507
|
} catch (err) {
|
|
346
508
|
config.logger.fatal(
|
|
347
509
|
`Failed to parse default_icon meta tag content as JSON5. content=${defaultIconContent}`,
|
|
@@ -517,7 +679,8 @@ function getUnimportOptions(config) {
|
|
|
517
679
|
debugLog: config.logger.debug,
|
|
518
680
|
imports: [
|
|
519
681
|
{ name: "defineConfig", from: "wxt" },
|
|
520
|
-
{ name: "fakeBrowser", from: "wxt/testing" }
|
|
682
|
+
{ name: "fakeBrowser", from: "wxt/testing" },
|
|
683
|
+
{ name: "i18n", from: "wxt/i18n" }
|
|
521
684
|
],
|
|
522
685
|
presets: [
|
|
523
686
|
{ package: "wxt/client" },
|
|
@@ -590,46 +753,7 @@ function surroundInUnderscore(name) {
|
|
|
590
753
|
}
|
|
591
754
|
|
|
592
755
|
// src/core/utils/building/generate-wxt-dir.ts
|
|
593
|
-
import
|
|
594
|
-
|
|
595
|
-
// src/core/utils/i18n.ts
|
|
596
|
-
var predefinedMessages = {
|
|
597
|
-
"@@extension_id": {
|
|
598
|
-
message: "<browser.runtime.id>",
|
|
599
|
-
description: "The extension or app ID; you might use this string to construct URLs for resources inside the extension. Even unlocalized extensions can use this message.\nNote: You can't use this message in a manifest file."
|
|
600
|
-
},
|
|
601
|
-
"@@ui_locale": {
|
|
602
|
-
message: "<browser.i18n.getUiLocale()>",
|
|
603
|
-
description: ""
|
|
604
|
-
},
|
|
605
|
-
"@@bidi_dir": {
|
|
606
|
-
message: "<ltr|rtl>",
|
|
607
|
-
description: 'The text direction for the current locale, either "ltr" for left-to-right languages such as English or "rtl" for right-to-left languages such as Japanese.'
|
|
608
|
-
},
|
|
609
|
-
"@@bidi_reversed_dir": {
|
|
610
|
-
message: "<rtl|ltr>",
|
|
611
|
-
description: `If the @@bidi_dir is "ltr", then this is "rtl"; otherwise, it's "ltr".`
|
|
612
|
-
},
|
|
613
|
-
"@@bidi_start_edge": {
|
|
614
|
-
message: "<left|right>",
|
|
615
|
-
description: `If the @@bidi_dir is "ltr", then this is "left"; otherwise, it's "right".`
|
|
616
|
-
},
|
|
617
|
-
"@@bidi_end_edge": {
|
|
618
|
-
message: "<right|left>",
|
|
619
|
-
description: `If the @@bidi_dir is "ltr", then this is "right"; otherwise, it's "left".`
|
|
620
|
-
}
|
|
621
|
-
};
|
|
622
|
-
function parseI18nMessages(messagesJson) {
|
|
623
|
-
return Object.entries({
|
|
624
|
-
...predefinedMessages,
|
|
625
|
-
...messagesJson
|
|
626
|
-
}).map(([name, details]) => ({
|
|
627
|
-
name,
|
|
628
|
-
...details
|
|
629
|
-
}));
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
// src/core/utils/building/generate-wxt-dir.ts
|
|
756
|
+
import glob3 from "fast-glob";
|
|
633
757
|
async function generateTypesDir(entrypoints, config) {
|
|
634
758
|
await fs4.ensureDir(config.typesDir);
|
|
635
759
|
const references = [];
|
|
@@ -663,7 +787,7 @@ async function writePathsDeclarationFile(entrypoints, config) {
|
|
|
663
787
|
config.outDir,
|
|
664
788
|
entry.inputPath.endsWith(".html") ? ".html" : ".js"
|
|
665
789
|
)
|
|
666
|
-
).concat(await getPublicFiles(config)).map(normalizePath).map((
|
|
790
|
+
).concat(await getPublicFiles(config)).map(normalizePath).map((path6) => ` | "/${path6}"`).sort().join("\n");
|
|
667
791
|
const template = `// Generated by wxt
|
|
668
792
|
import "wxt/browser";
|
|
669
793
|
|
|
@@ -699,28 +823,36 @@ declare module "wxt/browser" {
|
|
|
699
823
|
}
|
|
700
824
|
|
|
701
825
|
export interface WxtI18n extends I18n.Static {
|
|
702
|
-
{{
|
|
826
|
+
{{ browserOverrides }}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
declare module "wxt/i18n" {
|
|
831
|
+
export interface WxtMessageSchema {
|
|
832
|
+
t: {
|
|
833
|
+
{{ translationTOverrides }}
|
|
834
|
+
};
|
|
835
|
+
tp: {
|
|
836
|
+
{{ translationTpOverrides }}
|
|
837
|
+
};
|
|
703
838
|
}
|
|
704
839
|
}
|
|
705
840
|
`;
|
|
706
841
|
let messages;
|
|
707
842
|
if (defaultLocale) {
|
|
708
|
-
const defaultLocalePath =
|
|
709
|
-
config.
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
);
|
|
714
|
-
const content = JSON.parse(await fs4.readFile(defaultLocalePath, "utf-8"));
|
|
715
|
-
messages = parseI18nMessages(content);
|
|
843
|
+
const [defaultLocalePath] = await glob3(`${defaultLocale}.*`, {
|
|
844
|
+
cwd: config.localesDir,
|
|
845
|
+
absolute: true
|
|
846
|
+
});
|
|
847
|
+
messages = await readMessagesFile(defaultLocalePath);
|
|
716
848
|
} else {
|
|
717
|
-
messages =
|
|
849
|
+
messages = PREDEFINED_MESSAGES;
|
|
718
850
|
}
|
|
719
851
|
const overrides = messages.map((message) => {
|
|
720
852
|
return ` /**
|
|
721
|
-
* ${message.description ?? "No message description."}
|
|
853
|
+
* ${message.entry.description ?? "No message description."}
|
|
722
854
|
*
|
|
723
|
-
* "${message.message}"
|
|
855
|
+
* "${message.entry.message}"
|
|
724
856
|
*/
|
|
725
857
|
getMessage(
|
|
726
858
|
messageName: "${message.name}",
|
|
@@ -730,7 +862,13 @@ declare module "wxt/browser" {
|
|
|
730
862
|
});
|
|
731
863
|
await writeFileIfDifferent(
|
|
732
864
|
filePath,
|
|
733
|
-
template.replace("{{
|
|
865
|
+
template.replace("{{ browserOverrides }}", overrides.join("\n")).replace(
|
|
866
|
+
"{{ translationTOverrides }}",
|
|
867
|
+
messages.filter((message) => !message.isPlural).map((message) => ` "${message.name}": any;`).join("\n")
|
|
868
|
+
).replace(
|
|
869
|
+
"{{ translationTpOverrides }}",
|
|
870
|
+
messages.filter((message) => message.isPlural).map((message) => ` "${message.name}": any;`).join("\n")
|
|
871
|
+
)
|
|
734
872
|
);
|
|
735
873
|
return filePath;
|
|
736
874
|
}
|
|
@@ -766,7 +904,7 @@ async function writeMainDeclarationFile(references, config) {
|
|
|
766
904
|
}
|
|
767
905
|
async function writeTsConfigFile(mainReference, config) {
|
|
768
906
|
const dir = config.wxtDir;
|
|
769
|
-
const getTsconfigPath = (
|
|
907
|
+
const getTsconfigPath = (path6) => normalizePath(relative3(dir, path6));
|
|
770
908
|
const paths = Object.entries(config.alias).flatMap(([alias, absolutePath]) => {
|
|
771
909
|
const aliasPath = getTsconfigPath(absolutePath);
|
|
772
910
|
return [
|
|
@@ -802,7 +940,7 @@ ${paths}
|
|
|
802
940
|
|
|
803
941
|
// src/core/utils/building/get-internal-config.ts
|
|
804
942
|
import { loadConfig } from "c12";
|
|
805
|
-
import
|
|
943
|
+
import path2 from "node:path";
|
|
806
944
|
|
|
807
945
|
// src/core/utils/cache.ts
|
|
808
946
|
import fs5, { ensureDir } from "fs-extra";
|
|
@@ -811,14 +949,14 @@ function createFsCache(wxtDir) {
|
|
|
811
949
|
const getPath = (key) => resolve5(wxtDir, "cache", encodeURIComponent(key));
|
|
812
950
|
return {
|
|
813
951
|
async set(key, value) {
|
|
814
|
-
const
|
|
815
|
-
await ensureDir(dirname2(
|
|
816
|
-
await writeFileIfDifferent(
|
|
952
|
+
const path6 = getPath(key);
|
|
953
|
+
await ensureDir(dirname2(path6));
|
|
954
|
+
await writeFileIfDifferent(path6, value);
|
|
817
955
|
},
|
|
818
956
|
async get(key) {
|
|
819
|
-
const
|
|
957
|
+
const path6 = getPath(key);
|
|
820
958
|
try {
|
|
821
|
-
return await fs5.readFile(
|
|
959
|
+
return await fs5.readFile(path6, "utf-8");
|
|
822
960
|
} catch {
|
|
823
961
|
return void 0;
|
|
824
962
|
}
|
|
@@ -1040,7 +1178,7 @@ function download(config) {
|
|
|
1040
1178
|
}
|
|
1041
1179
|
|
|
1042
1180
|
// src/core/builders/vite/plugins/multipageMove.ts
|
|
1043
|
-
import { dirname as dirname4, extname, resolve as resolve7, join } from "node:path";
|
|
1181
|
+
import { dirname as dirname4, extname as extname2, resolve as resolve7, join } from "node:path";
|
|
1044
1182
|
import fs6, { ensureDir as ensureDir2 } from "fs-extra";
|
|
1045
1183
|
function multipageMove(entrypoints, config) {
|
|
1046
1184
|
return {
|
|
@@ -1059,7 +1197,7 @@ function multipageMove(entrypoints, config) {
|
|
|
1059
1197
|
const newBundlePath = getEntrypointBundlePath(
|
|
1060
1198
|
entrypoint,
|
|
1061
1199
|
config.outDir,
|
|
1062
|
-
|
|
1200
|
+
extname2(oldBundlePath)
|
|
1063
1201
|
);
|
|
1064
1202
|
if (newBundlePath === oldBundlePath) {
|
|
1065
1203
|
config.logger.debug(
|
|
@@ -1100,7 +1238,7 @@ async function removeEmptyDirs(dir) {
|
|
|
1100
1238
|
|
|
1101
1239
|
// src/core/builders/vite/plugins/unimport.ts
|
|
1102
1240
|
import { createUnimport as createUnimport2 } from "unimport";
|
|
1103
|
-
import { extname as
|
|
1241
|
+
import { extname as extname3 } from "path";
|
|
1104
1242
|
var ENABLED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
1105
1243
|
".js",
|
|
1106
1244
|
".jsx",
|
|
@@ -1122,7 +1260,7 @@ function unimport(config) {
|
|
|
1122
1260
|
async transform(code, id) {
|
|
1123
1261
|
if (id.includes("node_modules"))
|
|
1124
1262
|
return;
|
|
1125
|
-
if (!ENABLED_EXTENSIONS.has(
|
|
1263
|
+
if (!ENABLED_EXTENSIONS.has(extname3(id)))
|
|
1126
1264
|
return;
|
|
1127
1265
|
return unimport2.injectImports(code, id);
|
|
1128
1266
|
}
|
|
@@ -1286,7 +1424,7 @@ function entrypointGroupGlobals(entrypointGroup) {
|
|
|
1286
1424
|
}
|
|
1287
1425
|
|
|
1288
1426
|
// src/core/builders/vite/index.ts
|
|
1289
|
-
async function
|
|
1427
|
+
async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
|
|
1290
1428
|
const vite = await import("vite");
|
|
1291
1429
|
const getBaseConfig = async () => {
|
|
1292
1430
|
const resolvedInlineConfig = await inlineConfig.vite?.(wxtConfig.env) ?? {};
|
|
@@ -1514,19 +1652,20 @@ async function getInternalConfig(inlineConfig, command, server) {
|
|
|
1514
1652
|
const manifestVersion = mergedConfig.manifestVersion ?? (browser === "firefox" || browser === "safari" ? 2 : 3);
|
|
1515
1653
|
const mode = mergedConfig.mode ?? (command === "build" ? "production" : "development");
|
|
1516
1654
|
const env = { browser, command, manifestVersion, mode };
|
|
1517
|
-
const root =
|
|
1655
|
+
const root = path2.resolve(
|
|
1518
1656
|
inlineConfig.root ?? userConfig.root ?? process.cwd()
|
|
1519
1657
|
);
|
|
1520
|
-
const wxtDir =
|
|
1521
|
-
const srcDir =
|
|
1522
|
-
const entrypointsDir =
|
|
1658
|
+
const wxtDir = path2.resolve(root, ".wxt");
|
|
1659
|
+
const srcDir = path2.resolve(root, mergedConfig.srcDir ?? root);
|
|
1660
|
+
const entrypointsDir = path2.resolve(
|
|
1523
1661
|
srcDir,
|
|
1524
1662
|
mergedConfig.entrypointsDir ?? "entrypoints"
|
|
1525
1663
|
);
|
|
1526
|
-
const publicDir =
|
|
1527
|
-
const
|
|
1528
|
-
const
|
|
1529
|
-
const
|
|
1664
|
+
const publicDir = path2.resolve(srcDir, mergedConfig.publicDir ?? "public");
|
|
1665
|
+
const localesDir = path2.resolve(srcDir, mergedConfig.localesDir ?? "locales");
|
|
1666
|
+
const typesDir = path2.resolve(wxtDir, "types");
|
|
1667
|
+
const outBaseDir = path2.resolve(root, mergedConfig.outDir ?? ".output");
|
|
1668
|
+
const outDir = path2.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
|
|
1530
1669
|
const runnerConfig = await loadConfig({
|
|
1531
1670
|
name: "web-ext",
|
|
1532
1671
|
cwd: root,
|
|
@@ -1542,7 +1681,7 @@ async function getInternalConfig(inlineConfig, command, server) {
|
|
|
1542
1681
|
"~": srcDir,
|
|
1543
1682
|
"@@": root,
|
|
1544
1683
|
"~~": root
|
|
1545
|
-
}).map(([key, value]) => [key,
|
|
1684
|
+
}).map(([key, value]) => [key, path2.resolve(root, value)])
|
|
1546
1685
|
);
|
|
1547
1686
|
const finalConfig = {
|
|
1548
1687
|
browser,
|
|
@@ -1559,6 +1698,7 @@ async function getInternalConfig(inlineConfig, command, server) {
|
|
|
1559
1698
|
outBaseDir,
|
|
1560
1699
|
outDir,
|
|
1561
1700
|
publicDir,
|
|
1701
|
+
localesDir,
|
|
1562
1702
|
root,
|
|
1563
1703
|
runnerConfig,
|
|
1564
1704
|
srcDir,
|
|
@@ -1580,7 +1720,7 @@ async function getInternalConfig(inlineConfig, command, server) {
|
|
|
1580
1720
|
},
|
|
1581
1721
|
server
|
|
1582
1722
|
};
|
|
1583
|
-
const builder = await
|
|
1723
|
+
const builder = await createViteBuilder(
|
|
1584
1724
|
inlineConfig,
|
|
1585
1725
|
userConfig,
|
|
1586
1726
|
finalConfig
|
|
@@ -1627,6 +1767,7 @@ function mergeInlineConfig(inlineConfig, userConfig) {
|
|
|
1627
1767
|
manifest,
|
|
1628
1768
|
mode: inlineConfig.mode ?? userConfig.mode,
|
|
1629
1769
|
publicDir: inlineConfig.publicDir ?? userConfig.publicDir,
|
|
1770
|
+
localesDir: inlineConfig.localesDir ?? userConfig.localesDir,
|
|
1630
1771
|
runner,
|
|
1631
1772
|
srcDir: inlineConfig.srcDir ?? userConfig.srcDir,
|
|
1632
1773
|
outDir: inlineConfig.outDir ?? userConfig.outDir,
|
|
@@ -1731,16 +1872,16 @@ ${noImports}`;
|
|
|
1731
1872
|
// src/core/utils/building/import-entrypoint.ts
|
|
1732
1873
|
import { transformSync } from "esbuild";
|
|
1733
1874
|
import { fileURLToPath } from "node:url";
|
|
1734
|
-
async function importEntrypointFile(
|
|
1735
|
-
config.logger.debug("Loading file metadata:",
|
|
1736
|
-
const normalPath = normalizePath(
|
|
1875
|
+
async function importEntrypointFile(path6, config) {
|
|
1876
|
+
config.logger.debug("Loading file metadata:", path6);
|
|
1877
|
+
const normalPath = normalizePath(path6);
|
|
1737
1878
|
const unimport2 = createUnimport3({
|
|
1738
1879
|
...getUnimportOptions(config),
|
|
1739
1880
|
// Only allow specific imports, not all from the project
|
|
1740
1881
|
dirs: []
|
|
1741
1882
|
});
|
|
1742
1883
|
await unimport2.init();
|
|
1743
|
-
const text = await fs8.readFile(
|
|
1884
|
+
const text = await fs8.readFile(path6, "utf-8");
|
|
1744
1885
|
const textNoImports = removeProjectImportStatements(text);
|
|
1745
1886
|
const { code } = await unimport2.injectImports(textNoImports);
|
|
1746
1887
|
config.logger.debug(
|
|
@@ -1783,7 +1924,7 @@ async function importEntrypointFile(path7, config) {
|
|
|
1783
1924
|
}
|
|
1784
1925
|
);
|
|
1785
1926
|
try {
|
|
1786
|
-
const res = await jiti(
|
|
1927
|
+
const res = await jiti(path6);
|
|
1787
1928
|
return res.default;
|
|
1788
1929
|
} catch (err) {
|
|
1789
1930
|
config.logger.error(err);
|
|
@@ -1807,7 +1948,7 @@ import fs12 from "fs-extra";
|
|
|
1807
1948
|
import { resolve as resolve10 } from "path";
|
|
1808
1949
|
|
|
1809
1950
|
// src/core/utils/log/printFileList.ts
|
|
1810
|
-
import
|
|
1951
|
+
import path3 from "node:path";
|
|
1811
1952
|
import pc2 from "picocolors";
|
|
1812
1953
|
import fs9 from "fs-extra";
|
|
1813
1954
|
import { filesize } from "filesize";
|
|
@@ -1845,8 +1986,8 @@ async function printFileList(log, header, baseDir, files) {
|
|
|
1845
1986
|
const fileRows = await Promise.all(
|
|
1846
1987
|
files.map(async (file, i) => {
|
|
1847
1988
|
const parts = [
|
|
1848
|
-
|
|
1849
|
-
|
|
1989
|
+
path3.relative(process.cwd(), baseDir) + path3.sep,
|
|
1990
|
+
path3.relative(baseDir, file)
|
|
1850
1991
|
];
|
|
1851
1992
|
const prefix = i === files.length - 1 ? " \u2514\u2500" : " \u251C\u2500";
|
|
1852
1993
|
const color = getChunkColor(file);
|
|
@@ -1917,7 +2058,7 @@ function printHeader() {
|
|
|
1917
2058
|
}
|
|
1918
2059
|
|
|
1919
2060
|
// src/core/utils/building/internal-build.ts
|
|
1920
|
-
import
|
|
2061
|
+
import glob4 from "fast-glob";
|
|
1921
2062
|
|
|
1922
2063
|
// src/core/utils/manifest.ts
|
|
1923
2064
|
import fs11 from "fs-extra";
|
|
@@ -2074,7 +2215,7 @@ async function generateManifest(entrypoints, buildOutput, config) {
|
|
|
2074
2215
|
"wxt:reload-extension": {
|
|
2075
2216
|
description: "Reload the extension during development",
|
|
2076
2217
|
suggested_key: {
|
|
2077
|
-
default: "
|
|
2218
|
+
default: "Alt+R"
|
|
2078
2219
|
}
|
|
2079
2220
|
}
|
|
2080
2221
|
};
|
|
@@ -2447,13 +2588,12 @@ function stripPathFromMatchPattern(pattern) {
|
|
|
2447
2588
|
}
|
|
2448
2589
|
|
|
2449
2590
|
// src/core/utils/building/rebuild.ts
|
|
2450
|
-
async function rebuild(config, entrypointGroups, existingOutput = {
|
|
2591
|
+
async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput = {
|
|
2451
2592
|
steps: [],
|
|
2452
2593
|
publicAssets: []
|
|
2453
2594
|
}) {
|
|
2454
2595
|
const { default: ora } = await import("ora");
|
|
2455
2596
|
const spinner = ora(`Preparing...`).start();
|
|
2456
|
-
const allEntrypoints = await findEntrypoints(config);
|
|
2457
2597
|
await generateTypesDir(allEntrypoints, config).catch((err) => {
|
|
2458
2598
|
config.logger.warn("Failed to update .wxt directory:", err);
|
|
2459
2599
|
if (config.command === "build")
|
|
@@ -2503,7 +2643,7 @@ async function internalBuild(config) {
|
|
|
2503
2643
|
const entrypoints = await findEntrypoints(config);
|
|
2504
2644
|
config.logger.debug("Detected entrypoints:", entrypoints);
|
|
2505
2645
|
const groups = groupEntrypoints(entrypoints);
|
|
2506
|
-
const { output } = await rebuild(config, groups, void 0);
|
|
2646
|
+
const { output } = await rebuild(config, entrypoints, groups, void 0);
|
|
2507
2647
|
await printBuildSummary(
|
|
2508
2648
|
config.logger.success,
|
|
2509
2649
|
`Built extension in ${formatDuration(Date.now() - startTime)}`,
|
|
@@ -2521,7 +2661,7 @@ async function internalBuild(config) {
|
|
|
2521
2661
|
}
|
|
2522
2662
|
async function combineAnalysisStats(config) {
|
|
2523
2663
|
const { execaCommand } = await import("./execa-4F7CCWCA.js");
|
|
2524
|
-
const unixFiles = await
|
|
2664
|
+
const unixFiles = await glob4(`stats-*.json`, {
|
|
2525
2665
|
cwd: config.outDir,
|
|
2526
2666
|
absolute: true
|
|
2527
2667
|
});
|
|
@@ -2539,8 +2679,8 @@ async function build(config) {
|
|
|
2539
2679
|
}
|
|
2540
2680
|
|
|
2541
2681
|
// src/core/clean.ts
|
|
2542
|
-
import
|
|
2543
|
-
import
|
|
2682
|
+
import path4 from "node:path";
|
|
2683
|
+
import glob5 from "fast-glob";
|
|
2544
2684
|
import fs13 from "fs-extra";
|
|
2545
2685
|
import { consola as consola3 } from "consola";
|
|
2546
2686
|
import pc5 from "picocolors";
|
|
@@ -2553,8 +2693,8 @@ async function clean(root = process.cwd()) {
|
|
|
2553
2693
|
".output/*"
|
|
2554
2694
|
];
|
|
2555
2695
|
consola3.debug("Looking for:", tempDirs.map(pc5.cyan).join(", "));
|
|
2556
|
-
const directories = await
|
|
2557
|
-
cwd:
|
|
2696
|
+
const directories = await glob5(tempDirs, {
|
|
2697
|
+
cwd: path4.resolve(root),
|
|
2558
2698
|
absolute: true,
|
|
2559
2699
|
onlyDirectories: true,
|
|
2560
2700
|
deep: 2
|
|
@@ -2565,11 +2705,11 @@ async function clean(root = process.cwd()) {
|
|
|
2565
2705
|
}
|
|
2566
2706
|
consola3.debug(
|
|
2567
2707
|
"Found:",
|
|
2568
|
-
directories.map((dir) => pc5.cyan(
|
|
2708
|
+
directories.map((dir) => pc5.cyan(path4.relative(root, dir))).join(", ")
|
|
2569
2709
|
);
|
|
2570
2710
|
for (const directory of directories) {
|
|
2571
2711
|
await fs13.rm(directory, { force: true, recursive: true });
|
|
2572
|
-
consola3.debug("Deleted " + pc5.cyan(
|
|
2712
|
+
consola3.debug("Deleted " + pc5.cyan(path4.relative(root, directory)));
|
|
2573
2713
|
}
|
|
2574
2714
|
}
|
|
2575
2715
|
|
|
@@ -2735,8 +2875,8 @@ async function createServer(inlineConfig) {
|
|
|
2735
2875
|
reloadContentScript(contentScript) {
|
|
2736
2876
|
server.ws.send("wxt:reload-content-script", contentScript);
|
|
2737
2877
|
},
|
|
2738
|
-
reloadPage(
|
|
2739
|
-
server.ws.send("wxt:reload-page",
|
|
2878
|
+
reloadPage(path6) {
|
|
2879
|
+
server.ws.send("wxt:reload-page", path6);
|
|
2740
2880
|
},
|
|
2741
2881
|
reloadExtension() {
|
|
2742
2882
|
server.ws.send("wxt:reload-extension");
|
|
@@ -2771,12 +2911,12 @@ function createFileReloader(options) {
|
|
|
2771
2911
|
const { server, getLatestConfig, updateConfig } = options;
|
|
2772
2912
|
const fileChangedMutex = new Mutex();
|
|
2773
2913
|
const changeQueue = [];
|
|
2774
|
-
return async (event,
|
|
2914
|
+
return async (event, path6) => {
|
|
2775
2915
|
const config = await getLatestConfig();
|
|
2776
2916
|
updateConfig(config);
|
|
2777
|
-
if (
|
|
2917
|
+
if (path6.startsWith(config.outBaseDir))
|
|
2778
2918
|
return;
|
|
2779
|
-
changeQueue.push([event,
|
|
2919
|
+
changeQueue.push([event, path6]);
|
|
2780
2920
|
await fileChangedMutex.runExclusive(async () => {
|
|
2781
2921
|
const fileChanges = changeQueue.splice(0, changeQueue.length);
|
|
2782
2922
|
if (fileChanges.length === 0)
|
|
@@ -2792,8 +2932,10 @@ function createFileReloader(options) {
|
|
|
2792
2932
|
relative8(config.outDir, getEntrypointOutputFile(entry, ""))
|
|
2793
2933
|
);
|
|
2794
2934
|
}).join(pc6.dim(", "));
|
|
2935
|
+
const allEntrypoints = await findEntrypoints(config);
|
|
2795
2936
|
const { output: newOutput } = await rebuild(
|
|
2796
2937
|
config,
|
|
2938
|
+
allEntrypoints,
|
|
2797
2939
|
// TODO: this excludes new entrypoints, so they're not built until the dev command is restarted
|
|
2798
2940
|
changes.rebuildGroups,
|
|
2799
2941
|
changes.cachedOutput
|
|
@@ -2846,8 +2988,8 @@ function reloadContentScripts(steps, config, server) {
|
|
|
2846
2988
|
}
|
|
2847
2989
|
function reloadHtmlPages(groups, server, config) {
|
|
2848
2990
|
groups.flat().forEach((entry) => {
|
|
2849
|
-
const
|
|
2850
|
-
server.reloadPage(
|
|
2991
|
+
const path6 = getEntrypointBundlePath(entry, config.outDir, ".html");
|
|
2992
|
+
server.reloadPage(path6);
|
|
2851
2993
|
});
|
|
2852
2994
|
}
|
|
2853
2995
|
|
|
@@ -2856,7 +2998,7 @@ import prompts from "prompts";
|
|
|
2856
2998
|
import { consola as consola5 } from "consola";
|
|
2857
2999
|
import { downloadTemplate } from "giget";
|
|
2858
3000
|
import fs14 from "fs-extra";
|
|
2859
|
-
import
|
|
3001
|
+
import path5 from "node:path";
|
|
2860
3002
|
import pc7 from "picocolors";
|
|
2861
3003
|
async function initialize(options) {
|
|
2862
3004
|
consola5.info("Initalizing new project");
|
|
@@ -2904,7 +3046,7 @@ async function initialize(options) {
|
|
|
2904
3046
|
input.template ??= defaultTemplate;
|
|
2905
3047
|
input.packageManager ??= options.packageManager;
|
|
2906
3048
|
await cloneProject(input);
|
|
2907
|
-
const cdPath =
|
|
3049
|
+
const cdPath = path5.relative(process.cwd(), path5.resolve(input.directory));
|
|
2908
3050
|
console.log();
|
|
2909
3051
|
consola5.log(
|
|
2910
3052
|
`\u2728 WXT project created with the ${TEMPLATE_COLORS[input.template.name]?.(input.template.name) ?? input.template.name} template.`
|
|
@@ -2956,8 +3098,8 @@ async function cloneProject({
|
|
|
2956
3098
|
force: true
|
|
2957
3099
|
});
|
|
2958
3100
|
await fs14.move(
|
|
2959
|
-
|
|
2960
|
-
|
|
3101
|
+
path5.join(directory, "_gitignore"),
|
|
3102
|
+
path5.join(directory, ".gitignore")
|
|
2961
3103
|
).catch(
|
|
2962
3104
|
(err) => consola5.warn("Failed to move _gitignore to .gitignore:", err)
|
|
2963
3105
|
);
|
|
@@ -3023,8 +3165,8 @@ async function zip(config) {
|
|
|
3023
3165
|
);
|
|
3024
3166
|
await zipdir(internalConfig.zip.sourcesRoot, {
|
|
3025
3167
|
saveTo: sourcesZipPath,
|
|
3026
|
-
filter(
|
|
3027
|
-
const relativePath = relative9(internalConfig.zip.sourcesRoot,
|
|
3168
|
+
filter(path6) {
|
|
3169
|
+
const relativePath = relative9(internalConfig.zip.sourcesRoot, path6);
|
|
3028
3170
|
const matchedPattern = internalConfig.zip.ignoredSources.find(
|
|
3029
3171
|
(pattern) => minimatch2(relativePath, pattern)
|
|
3030
3172
|
);
|