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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "0.14.
|
|
2
|
+
var version = "0.14.2-alpha2";
|
|
3
3
|
|
|
4
4
|
// src/core/utils/arrays.ts
|
|
5
5
|
function every(array, predicate) {
|
|
@@ -12,11 +12,11 @@ function every(array, predicate) {
|
|
|
12
12
|
// src/core/utils/paths.ts
|
|
13
13
|
import systemPath from "node:path";
|
|
14
14
|
import normalize from "normalize-path";
|
|
15
|
-
function normalizePath(
|
|
16
|
-
return normalize(
|
|
15
|
+
function normalizePath(path5) {
|
|
16
|
+
return normalize(path5);
|
|
17
17
|
}
|
|
18
|
-
function unnormalizePath(
|
|
19
|
-
return systemPath.normalize(
|
|
18
|
+
function unnormalizePath(path5) {
|
|
19
|
+
return systemPath.normalize(path5);
|
|
20
20
|
}
|
|
21
21
|
var CSS_EXTENSIONS = ["css", "scss", "sass", "less", "styl", "stylus"];
|
|
22
22
|
var CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
|
|
@@ -131,7 +131,7 @@ import { relative as relative4, resolve as resolve12 } from "path";
|
|
|
131
131
|
import fs12 from "fs-extra";
|
|
132
132
|
import { minimatch } from "minimatch";
|
|
133
133
|
import { parseHTML as parseHTML2 } from "linkedom";
|
|
134
|
-
import
|
|
134
|
+
import JSON52 from "json5";
|
|
135
135
|
|
|
136
136
|
// src/core/utils/fs.ts
|
|
137
137
|
import fs from "fs-extra";
|
|
@@ -151,8 +151,145 @@ async function getPublicFiles(config) {
|
|
|
151
151
|
|
|
152
152
|
// src/core/utils/building/build-entrypoints.ts
|
|
153
153
|
import fs2 from "fs-extra";
|
|
154
|
-
import { dirname, resolve as resolve2 } from "path";
|
|
154
|
+
import { dirname, resolve as resolve2, extname } from "node:path";
|
|
155
155
|
import pc from "picocolors";
|
|
156
|
+
|
|
157
|
+
// src/i18n/node.ts
|
|
158
|
+
import { readFile } from "node:fs/promises";
|
|
159
|
+
import JSON5 from "json5";
|
|
160
|
+
import YAML from "yaml";
|
|
161
|
+
async function readMessagesFile(file) {
|
|
162
|
+
const text = await readFile(file, "utf-8");
|
|
163
|
+
return readMessagesText(text);
|
|
164
|
+
}
|
|
165
|
+
function readMessagesText(text) {
|
|
166
|
+
const parsers = [
|
|
167
|
+
JSON.parse,
|
|
168
|
+
JSON5.parse,
|
|
169
|
+
YAML.parse
|
|
170
|
+
];
|
|
171
|
+
for (const parse of parsers) {
|
|
172
|
+
try {
|
|
173
|
+
const result = parse(text);
|
|
174
|
+
if (typeof result === "object") {
|
|
175
|
+
return readMessagesObject(result);
|
|
176
|
+
}
|
|
177
|
+
} catch {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
throw Error("I18n messages text is not valid JSON, JSON5, or YAML");
|
|
182
|
+
}
|
|
183
|
+
function readMessagesObject(input) {
|
|
184
|
+
const messagesFromInput = findEntries([], input);
|
|
185
|
+
return [...messagesFromInput, ...PREDEFINED_MESSAGES];
|
|
186
|
+
}
|
|
187
|
+
function convertMessagesToManifest(messages) {
|
|
188
|
+
return messages.filter((message) => !message.isBuiltin).reduce((schema, { name, entry }) => {
|
|
189
|
+
schema[name] = entry;
|
|
190
|
+
return schema;
|
|
191
|
+
}, {});
|
|
192
|
+
}
|
|
193
|
+
function findEntries(keyPath, input) {
|
|
194
|
+
const name = keyPath.join("_");
|
|
195
|
+
if (isBasicEntry(input))
|
|
196
|
+
return [
|
|
197
|
+
{
|
|
198
|
+
name,
|
|
199
|
+
entry: { message: input }
|
|
200
|
+
}
|
|
201
|
+
];
|
|
202
|
+
if (isManifestEntry(input))
|
|
203
|
+
return [
|
|
204
|
+
{
|
|
205
|
+
name,
|
|
206
|
+
entry: input
|
|
207
|
+
}
|
|
208
|
+
];
|
|
209
|
+
if (isPluralEntry(input))
|
|
210
|
+
return [
|
|
211
|
+
{
|
|
212
|
+
name,
|
|
213
|
+
entry: {
|
|
214
|
+
message: Object.values(input).join(" | ")
|
|
215
|
+
},
|
|
216
|
+
isPlural: true
|
|
217
|
+
}
|
|
218
|
+
];
|
|
219
|
+
return Object.entries(input).reduce((items, [key, child]) => {
|
|
220
|
+
const nestedEntries = findEntries(keyPath.concat(key), child);
|
|
221
|
+
return [...items, ...nestedEntries];
|
|
222
|
+
}, []);
|
|
223
|
+
}
|
|
224
|
+
function isBasicEntry(entry) {
|
|
225
|
+
return typeof entry === "string";
|
|
226
|
+
}
|
|
227
|
+
function isManifestEntry(entry) {
|
|
228
|
+
const keys = Object.keys(entry);
|
|
229
|
+
if (keys.length < 1 || keys.length > 3)
|
|
230
|
+
return false;
|
|
231
|
+
const knownKeys = /* @__PURE__ */ new Set(["message", "placeholders", "description"]);
|
|
232
|
+
const unknownKeys = keys.filter((key) => !knownKeys.has(key));
|
|
233
|
+
return unknownKeys.length === 0;
|
|
234
|
+
}
|
|
235
|
+
function isPluralEntry(entry) {
|
|
236
|
+
const keys = Object.keys(entry);
|
|
237
|
+
if (keys.length === 0)
|
|
238
|
+
return false;
|
|
239
|
+
const invalidKeys = keys.filter((key) => key !== "n" && isNaN(Number(key)));
|
|
240
|
+
return invalidKeys.length === 0;
|
|
241
|
+
}
|
|
242
|
+
var PREDEFINED_MESSAGES = [
|
|
243
|
+
{
|
|
244
|
+
name: "@@extension_id",
|
|
245
|
+
isBuiltin: true,
|
|
246
|
+
entry: {
|
|
247
|
+
message: "<browser.runtime.id>",
|
|
248
|
+
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."
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: "@@ui_locale",
|
|
253
|
+
isBuiltin: true,
|
|
254
|
+
entry: {
|
|
255
|
+
message: "<browser.i18n.getUiLocale()>"
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
name: "@@bidi_dir",
|
|
260
|
+
isBuiltin: true,
|
|
261
|
+
entry: {
|
|
262
|
+
message: "<ltr|rtl>",
|
|
263
|
+
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.'
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "@@bidi_reversed_dir",
|
|
268
|
+
isBuiltin: true,
|
|
269
|
+
entry: {
|
|
270
|
+
message: "<rtl|ltr>",
|
|
271
|
+
description: `If the @@bidi_dir is "ltr", then this is "rtl"; otherwise, it's "ltr".`
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
name: "@@bidi_start_edge",
|
|
276
|
+
isBuiltin: true,
|
|
277
|
+
entry: {
|
|
278
|
+
message: "<left|right>",
|
|
279
|
+
description: `If the @@bidi_dir is "ltr", then this is "left"; otherwise, it's "right".`
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
name: "@@bidi_end_edge",
|
|
284
|
+
isBuiltin: true,
|
|
285
|
+
entry: {
|
|
286
|
+
message: "<right|left>",
|
|
287
|
+
description: `If the @@bidi_dir is "ltr", then this is "right"; otherwise, it's "left".`
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
];
|
|
291
|
+
|
|
292
|
+
// src/core/utils/building/build-entrypoints.ts
|
|
156
293
|
async function buildEntrypoints(groups, config, spinner) {
|
|
157
294
|
const steps = [];
|
|
158
295
|
for (let i = 0; i < groups.length; i++) {
|
|
@@ -161,7 +298,10 @@ async function buildEntrypoints(groups, config, spinner) {
|
|
|
161
298
|
spinner.text = pc.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNames}`;
|
|
162
299
|
steps.push(await config.builder.build(group));
|
|
163
300
|
}
|
|
164
|
-
const publicAssets = await
|
|
301
|
+
const publicAssets = (await Promise.all([
|
|
302
|
+
copyPublicDirectory(config),
|
|
303
|
+
copyLocalesDirectory(config)
|
|
304
|
+
])).flat();
|
|
165
305
|
return { publicAssets, steps };
|
|
166
306
|
}
|
|
167
307
|
async function copyPublicDirectory(config) {
|
|
@@ -181,6 +321,28 @@ async function copyPublicDirectory(config) {
|
|
|
181
321
|
}
|
|
182
322
|
return publicAssets;
|
|
183
323
|
}
|
|
324
|
+
async function copyLocalesDirectory(config) {
|
|
325
|
+
const localesExist = await fs2.exists(config.localesDir);
|
|
326
|
+
if (!localesExist || config.manifest.default_locale == null)
|
|
327
|
+
return [];
|
|
328
|
+
const files = await fs2.readdir(config.localesDir);
|
|
329
|
+
return await Promise.all(
|
|
330
|
+
files.map(async (file) => {
|
|
331
|
+
const locale = file.replace(extname(file), "");
|
|
332
|
+
const fileName = unnormalizePath(`_locales/${locale}/messages.json`);
|
|
333
|
+
const srcPath = resolve2(config.localesDir, file);
|
|
334
|
+
const outPath = resolve2(config.outDir, fileName);
|
|
335
|
+
const messages = await readMessagesFile(srcPath);
|
|
336
|
+
const json = convertMessagesToManifest(messages);
|
|
337
|
+
await fs2.ensureDir(dirname(outPath));
|
|
338
|
+
await fs2.writeJson(outPath, json);
|
|
339
|
+
return {
|
|
340
|
+
fileName,
|
|
341
|
+
type: "asset"
|
|
342
|
+
};
|
|
343
|
+
})
|
|
344
|
+
);
|
|
345
|
+
}
|
|
184
346
|
|
|
185
347
|
// src/core/utils/building/generate-wxt-dir.ts
|
|
186
348
|
import { createUnimport } from "unimport";
|
|
@@ -196,7 +358,8 @@ function getUnimportOptions(config) {
|
|
|
196
358
|
debugLog: config.logger.debug,
|
|
197
359
|
imports: [
|
|
198
360
|
{ name: "defineConfig", from: "wxt" },
|
|
199
|
-
{ name: "fakeBrowser", from: "wxt/testing" }
|
|
361
|
+
{ name: "fakeBrowser", from: "wxt/testing" },
|
|
362
|
+
{ name: "i18n", from: "wxt/i18n" }
|
|
200
363
|
],
|
|
201
364
|
presets: [
|
|
202
365
|
{ package: "wxt/client" },
|
|
@@ -269,46 +432,7 @@ function surroundInUnderscore(name) {
|
|
|
269
432
|
}
|
|
270
433
|
|
|
271
434
|
// src/core/utils/building/generate-wxt-dir.ts
|
|
272
|
-
import
|
|
273
|
-
|
|
274
|
-
// src/core/utils/i18n.ts
|
|
275
|
-
var predefinedMessages = {
|
|
276
|
-
"@@extension_id": {
|
|
277
|
-
message: "<browser.runtime.id>",
|
|
278
|
-
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."
|
|
279
|
-
},
|
|
280
|
-
"@@ui_locale": {
|
|
281
|
-
message: "<browser.i18n.getUiLocale()>",
|
|
282
|
-
description: ""
|
|
283
|
-
},
|
|
284
|
-
"@@bidi_dir": {
|
|
285
|
-
message: "<ltr|rtl>",
|
|
286
|
-
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.'
|
|
287
|
-
},
|
|
288
|
-
"@@bidi_reversed_dir": {
|
|
289
|
-
message: "<rtl|ltr>",
|
|
290
|
-
description: `If the @@bidi_dir is "ltr", then this is "rtl"; otherwise, it's "ltr".`
|
|
291
|
-
},
|
|
292
|
-
"@@bidi_start_edge": {
|
|
293
|
-
message: "<left|right>",
|
|
294
|
-
description: `If the @@bidi_dir is "ltr", then this is "left"; otherwise, it's "right".`
|
|
295
|
-
},
|
|
296
|
-
"@@bidi_end_edge": {
|
|
297
|
-
message: "<right|left>",
|
|
298
|
-
description: `If the @@bidi_dir is "ltr", then this is "right"; otherwise, it's "left".`
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
function parseI18nMessages(messagesJson) {
|
|
302
|
-
return Object.entries({
|
|
303
|
-
...predefinedMessages,
|
|
304
|
-
...messagesJson
|
|
305
|
-
}).map(([name, details]) => ({
|
|
306
|
-
name,
|
|
307
|
-
...details
|
|
308
|
-
}));
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// src/core/utils/building/generate-wxt-dir.ts
|
|
435
|
+
import glob2 from "fast-glob";
|
|
312
436
|
async function generateTypesDir(entrypoints, config) {
|
|
313
437
|
await fs3.ensureDir(config.typesDir);
|
|
314
438
|
const references = [];
|
|
@@ -342,7 +466,7 @@ async function writePathsDeclarationFile(entrypoints, config) {
|
|
|
342
466
|
config.outDir,
|
|
343
467
|
entry.inputPath.endsWith(".html") ? ".html" : ".js"
|
|
344
468
|
)
|
|
345
|
-
).concat(await getPublicFiles(config)).map(normalizePath).map((
|
|
469
|
+
).concat(await getPublicFiles(config)).map(normalizePath).map((path5) => ` | "/${path5}"`).sort().join("\n");
|
|
346
470
|
const template = `// Generated by wxt
|
|
347
471
|
import "wxt/browser";
|
|
348
472
|
|
|
@@ -378,28 +502,36 @@ declare module "wxt/browser" {
|
|
|
378
502
|
}
|
|
379
503
|
|
|
380
504
|
export interface WxtI18n extends I18n.Static {
|
|
381
|
-
{{
|
|
505
|
+
{{ browserOverrides }}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
declare module "wxt/i18n" {
|
|
510
|
+
export interface WxtMessageSchema {
|
|
511
|
+
t: {
|
|
512
|
+
{{ translationTOverrides }}
|
|
513
|
+
};
|
|
514
|
+
tp: {
|
|
515
|
+
{{ translationTpOverrides }}
|
|
516
|
+
};
|
|
382
517
|
}
|
|
383
518
|
}
|
|
384
519
|
`;
|
|
385
520
|
let messages;
|
|
386
521
|
if (defaultLocale) {
|
|
387
|
-
const defaultLocalePath =
|
|
388
|
-
config.
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
);
|
|
393
|
-
const content = JSON.parse(await fs3.readFile(defaultLocalePath, "utf-8"));
|
|
394
|
-
messages = parseI18nMessages(content);
|
|
522
|
+
const [defaultLocalePath] = await glob2(`${defaultLocale}.*`, {
|
|
523
|
+
cwd: config.localesDir,
|
|
524
|
+
absolute: true
|
|
525
|
+
});
|
|
526
|
+
messages = await readMessagesFile(defaultLocalePath);
|
|
395
527
|
} else {
|
|
396
|
-
messages =
|
|
528
|
+
messages = PREDEFINED_MESSAGES;
|
|
397
529
|
}
|
|
398
530
|
const overrides = messages.map((message) => {
|
|
399
531
|
return ` /**
|
|
400
|
-
* ${message.description ?? "No message description."}
|
|
532
|
+
* ${message.entry.description ?? "No message description."}
|
|
401
533
|
*
|
|
402
|
-
* "${message.message}"
|
|
534
|
+
* "${message.entry.message}"
|
|
403
535
|
*/
|
|
404
536
|
getMessage(
|
|
405
537
|
messageName: "${message.name}",
|
|
@@ -409,7 +541,13 @@ declare module "wxt/browser" {
|
|
|
409
541
|
});
|
|
410
542
|
await writeFileIfDifferent(
|
|
411
543
|
filePath,
|
|
412
|
-
template.replace("{{
|
|
544
|
+
template.replace("{{ browserOverrides }}", overrides.join("\n")).replace(
|
|
545
|
+
"{{ translationTOverrides }}",
|
|
546
|
+
messages.filter((message) => !message.isPlural).map((message) => ` "${message.name}": any;`).join("\n")
|
|
547
|
+
).replace(
|
|
548
|
+
"{{ translationTpOverrides }}",
|
|
549
|
+
messages.filter((message) => message.isPlural).map((message) => ` "${message.name}": any;`).join("\n")
|
|
550
|
+
)
|
|
413
551
|
);
|
|
414
552
|
return filePath;
|
|
415
553
|
}
|
|
@@ -445,7 +583,7 @@ async function writeMainDeclarationFile(references, config) {
|
|
|
445
583
|
}
|
|
446
584
|
async function writeTsConfigFile(mainReference, config) {
|
|
447
585
|
const dir = config.wxtDir;
|
|
448
|
-
const getTsconfigPath = (
|
|
586
|
+
const getTsconfigPath = (path5) => normalizePath(relative2(dir, path5));
|
|
449
587
|
const paths = Object.entries(config.alias).flatMap(([alias, absolutePath]) => {
|
|
450
588
|
const aliasPath = getTsconfigPath(absolutePath);
|
|
451
589
|
return [
|
|
@@ -481,7 +619,7 @@ ${paths}
|
|
|
481
619
|
|
|
482
620
|
// src/core/utils/building/get-internal-config.ts
|
|
483
621
|
import { loadConfig } from "c12";
|
|
484
|
-
import
|
|
622
|
+
import path3 from "node:path";
|
|
485
623
|
|
|
486
624
|
// src/core/utils/cache.ts
|
|
487
625
|
import fs4, { ensureDir } from "fs-extra";
|
|
@@ -490,14 +628,14 @@ function createFsCache(wxtDir) {
|
|
|
490
628
|
const getPath = (key) => resolve4(wxtDir, "cache", encodeURIComponent(key));
|
|
491
629
|
return {
|
|
492
630
|
async set(key, value) {
|
|
493
|
-
const
|
|
494
|
-
await ensureDir(dirname2(
|
|
495
|
-
await writeFileIfDifferent(
|
|
631
|
+
const path5 = getPath(key);
|
|
632
|
+
await ensureDir(dirname2(path5));
|
|
633
|
+
await writeFileIfDifferent(path5, value);
|
|
496
634
|
},
|
|
497
635
|
async get(key) {
|
|
498
|
-
const
|
|
636
|
+
const path5 = getPath(key);
|
|
499
637
|
try {
|
|
500
|
-
return await fs4.readFile(
|
|
638
|
+
return await fs4.readFile(path5, "utf-8");
|
|
501
639
|
} catch {
|
|
502
640
|
return void 0;
|
|
503
641
|
}
|
|
@@ -719,7 +857,7 @@ function download(config) {
|
|
|
719
857
|
}
|
|
720
858
|
|
|
721
859
|
// src/core/builders/vite/plugins/multipageMove.ts
|
|
722
|
-
import { dirname as dirname4, extname, resolve as resolve6, join } from "node:path";
|
|
860
|
+
import { dirname as dirname4, extname as extname2, resolve as resolve6, join } from "node:path";
|
|
723
861
|
import fs5, { ensureDir as ensureDir2 } from "fs-extra";
|
|
724
862
|
function multipageMove(entrypoints, config) {
|
|
725
863
|
return {
|
|
@@ -738,7 +876,7 @@ function multipageMove(entrypoints, config) {
|
|
|
738
876
|
const newBundlePath = getEntrypointBundlePath(
|
|
739
877
|
entrypoint,
|
|
740
878
|
config.outDir,
|
|
741
|
-
|
|
879
|
+
extname2(oldBundlePath)
|
|
742
880
|
);
|
|
743
881
|
if (newBundlePath === oldBundlePath) {
|
|
744
882
|
config.logger.debug(
|
|
@@ -779,7 +917,7 @@ async function removeEmptyDirs(dir) {
|
|
|
779
917
|
|
|
780
918
|
// src/core/builders/vite/plugins/unimport.ts
|
|
781
919
|
import { createUnimport as createUnimport2 } from "unimport";
|
|
782
|
-
import { extname as
|
|
920
|
+
import { extname as extname3 } from "path";
|
|
783
921
|
var ENABLED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
784
922
|
".js",
|
|
785
923
|
".jsx",
|
|
@@ -801,7 +939,7 @@ function unimport(config) {
|
|
|
801
939
|
async transform(code, id) {
|
|
802
940
|
if (id.includes("node_modules"))
|
|
803
941
|
return;
|
|
804
|
-
if (!ENABLED_EXTENSIONS.has(
|
|
942
|
+
if (!ENABLED_EXTENSIONS.has(extname3(id)))
|
|
805
943
|
return;
|
|
806
944
|
return unimport2.injectImports(code, id);
|
|
807
945
|
}
|
|
@@ -927,7 +1065,7 @@ function globals(config) {
|
|
|
927
1065
|
}
|
|
928
1066
|
|
|
929
1067
|
// src/core/builders/vite/plugins/webextensionPolyfillMock.ts
|
|
930
|
-
import
|
|
1068
|
+
import path2 from "node:path";
|
|
931
1069
|
function webextensionPolyfillMock(config) {
|
|
932
1070
|
return {
|
|
933
1071
|
name: "wxt:testing-inline-deps",
|
|
@@ -936,7 +1074,7 @@ function webextensionPolyfillMock(config) {
|
|
|
936
1074
|
resolve: {
|
|
937
1075
|
alias: {
|
|
938
1076
|
// Alias to use a mocked version of the polyfill
|
|
939
|
-
"webextension-polyfill":
|
|
1077
|
+
"webextension-polyfill": path2.resolve(
|
|
940
1078
|
config.root,
|
|
941
1079
|
"node_modules/wxt/dist/virtual/mock-browser"
|
|
942
1080
|
)
|
|
@@ -993,7 +1131,7 @@ function entrypointGroupGlobals(entrypointGroup) {
|
|
|
993
1131
|
}
|
|
994
1132
|
|
|
995
1133
|
// src/core/builders/vite/index.ts
|
|
996
|
-
async function
|
|
1134
|
+
async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
|
|
997
1135
|
const vite = await import("vite");
|
|
998
1136
|
const getBaseConfig = async () => {
|
|
999
1137
|
const resolvedInlineConfig = await inlineConfig.vite?.(wxtConfig.env) ?? {};
|
|
@@ -1221,19 +1359,20 @@ async function getInternalConfig(inlineConfig, command, server) {
|
|
|
1221
1359
|
const manifestVersion = mergedConfig.manifestVersion ?? (browser === "firefox" || browser === "safari" ? 2 : 3);
|
|
1222
1360
|
const mode = mergedConfig.mode ?? (command === "build" ? "production" : "development");
|
|
1223
1361
|
const env = { browser, command, manifestVersion, mode };
|
|
1224
|
-
const root =
|
|
1362
|
+
const root = path3.resolve(
|
|
1225
1363
|
inlineConfig.root ?? userConfig.root ?? process.cwd()
|
|
1226
1364
|
);
|
|
1227
|
-
const wxtDir =
|
|
1228
|
-
const srcDir =
|
|
1229
|
-
const entrypointsDir =
|
|
1365
|
+
const wxtDir = path3.resolve(root, ".wxt");
|
|
1366
|
+
const srcDir = path3.resolve(root, mergedConfig.srcDir ?? root);
|
|
1367
|
+
const entrypointsDir = path3.resolve(
|
|
1230
1368
|
srcDir,
|
|
1231
1369
|
mergedConfig.entrypointsDir ?? "entrypoints"
|
|
1232
1370
|
);
|
|
1233
|
-
const publicDir =
|
|
1234
|
-
const
|
|
1235
|
-
const
|
|
1236
|
-
const
|
|
1371
|
+
const publicDir = path3.resolve(srcDir, mergedConfig.publicDir ?? "public");
|
|
1372
|
+
const localesDir = path3.resolve(srcDir, mergedConfig.localesDir ?? "locales");
|
|
1373
|
+
const typesDir = path3.resolve(wxtDir, "types");
|
|
1374
|
+
const outBaseDir = path3.resolve(root, mergedConfig.outDir ?? ".output");
|
|
1375
|
+
const outDir = path3.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
|
|
1237
1376
|
const runnerConfig = await loadConfig({
|
|
1238
1377
|
name: "web-ext",
|
|
1239
1378
|
cwd: root,
|
|
@@ -1249,7 +1388,7 @@ async function getInternalConfig(inlineConfig, command, server) {
|
|
|
1249
1388
|
"~": srcDir,
|
|
1250
1389
|
"@@": root,
|
|
1251
1390
|
"~~": root
|
|
1252
|
-
}).map(([key, value]) => [key,
|
|
1391
|
+
}).map(([key, value]) => [key, path3.resolve(root, value)])
|
|
1253
1392
|
);
|
|
1254
1393
|
const finalConfig = {
|
|
1255
1394
|
browser,
|
|
@@ -1266,6 +1405,7 @@ async function getInternalConfig(inlineConfig, command, server) {
|
|
|
1266
1405
|
outBaseDir,
|
|
1267
1406
|
outDir,
|
|
1268
1407
|
publicDir,
|
|
1408
|
+
localesDir,
|
|
1269
1409
|
root,
|
|
1270
1410
|
runnerConfig,
|
|
1271
1411
|
srcDir,
|
|
@@ -1287,7 +1427,7 @@ async function getInternalConfig(inlineConfig, command, server) {
|
|
|
1287
1427
|
},
|
|
1288
1428
|
server
|
|
1289
1429
|
};
|
|
1290
|
-
const builder = await
|
|
1430
|
+
const builder = await createViteBuilder(
|
|
1291
1431
|
inlineConfig,
|
|
1292
1432
|
userConfig,
|
|
1293
1433
|
finalConfig
|
|
@@ -1334,6 +1474,7 @@ function mergeInlineConfig(inlineConfig, userConfig) {
|
|
|
1334
1474
|
manifest,
|
|
1335
1475
|
mode: inlineConfig.mode ?? userConfig.mode,
|
|
1336
1476
|
publicDir: inlineConfig.publicDir ?? userConfig.publicDir,
|
|
1477
|
+
localesDir: inlineConfig.localesDir ?? userConfig.localesDir,
|
|
1337
1478
|
runner,
|
|
1338
1479
|
srcDir: inlineConfig.srcDir ?? userConfig.srcDir,
|
|
1339
1480
|
outDir: inlineConfig.outDir ?? userConfig.outDir,
|
|
@@ -1438,16 +1579,16 @@ ${noImports}`;
|
|
|
1438
1579
|
// src/core/utils/building/import-entrypoint.ts
|
|
1439
1580
|
import { transformSync } from "esbuild";
|
|
1440
1581
|
import { fileURLToPath } from "node:url";
|
|
1441
|
-
async function importEntrypointFile(
|
|
1442
|
-
config.logger.debug("Loading file metadata:",
|
|
1443
|
-
const normalPath = normalizePath(
|
|
1582
|
+
async function importEntrypointFile(path5, config) {
|
|
1583
|
+
config.logger.debug("Loading file metadata:", path5);
|
|
1584
|
+
const normalPath = normalizePath(path5);
|
|
1444
1585
|
const unimport2 = createUnimport3({
|
|
1445
1586
|
...getUnimportOptions(config),
|
|
1446
1587
|
// Only allow specific imports, not all from the project
|
|
1447
1588
|
dirs: []
|
|
1448
1589
|
});
|
|
1449
1590
|
await unimport2.init();
|
|
1450
|
-
const text = await fs7.readFile(
|
|
1591
|
+
const text = await fs7.readFile(path5, "utf-8");
|
|
1451
1592
|
const textNoImports = removeProjectImportStatements(text);
|
|
1452
1593
|
const { code } = await unimport2.injectImports(textNoImports);
|
|
1453
1594
|
config.logger.debug(
|
|
@@ -1490,7 +1631,7 @@ async function importEntrypointFile(path6, config) {
|
|
|
1490
1631
|
}
|
|
1491
1632
|
);
|
|
1492
1633
|
try {
|
|
1493
|
-
const res = await jiti(
|
|
1634
|
+
const res = await jiti(path5);
|
|
1494
1635
|
return res.default;
|
|
1495
1636
|
} catch (err) {
|
|
1496
1637
|
config.logger.error(err);
|
|
@@ -1514,7 +1655,7 @@ import fs11 from "fs-extra";
|
|
|
1514
1655
|
import { resolve as resolve9 } from "path";
|
|
1515
1656
|
|
|
1516
1657
|
// src/core/utils/log/printFileList.ts
|
|
1517
|
-
import
|
|
1658
|
+
import path4 from "node:path";
|
|
1518
1659
|
import pc2 from "picocolors";
|
|
1519
1660
|
import fs8 from "fs-extra";
|
|
1520
1661
|
import { filesize } from "filesize";
|
|
@@ -1552,8 +1693,8 @@ async function printFileList(log, header, baseDir, files) {
|
|
|
1552
1693
|
const fileRows = await Promise.all(
|
|
1553
1694
|
files.map(async (file, i) => {
|
|
1554
1695
|
const parts = [
|
|
1555
|
-
|
|
1556
|
-
|
|
1696
|
+
path4.relative(process.cwd(), baseDir) + path4.sep,
|
|
1697
|
+
path4.relative(baseDir, file)
|
|
1557
1698
|
];
|
|
1558
1699
|
const prefix = i === files.length - 1 ? " \u2514\u2500" : " \u251C\u2500";
|
|
1559
1700
|
const color = getChunkColor(file);
|
|
@@ -1620,7 +1761,7 @@ import pc3 from "picocolors";
|
|
|
1620
1761
|
import { consola as consola2 } from "consola";
|
|
1621
1762
|
|
|
1622
1763
|
// src/core/utils/building/internal-build.ts
|
|
1623
|
-
import
|
|
1764
|
+
import glob3 from "fast-glob";
|
|
1624
1765
|
|
|
1625
1766
|
// src/core/utils/manifest.ts
|
|
1626
1767
|
import fs10 from "fs-extra";
|
|
@@ -1777,7 +1918,7 @@ async function generateManifest(entrypoints, buildOutput, config) {
|
|
|
1777
1918
|
"wxt:reload-extension": {
|
|
1778
1919
|
description: "Reload the extension during development",
|
|
1779
1920
|
suggested_key: {
|
|
1780
|
-
default: "
|
|
1921
|
+
default: "Alt+R"
|
|
1781
1922
|
}
|
|
1782
1923
|
}
|
|
1783
1924
|
};
|
|
@@ -2150,13 +2291,12 @@ function stripPathFromMatchPattern(pattern) {
|
|
|
2150
2291
|
}
|
|
2151
2292
|
|
|
2152
2293
|
// src/core/utils/building/rebuild.ts
|
|
2153
|
-
async function rebuild(config, entrypointGroups, existingOutput = {
|
|
2294
|
+
async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput = {
|
|
2154
2295
|
steps: [],
|
|
2155
2296
|
publicAssets: []
|
|
2156
2297
|
}) {
|
|
2157
2298
|
const { default: ora } = await import("ora");
|
|
2158
2299
|
const spinner = ora(`Preparing...`).start();
|
|
2159
|
-
const allEntrypoints = await findEntrypoints(config);
|
|
2160
2300
|
await generateTypesDir(allEntrypoints, config).catch((err) => {
|
|
2161
2301
|
config.logger.warn("Failed to update .wxt directory:", err);
|
|
2162
2302
|
if (config.command === "build")
|
|
@@ -2206,7 +2346,7 @@ async function internalBuild(config) {
|
|
|
2206
2346
|
const entrypoints = await findEntrypoints(config);
|
|
2207
2347
|
config.logger.debug("Detected entrypoints:", entrypoints);
|
|
2208
2348
|
const groups = groupEntrypoints(entrypoints);
|
|
2209
|
-
const { output } = await rebuild(config, groups, void 0);
|
|
2349
|
+
const { output } = await rebuild(config, entrypoints, groups, void 0);
|
|
2210
2350
|
await printBuildSummary(
|
|
2211
2351
|
config.logger.success,
|
|
2212
2352
|
`Built extension in ${formatDuration(Date.now() - startTime)}`,
|
|
@@ -2224,7 +2364,7 @@ async function internalBuild(config) {
|
|
|
2224
2364
|
}
|
|
2225
2365
|
async function combineAnalysisStats(config) {
|
|
2226
2366
|
const { execaCommand } = await import("./execa-4F7CCWCA.js");
|
|
2227
|
-
const unixFiles = await
|
|
2367
|
+
const unixFiles = await glob3(`stats-*.json`, {
|
|
2228
2368
|
cwd: config.outDir,
|
|
2229
2369
|
absolute: true
|
|
2230
2370
|
});
|
|
@@ -2236,9 +2376,9 @@ async function combineAnalysisStats(config) {
|
|
|
2236
2376
|
}
|
|
2237
2377
|
|
|
2238
2378
|
// src/core/utils/building/find-entrypoints.ts
|
|
2239
|
-
import
|
|
2379
|
+
import glob4 from "fast-glob";
|
|
2240
2380
|
async function findEntrypoints(config) {
|
|
2241
|
-
const relativePaths = await
|
|
2381
|
+
const relativePaths = await glob4(Object.keys(PATH_GLOB_TO_TYPE_MAP), {
|
|
2242
2382
|
cwd: config.entrypointsDir
|
|
2243
2383
|
});
|
|
2244
2384
|
relativePaths.sort();
|
|
@@ -2247,7 +2387,7 @@ async function findEntrypoints(config) {
|
|
|
2247
2387
|
const inputPath = resolve12(config.entrypointsDir, relativePath);
|
|
2248
2388
|
const name = getEntrypointName(config.entrypointsDir, inputPath);
|
|
2249
2389
|
const matchingGlob = pathGlobs.find(
|
|
2250
|
-
(
|
|
2390
|
+
(glob5) => minimatch(relativePath, glob5)
|
|
2251
2391
|
);
|
|
2252
2392
|
if (matchingGlob) {
|
|
2253
2393
|
const type = PATH_GLOB_TO_TYPE_MAP[matchingGlob];
|
|
@@ -2366,11 +2506,11 @@ function getHtmlBaseOptions(document) {
|
|
|
2366
2506
|
const options = {};
|
|
2367
2507
|
const includeContent = document.querySelector("meta[name='manifest.include']")?.getAttribute("content");
|
|
2368
2508
|
if (includeContent) {
|
|
2369
|
-
options.include =
|
|
2509
|
+
options.include = JSON52.parse(includeContent);
|
|
2370
2510
|
}
|
|
2371
2511
|
const excludeContent = document.querySelector("meta[name='manifest.exclude']")?.getAttribute("content");
|
|
2372
2512
|
if (excludeContent) {
|
|
2373
|
-
options.exclude =
|
|
2513
|
+
options.exclude = JSON52.parse(excludeContent);
|
|
2374
2514
|
}
|
|
2375
2515
|
return options;
|
|
2376
2516
|
}
|
|
@@ -2384,7 +2524,7 @@ async function getPopupEntrypoint(config, { inputPath, name }) {
|
|
|
2384
2524
|
const defaultIconContent = document.querySelector("meta[name='manifest.default_icon']")?.getAttribute("content");
|
|
2385
2525
|
if (defaultIconContent) {
|
|
2386
2526
|
try {
|
|
2387
|
-
options.defaultIcon =
|
|
2527
|
+
options.defaultIcon = JSON52.parse(defaultIconContent);
|
|
2388
2528
|
} catch (err) {
|
|
2389
2529
|
config.logger.fatal(
|
|
2390
2530
|
`Failed to parse default_icon meta tag content as JSON5. content=${defaultIconContent}`,
|