wxt 0.20.7 → 0.20.8
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/README.md +21 -47
- package/dist/core/builders/vite/index.d.ts +4 -0
- package/dist/core/builders/vite/index.mjs +55 -16
- package/dist/core/builders/vite/plugins/devServerGlobals.mjs +1 -1
- package/dist/core/builders/vite/plugins/iifeFooter.d.ts +8 -0
- package/dist/core/builders/vite/plugins/iifeFooter.mjs +12 -0
- package/dist/core/builders/vite/plugins/index.d.ts +1 -1
- package/dist/core/builders/vite/plugins/index.mjs +1 -1
- package/dist/core/create-server.mjs +4 -2
- package/dist/core/initialize.mjs +1 -1
- package/dist/core/keyboard-shortcuts.mjs +2 -4
- package/dist/core/runners/web-ext.mjs +1 -0
- package/dist/core/utils/building/build-entrypoints.mjs +1 -1
- package/dist/core/utils/minimatch-multiple.d.ts +15 -0
- package/dist/core/utils/minimatch-multiple.mjs +17 -0
- package/dist/core/utils/testing/fake-objects.d.ts +253 -234
- package/dist/core/zip.mjs +2 -2
- package/dist/utils/app-config.d.ts +1 -1
- package/dist/utils/content-script-context.d.ts +10 -0
- package/dist/utils/content-script-context.mjs +8 -0
- package/dist/utils/split-shadow-root-css.d.ts +1 -0
- package/dist/version.mjs +1 -1
- package/dist/virtual/background-entrypoint.mjs +14 -2
- package/package.json +4 -4
- package/dist/core/builders/vite/plugins/multipageMove.d.ts +0 -20
- package/dist/core/builders/vite/plugins/multipageMove.mjs +0 -59
package/README.md
CHANGED
|
@@ -1,51 +1,33 @@
|
|
|
1
1
|
<!-- DO NOT EDIT, THIS FILE WAS GENERATED BY '../../scripts/generate-readmes.sh' -->
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<span>⚡</span>
|
|
21
|
-
<br/>
|
|
22
|
-
<q><i>It's like Nuxt, but for Web Extensions</i></q>
|
|
23
|
-
</p>
|
|
24
|
-
|
|
25
|
-
<p align="center">
|
|
26
|
-
<a href="https://wxt.dev/guide/installation.html" target="_blank">Get Started</a>
|
|
27
|
-
•
|
|
28
|
-
<a href="https://wxt.dev/api/config.html" target="_blank">Configuration</a>
|
|
29
|
-
•
|
|
30
|
-
<a href="https://wxt.dev/examples.html" target="_blank">Examples</a>
|
|
31
|
-
•
|
|
32
|
-
<a href="https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md" target="_blank">Changelog</a>
|
|
33
|
-
•
|
|
34
|
-
<a href="https://discord.gg/ZFsZqGery9" target="_blank">Discord</a>
|
|
35
|
-
</p>
|
|
2
|
+
<div align="center">
|
|
3
|
+
|
|
4
|
+
# <img align="top" width="44" src="https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/public/hero-logo.svg" alt="WXT Logo"> WXT
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/wxt)
|
|
7
|
+
[](https://www.npmjs.com/package/wxt)
|
|
8
|
+
[](https://github.com/wxt-dev/wxt/blob/main/LICENSE)
|
|
9
|
+
[](https://codecov.io/github/wxt-dev/wxt)
|
|
10
|
+
|
|
11
|
+
Next-gen framework for developing web extensions.<br/>⚡<br/><q><i>It's like Nuxt, but for Web Extensions</i></q>
|
|
12
|
+
|
|
13
|
+
[Get Started](https://wxt.dev/guide/installation.html) •
|
|
14
|
+
[Configuration](https://wxt.dev/api/config.html) •
|
|
15
|
+
[Examples](https://wxt.dev/examples.html) •
|
|
16
|
+
[Changelog](https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md) •
|
|
17
|
+
[Discord](https://discord.gg/ZFsZqGery9)
|
|
18
|
+
|
|
19
|
+
</div>
|
|
36
20
|
|
|
37
21
|

|
|
38
22
|
|
|
39
23
|
## Demo
|
|
40
24
|
|
|
41
|
-
https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94
|
|
25
|
+
<https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94>
|
|
42
26
|
|
|
43
27
|
## Quick Start
|
|
44
28
|
|
|
45
29
|
Bootstrap a new project:
|
|
46
30
|
|
|
47
|
-
<!-- automd:pm-x version="latest" name="wxt" args="init" -->
|
|
48
|
-
|
|
49
31
|
```sh
|
|
50
32
|
# npm
|
|
51
33
|
npx wxt@latest init
|
|
@@ -57,8 +39,6 @@ pnpm dlx wxt@latest init
|
|
|
57
39
|
bunx wxt@latest init
|
|
58
40
|
```
|
|
59
41
|
|
|
60
|
-
<!-- /automd -->
|
|
61
|
-
|
|
62
42
|
Or see the [installation guide](https://wxt.dev/guide/installation.html) to get started with WXT.
|
|
63
43
|
|
|
64
44
|
## Features
|
|
@@ -80,17 +60,11 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get
|
|
|
80
60
|
|
|
81
61
|
WXT is a [MIT-licensed](https://github.com/wxt-dev/wxt/blob/main/LICENSE) open source project with its ongoing development made possible entirely by the support of these awesome backers. If you'd like to join them, please consider [sponsoring WXT's development](https://github.com/sponsors/wxt-dev).
|
|
82
62
|
|
|
83
|
-
|
|
63
|
+
[](https://github.com/sponsors/wxt-dev)
|
|
84
64
|
|
|
85
65
|
## Contributors
|
|
86
66
|
|
|
87
|
-
<!-- automd:contributors author="aklinker1" license="MIT" github="wxt-dev/wxt" -->
|
|
88
|
-
|
|
89
67
|
Published under the [MIT](https://github.com/wxt-dev/wxt/blob/main/LICENSE) license.
|
|
90
68
|
Made by [@aklinker1](https://github.com/aklinker1) and [community](https://github.com/wxt-dev/wxt/graphs/contributors) 💛
|
|
91
|
-
<br><br>
|
|
92
|
-
<a href="https://github.com/wxt-dev/wxt/graphs/contributors">
|
|
93
|
-
<img src="https://contrib.rocks/image?repo=wxt-dev/wxt" />
|
|
94
|
-
</a>
|
|
95
69
|
|
|
96
|
-
|
|
70
|
+
[](https://github.com/wxt-dev/wxt/graphs/contributors)
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { ResolvedConfig, WxtBuilder, WxtDevServer, WxtHooks } from '../../../types';
|
|
2
2
|
import { Hookable } from 'hookable';
|
|
3
3
|
export declare function createViteBuilder(wxtConfig: ResolvedConfig, hooks: Hookable<WxtHooks>, getWxtDevServer?: () => WxtDevServer | undefined): Promise<WxtBuilder>;
|
|
4
|
+
/**
|
|
5
|
+
* Recursively remove all directories that are empty/
|
|
6
|
+
*/
|
|
7
|
+
export declare function removeEmptyDirs(dir: string): Promise<void>;
|
|
@@ -9,7 +9,9 @@ import { ViteNodeServer } from "vite-node/server";
|
|
|
9
9
|
import { ViteNodeRunner } from "vite-node/client";
|
|
10
10
|
import { installSourcemapsSupport } from "vite-node/source-map";
|
|
11
11
|
import { createExtensionEnvironment } from "../../utils/environments/index.mjs";
|
|
12
|
-
import { relative } from "node:path";
|
|
12
|
+
import { dirname, extname, join, relative } from "node:path";
|
|
13
|
+
import fs from "fs-extra";
|
|
14
|
+
import { normalizePath } from "../../utils/paths.mjs";
|
|
13
15
|
export async function createViteBuilder(wxtConfig, hooks, getWxtDevServer) {
|
|
14
16
|
const vite = await import("vite");
|
|
15
17
|
const getBaseConfig = async (baseConfigOptions) => {
|
|
@@ -62,20 +64,16 @@ export async function createViteBuilder(wxtConfig, hooks, getWxtDevServer) {
|
|
|
62
64
|
const plugins = [
|
|
63
65
|
wxtPlugins.entrypointGroupGlobals(entrypoint)
|
|
64
66
|
];
|
|
67
|
+
const iifeReturnValueName = safeVarName(entrypoint.name);
|
|
65
68
|
if (entrypoint.type === "content-script-style" || entrypoint.type === "unlisted-style") {
|
|
66
69
|
plugins.push(wxtPlugins.cssEntrypoints(entrypoint, wxtConfig));
|
|
67
70
|
}
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
if (entrypoint.type === "content-script" || entrypoint.type === "unlisted-script") {
|
|
72
|
+
plugins.push(wxtPlugins.iifeFooter(iifeReturnValueName));
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
70
75
|
mode: wxtConfig.mode,
|
|
71
76
|
plugins,
|
|
72
|
-
esbuild: {
|
|
73
|
-
// Add a footer with the returned value so it can return values to `scripting.executeScript`
|
|
74
|
-
// Footer is added a part of esbuild to make sure it's not minified. It
|
|
75
|
-
// get's removed if added to `build.rollupOptions.output.footer`
|
|
76
|
-
// See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/executeScript#return_value
|
|
77
|
-
footer: iifeReturnValueName + ";"
|
|
78
|
-
},
|
|
79
77
|
build: {
|
|
80
78
|
lib: {
|
|
81
79
|
entry,
|
|
@@ -109,7 +107,6 @@ export async function createViteBuilder(wxtConfig, hooks, getWxtDevServer) {
|
|
|
109
107
|
"process.env.NODE_ENV": JSON.stringify(wxtConfig.mode)
|
|
110
108
|
}
|
|
111
109
|
};
|
|
112
|
-
return libMode;
|
|
113
110
|
};
|
|
114
111
|
const getMultiPageConfig = (entrypoints) => {
|
|
115
112
|
const htmlEntrypoints = new Set(
|
|
@@ -117,10 +114,7 @@ export async function createViteBuilder(wxtConfig, hooks, getWxtDevServer) {
|
|
|
117
114
|
);
|
|
118
115
|
return {
|
|
119
116
|
mode: wxtConfig.mode,
|
|
120
|
-
plugins: [
|
|
121
|
-
wxtPlugins.multipageMove(entrypoints, wxtConfig),
|
|
122
|
-
wxtPlugins.entrypointGroupGlobals(entrypoints)
|
|
123
|
-
],
|
|
117
|
+
plugins: [wxtPlugins.entrypointGroupGlobals(entrypoints)],
|
|
124
118
|
build: {
|
|
125
119
|
rollupOptions: {
|
|
126
120
|
input: entrypoints.reduce((input, entry) => {
|
|
@@ -248,9 +242,10 @@ export async function createViteBuilder(wxtConfig, hooks, getWxtDevServer) {
|
|
|
248
242
|
buildConfig
|
|
249
243
|
);
|
|
250
244
|
const result = await vite.build(buildConfig);
|
|
245
|
+
const chunks = getBuildOutputChunks(result);
|
|
251
246
|
return {
|
|
252
247
|
entrypoints: group,
|
|
253
|
-
chunks:
|
|
248
|
+
chunks: await moveHtmlFiles(wxtConfig, group, chunks)
|
|
254
249
|
};
|
|
255
250
|
},
|
|
256
251
|
async createServer(info) {
|
|
@@ -315,3 +310,47 @@ function getRollupEntry(entrypoint) {
|
|
|
315
310
|
}
|
|
316
311
|
return entrypoint.inputPath;
|
|
317
312
|
}
|
|
313
|
+
async function moveHtmlFiles(config, group, chunks) {
|
|
314
|
+
if (!Array.isArray(group)) return chunks;
|
|
315
|
+
const entryMap = group.reduce((map, entry) => {
|
|
316
|
+
const a = normalizePath(relative(config.root, entry.inputPath));
|
|
317
|
+
map[a] = entry;
|
|
318
|
+
return map;
|
|
319
|
+
}, {});
|
|
320
|
+
const movedChunks = await Promise.all(
|
|
321
|
+
chunks.map(async (chunk) => {
|
|
322
|
+
if (!chunk.fileName.endsWith(".html")) return chunk;
|
|
323
|
+
const entry = entryMap[chunk.fileName];
|
|
324
|
+
const oldBundlePath = chunk.fileName;
|
|
325
|
+
const newBundlePath = getEntrypointBundlePath(
|
|
326
|
+
entry,
|
|
327
|
+
config.outDir,
|
|
328
|
+
extname(chunk.fileName)
|
|
329
|
+
);
|
|
330
|
+
const oldAbsPath = join(config.outDir, oldBundlePath);
|
|
331
|
+
const newAbsPath = join(config.outDir, newBundlePath);
|
|
332
|
+
await fs.ensureDir(dirname(newAbsPath));
|
|
333
|
+
await fs.move(oldAbsPath, newAbsPath, { overwrite: true });
|
|
334
|
+
return {
|
|
335
|
+
...chunk,
|
|
336
|
+
fileName: newBundlePath
|
|
337
|
+
};
|
|
338
|
+
})
|
|
339
|
+
);
|
|
340
|
+
removeEmptyDirs(config.outDir);
|
|
341
|
+
return movedChunks;
|
|
342
|
+
}
|
|
343
|
+
export async function removeEmptyDirs(dir) {
|
|
344
|
+
const files = await fs.readdir(dir);
|
|
345
|
+
for (const file of files) {
|
|
346
|
+
const filePath = join(dir, file);
|
|
347
|
+
const stats = await fs.stat(filePath);
|
|
348
|
+
if (stats.isDirectory()) {
|
|
349
|
+
await removeEmptyDirs(filePath);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
try {
|
|
353
|
+
await fs.rmdir(dir);
|
|
354
|
+
} catch {
|
|
355
|
+
}
|
|
356
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
/**
|
|
3
|
+
* Add a footer with the returned value so it can return values to `scripting.executeScript`
|
|
4
|
+
* Footer is added a part of esbuild to make sure it's not minified. It
|
|
5
|
+
* get's removed if added to `build.rollupOptions.output.footer`
|
|
6
|
+
* See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/executeScript#return_value
|
|
7
|
+
*/
|
|
8
|
+
export declare function iifeFooter(iifeReturnValueName: string): Plugin;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function iifeFooter(iifeReturnValueName) {
|
|
2
|
+
return {
|
|
3
|
+
name: "wxt:iife-footer",
|
|
4
|
+
generateBundle(_, bundle) {
|
|
5
|
+
for (const chunk of Object.values(bundle)) {
|
|
6
|
+
if (chunk.type === "chunk" && chunk.isEntry) {
|
|
7
|
+
chunk.code += `${iifeReturnValueName};`;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export * from './devHtmlPrerender';
|
|
2
2
|
export * from './devServerGlobals';
|
|
3
3
|
export * from './download';
|
|
4
|
-
export * from './multipageMove';
|
|
5
4
|
export * from './resolveVirtualModules';
|
|
6
5
|
export * from './tsconfigPaths';
|
|
7
6
|
export * from './noopBackground';
|
|
@@ -14,3 +13,4 @@ export * from './defineImportMeta';
|
|
|
14
13
|
export * from './removeEntrypointMainFunction';
|
|
15
14
|
export * from './wxtPluginLoader';
|
|
16
15
|
export * from './resolveAppConfig';
|
|
16
|
+
export * from './iifeFooter';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export * from "./devHtmlPrerender.mjs";
|
|
2
2
|
export * from "./devServerGlobals.mjs";
|
|
3
3
|
export * from "./download.mjs";
|
|
4
|
-
export * from "./multipageMove.mjs";
|
|
5
4
|
export * from "./resolveVirtualModules.mjs";
|
|
6
5
|
export * from "./tsconfigPaths.mjs";
|
|
7
6
|
export * from "./noopBackground.mjs";
|
|
@@ -14,3 +13,4 @@ export * from "./defineImportMeta.mjs";
|
|
|
14
13
|
export * from "./removeEntrypointMainFunction.mjs";
|
|
15
14
|
export * from "./wxtPluginLoader.mjs";
|
|
16
15
|
export * from "./resolveAppConfig.mjs";
|
|
16
|
+
export * from "./iifeFooter.mjs";
|
|
@@ -73,8 +73,10 @@ async function createServerInternal() {
|
|
|
73
73
|
});
|
|
74
74
|
await buildAndOpenBrowser();
|
|
75
75
|
const reloadOnChange = createFileReloader(server);
|
|
76
|
-
server.watcher.on("all",
|
|
77
|
-
|
|
76
|
+
server.watcher.on("all", async (...args) => {
|
|
77
|
+
await reloadOnChange(args[0], args[1]);
|
|
78
|
+
keyboardShortcuts.start();
|
|
79
|
+
});
|
|
78
80
|
keyboardShortcuts.printHelp({
|
|
79
81
|
canReopenBrowser: !wxt.config.runnerConfig.config.disabled && !!runner.canOpen?.()
|
|
80
82
|
});
|
package/dist/core/initialize.mjs
CHANGED
|
@@ -48,7 +48,7 @@ export async function initialize(options) {
|
|
|
48
48
|
input.packageManager ??= options.packageManager;
|
|
49
49
|
const isExists = await fs.pathExists(input.directory);
|
|
50
50
|
if (isExists) {
|
|
51
|
-
const isEmpty = (await fs.readdir(input.directory)).length === 0;
|
|
51
|
+
const isEmpty = (await fs.readdir(input.directory)).filter((dir) => dir !== ".git").length === 0;
|
|
52
52
|
if (!isEmpty) {
|
|
53
53
|
consola.error(
|
|
54
54
|
`The directory ${path.resolve(input.directory)} is not empty. Aborted.`
|
|
@@ -10,8 +10,7 @@ export function createKeyboardShortcuts(server) {
|
|
|
10
10
|
};
|
|
11
11
|
return {
|
|
12
12
|
start() {
|
|
13
|
-
|
|
14
|
-
rl = readline.createInterface({
|
|
13
|
+
rl ??= readline.createInterface({
|
|
15
14
|
input: process.stdin,
|
|
16
15
|
terminal: false
|
|
17
16
|
// Don't intercept ctrl+C, ctrl+Z, etc
|
|
@@ -19,8 +18,7 @@ export function createKeyboardShortcuts(server) {
|
|
|
19
18
|
rl.on("line", handleInput);
|
|
20
19
|
},
|
|
21
20
|
stop() {
|
|
22
|
-
rl?.
|
|
23
|
-
rl = void 0;
|
|
21
|
+
rl?.removeListener("line", handleInput);
|
|
24
22
|
},
|
|
25
23
|
printHelp(flags) {
|
|
26
24
|
if (flags.canReopenBrowser) {
|
|
@@ -25,6 +25,7 @@ export function createWebExtRunner() {
|
|
|
25
25
|
devtools: wxtUserConfig?.openDevtools,
|
|
26
26
|
startUrl: wxtUserConfig?.startUrls,
|
|
27
27
|
keepProfileChanges: wxtUserConfig?.keepProfileChanges,
|
|
28
|
+
chromiumPort: wxtUserConfig?.chromiumPort,
|
|
28
29
|
...wxt.config.browser === "firefox" ? {
|
|
29
30
|
firefox: wxtUserConfig?.binaries?.firefox,
|
|
30
31
|
firefoxProfile: wxtUserConfig?.firefoxProfile,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MinimatchOptions } from 'minimatch';
|
|
2
|
+
/**
|
|
3
|
+
* Run [`minimatch`](https://npmjs.com/package/minimatch) against multiple
|
|
4
|
+
* patterns.
|
|
5
|
+
*
|
|
6
|
+
* Supports negated patterns, the order does not matter. If your `search` string
|
|
7
|
+
* matches any of the negative patterns, it will return `false`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* minimatchMultiple('a.json', ['*.json', '!b.json']); // => true
|
|
12
|
+
* minimatchMultiple('b.json', ['*.json', '!b.json']); // => false
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare function minimatchMultiple(search: string, patterns: string[] | undefined, options?: MinimatchOptions): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { minimatch } from "minimatch";
|
|
2
|
+
export function minimatchMultiple(search, patterns, options) {
|
|
3
|
+
if (patterns == null) return false;
|
|
4
|
+
const negatePatterns = [];
|
|
5
|
+
const positivePatterns = [];
|
|
6
|
+
for (const pattern of patterns) {
|
|
7
|
+
if (pattern[0] === "!") negatePatterns.push(pattern.slice(1));
|
|
8
|
+
else positivePatterns.push(pattern);
|
|
9
|
+
}
|
|
10
|
+
if (negatePatterns.some(
|
|
11
|
+
(negatePattern) => minimatch(search, negatePattern, options)
|
|
12
|
+
))
|
|
13
|
+
return false;
|
|
14
|
+
return positivePatterns.some(
|
|
15
|
+
(positivePattern) => minimatch(search, positivePattern, options)
|
|
16
|
+
);
|
|
17
|
+
}
|