Compare commits

..

17 Commits

Author SHA1 Message Date
GitHub Actions ca5a52c6f1 chore(release): v0.17.12 2024-04-03 19:04:03 +00:00
Aaron 982c69f8ae feat: Add hooks for extending vite config (#599) 2024-04-03 14:00:48 -05:00
Aaron 6fc7d9254a fix(content-script-ui): Properly assign and unassign mounted value (#598) 2024-04-03 12:38:46 -05:00
dependabot[bot] 2e0e104d48 chore(deps): bump c12 from 1.5.1 to 1.10.0 (#592)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 23:23:11 -05:00
dependabot[bot] 02430fd7b8 chore(deps-dev): bump sass from 1.69.5 to 1.72.0 (#591)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 23:23:01 -05:00
dependabot[bot] 2e6d35d193 chore(deps-dev): bump vue from 3.3.10 to 3.4.21 (#589)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 23:08:37 -05:00
dependabot[bot] 7cf412ac1f chore(deps): bump vitest from 1.2.2 to 1.4.0 (#590)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 22:15:44 -05:00
Aaron 9398cbb596 docs: Add discord server link (#593) 2024-04-01 19:13:12 -05:00
dependabot[bot] ca9b96142e chore(deps-dev): bump @aklinker1/check from 1.1.1 to 1.2.0 (#588)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 18:10:28 -05:00
Aaron db57c8e079 chore: Remove unnecssary 'Omit' types 2024-03-31 08:40:21 -05:00
GitHub Actions 7e37e11caf chore(release): v0.17.11 2024-03-31 13:22:25 +00:00
Aaron bb90029c54 fix: Resolve absolute paths from the public directory properly (#583) 2024-03-31 08:19:06 -05:00
Aaron d3b14afbce chore: Extract helper function 2024-03-30 14:49:10 -05:00
Aaron ba2197a609 chore: Add some array utils (#582) 2024-03-30 13:30:45 -05:00
Aaron 4c558d3eb6 chore: Simplify virtual module setup (#581) 2024-03-30 12:44:27 -05:00
Qiwei Yang dcd175444a docs: Add "GitHub Custom Notifier" to homepage (#580) 2024-03-30 08:37:26 -05:00
Aaron 16fc58404a docs: Fix zip.includeSources example 2024-03-30 08:37:00 -05:00
44 changed files with 504 additions and 329 deletions
+46
View File
@@ -1,5 +1,51 @@
# Changelog
## v0.17.12
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.17.11...v0.17.12)
### 🚀 Enhancements
- Add hooks for extending vite config ([#599](https://github.com/wxt-dev/wxt/pull/599))
### 🩹 Fixes
- **content-script-ui:** Properly assign and unassign mounted value ([#598](https://github.com/wxt-dev/wxt/pull/598))
### 📖 Documentation
- Add discord server link ([#593](https://github.com/wxt-dev/wxt/pull/593))
### 🏡 Chore
- Remove unnecssary 'Omit' types ([db57c8e](https://github.com/wxt-dev/wxt/commit/db57c8e))
- **deps-dev:** Bump @aklinker1/check from 1.1.1 to 1.2.0 ([#588](https://github.com/wxt-dev/wxt/pull/588))
- **deps-dev:** Bump vue from 3.3.10 to 3.4.21 ([#589](https://github.com/wxt-dev/wxt/pull/589))
- **deps-dev:** Bump sass from 1.69.5 to 1.72.0 ([#591](https://github.com/wxt-dev/wxt/pull/591))
## v0.17.11
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.17.10...v0.17.11)
### 🩹 Fixes
- Resolve absolute paths from the public directory properly ([#583](https://github.com/wxt-dev/wxt/pull/583))
### 📖 Documentation
- Fix `zip.includeSources` example ([16fc584](https://github.com/wxt-dev/wxt/commit/16fc584))
- Add "GitHub Custom Notifier" to homepage ([#580](https://github.com/wxt-dev/wxt/pull/580))
### 🏡 Chore
- Simplify virtual module setup ([#581](https://github.com/wxt-dev/wxt/pull/581))
- Add some array utils ([#582](https://github.com/wxt-dev/wxt/pull/582))
- Extract helper function ([d3b14af](https://github.com/wxt-dev/wxt/commit/d3b14af))
### ❤️ Contributors
- Qiwei Yang ([@qiweiii](http://github.com/qiweiii))
## v0.17.10
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.17.9...v0.17.10)
+2
View File
@@ -29,6 +29,8 @@
<a href="https://wxt.dev/api/config.html" target="_blank">Configuration</a>
&bull;
<a href="https://wxt.dev/examples.html" target="_blank">Examples</a>
&bull;
<a href="https://discord.gg/ZFsZqGery9" target="_blank">Discord</a>
</p>
![Example CLI Output](./docs/assets/cli-output.png)
+1 -1
View File
@@ -1,4 +1,4 @@
import messages from 'public/_locales/en/messages.json';
import messages from '~/public/_locales/en/messages.json';
export default defineBackground({
// type: 'module',
-3
View File
@@ -12,9 +12,6 @@ export default defineConfig({
},
],
},
alias: {
public: 'src/public',
},
zip: {
downloadPackages: ['sass'],
},
@@ -21,6 +21,7 @@ const chromeExtensionIds = [
'aiakblgmlabokilgljkglggnpflljdgp', // Markdown Sticky Notes
'nomnkbngkijpffepcgbbofhcnafpkiep', // DocVersionRedirector
'ceicccfeikoipigeghddpocceifjelph', // Plex Skipper
'aelkipgppclpfimeamgmlonimflbhlgf', // GitHub Custom Notifier
];
const { data, err, isLoading } = useListExtensionDetails(chromeExtensionIds);
+4 -1
View File
@@ -146,6 +146,9 @@ export default defineConfig({
],
},
socialLinks: [{ icon: 'github', link: 'https://github.com/wxt-dev/wxt' }],
socialLinks: [
{ icon: 'discord', link: 'https://discord.gg/ZFsZqGery9' },
{ icon: 'github', link: 'https://github.com/wxt-dev/wxt' },
],
},
});
+16 -3
View File
@@ -9,16 +9,21 @@ const hooks: WxtHooks = {
'build:manifestGenerated': vi.fn(),
'entrypoints:resolved': vi.fn(),
'entrypoints:grouped': vi.fn(),
'vite:build:extendConfig': vi.fn(),
'vite:devServer:extendConfig': vi.fn(),
};
function expectHooksToBeCalled(called: Record<keyof WxtHooks, boolean>) {
function expectHooksToBeCalled(
called: Record<keyof WxtHooks, boolean | number>,
) {
Object.keys(hooks).forEach((key) => {
const hookName = key as keyof WxtHooks;
const times = called[hookName] ? 1 : 0;
const value = called[hookName];
const times = typeof value === 'number' ? value : value ? 1 : 0;
expect(
hooks[hookName],
`Expected "${hookName}" to be called ${times} time(s)`,
).toBeCalledTimes(called[hookName] ? 1 : 0);
).toBeCalledTimes(times);
});
}
@@ -40,6 +45,8 @@ describe('Hooks', () => {
'build:manifestGenerated': false,
'entrypoints:grouped': false,
'entrypoints:resolved': true,
'vite:build:extendConfig': false,
'vite:devServer:extendConfig': false,
});
});
@@ -56,6 +63,8 @@ describe('Hooks', () => {
'build:manifestGenerated': true,
'entrypoints:grouped': true,
'entrypoints:resolved': true,
'vite:build:extendConfig': 1,
'vite:devServer:extendConfig': false,
});
});
@@ -72,6 +81,8 @@ describe('Hooks', () => {
'build:manifestGenerated': true,
'entrypoints:grouped': true,
'entrypoints:resolved': true,
'vite:build:extendConfig': 1,
'vite:devServer:extendConfig': false,
});
});
@@ -94,6 +105,8 @@ describe('Hooks', () => {
'build:manifestGenerated': true,
'entrypoints:grouped': true,
'entrypoints:resolved': true,
'vite:build:extendConfig': 2,
'vite:devServer:extendConfig': 1,
});
});
});
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "wxt",
"type": "module",
"version": "0.17.10",
"version": "0.17.12",
"description": "Next gen framework for developing web extensions",
"engines": {
"node": ">=18",
+144 -200
View File
@@ -28,7 +28,7 @@ importers:
version: 0.4.0
c12:
specifier: ^1.5.1
version: 1.5.1
version: 1.10.0
cac:
specifier: ^6.7.14
version: 6.7.14
@@ -125,7 +125,7 @@ importers:
devDependencies:
'@aklinker1/check':
specifier: ^1.1.1
version: 1.1.1(typescript@5.3.3)
version: 1.2.0(typescript@5.3.3)
'@faker-js/faker':
specifier: ^8.3.1
version: 8.3.1
@@ -212,7 +212,7 @@ importers:
version: 1.0.2(vite@5.1.3)
vue:
specifier: ^3.3.10
version: 3.3.10(typescript@5.3.3)
version: 3.4.21(typescript@5.3.3)
demo:
dependencies:
@@ -241,8 +241,8 @@ importers:
packages:
/@aklinker1/check@1.1.1(typescript@5.3.3):
resolution: {integrity: sha512-P6+vKw9Qm4y3newTcKt4kfxr4cCZgjaoDpCddpqutTZm6bKTgpmtUQNUzWbmpT/V41+86wNAko/jh58Klmn/5A==}
/@aklinker1/check@1.2.0(typescript@5.3.3):
resolution: {integrity: sha512-8GEoPcifx5f7Yx2t1KCGEQyrLOOb2ErP3cG+H1+TwWBYjkT2HV9ZHCLYy0Ws8CET8VeUcKDvLKmn2DW3HBt+FA==}
hasBin: true
peerDependencies:
typescript: ^5.0.0
@@ -446,8 +446,8 @@ packages:
js-tokens: 4.0.0
dev: false
/@babel/parser@7.23.6:
resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==}
/@babel/parser@7.24.1:
resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
@@ -1221,7 +1221,7 @@ packages:
'@types/node': 20.10.3
optional: true
/@vitejs/plugin-vue@5.0.2(vite@5.1.3)(vue@3.4.3):
/@vitejs/plugin-vue@5.0.2(vite@5.1.3)(vue@3.4.21):
resolution: {integrity: sha512-kEjJHrLb5ePBvjD0SPZwJlw1QTRcjjCA9sB5VyfonoXVBxTS7TMnqL6EkLt1Eu61RDeiuZ/WN9Hf6PxXhPI2uA==}
engines: {node: ^18.0.0 || >=20.0.0}
peerDependencies:
@@ -1229,7 +1229,7 @@ packages:
vue: ^3.2.25
dependencies:
vite: 5.1.3(@types/node@20.10.3)(sass@1.69.5)
vue: 3.4.3(typescript@5.3.3)
vue: 3.4.21(typescript@5.3.3)
dev: true
/@vitest/coverage-v8@1.2.2(vitest@1.2.2):
@@ -1267,13 +1267,13 @@ packages:
dependencies:
'@vitest/utils': 1.2.2
p-limit: 5.0.0
pathe: 1.1.1
pathe: 1.1.2
/@vitest/snapshot@1.2.2:
resolution: {integrity: sha512-SmGY4saEw1+bwE1th6S/cZmPxz/Q4JWsl7LvbQIky2tKE35US4gd0Mjzqfr84/4OD0tikGWaWdMja/nWL5NIPA==}
dependencies:
magic-string: 0.30.5
pathe: 1.1.1
magic-string: 0.30.8
pathe: 1.1.2
pretty-format: 29.7.0
/@vitest/spy@1.2.2:
@@ -1289,179 +1289,96 @@ packages:
loupe: 2.3.7
pretty-format: 29.7.0
/@vue/compiler-core@3.3.10:
resolution: {integrity: sha512-doe0hODR1+i1menPkRzJ5MNR6G+9uiZHIknK3Zn5OcIztu6GGw7u0XUzf3AgB8h/dfsZC9eouzoLo3c3+N/cVA==}
/@vue/compiler-core@3.4.21:
resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==}
dependencies:
'@babel/parser': 7.23.6
'@vue/shared': 3.3.10
estree-walker: 2.0.2
source-map-js: 1.0.2
dev: true
/@vue/compiler-core@3.4.3:
resolution: {integrity: sha512-u8jzgFg0EDtSrb/hG53Wwh1bAOQFtc1ZCegBpA/glyvTlgHl+tq13o1zvRfLbegYUw/E4mSTGOiCnAJ9SJ+lsg==}
dependencies:
'@babel/parser': 7.23.6
'@vue/shared': 3.4.3
'@babel/parser': 7.24.1
'@vue/shared': 3.4.21
entities: 4.5.0
estree-walker: 2.0.2
source-map-js: 1.0.2
dev: true
/@vue/compiler-dom@3.3.10:
resolution: {integrity: sha512-NCrqF5fm10GXZIK0GrEAauBqdy+F2LZRt3yNHzrYjpYBuRssQbuPLtSnSNjyR9luHKkWSH8we5LMB3g+4z2HvA==}
/@vue/compiler-dom@3.4.21:
resolution: {integrity: sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==}
dependencies:
'@vue/compiler-core': 3.3.10
'@vue/shared': 3.3.10
'@vue/compiler-core': 3.4.21
'@vue/shared': 3.4.21
dev: true
/@vue/compiler-dom@3.4.3:
resolution: {integrity: sha512-oGF1E9/htI6JWj/lTJgr6UgxNCtNHbM6xKVreBWeZL9QhRGABRVoWGAzxmtBfSOd+w0Zi5BY0Es/tlJrN6WgEg==}
/@vue/compiler-sfc@3.4.21:
resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==}
dependencies:
'@vue/compiler-core': 3.4.3
'@vue/shared': 3.4.3
dev: true
/@vue/compiler-sfc@3.3.10:
resolution: {integrity: sha512-xpcTe7Rw7QefOTRFFTlcfzozccvjM40dT45JtrE3onGm/jBLZ0JhpKu3jkV7rbDFLeeagR/5RlJ2Y9SvyS0lAg==}
dependencies:
'@babel/parser': 7.23.6
'@vue/compiler-core': 3.3.10
'@vue/compiler-dom': 3.3.10
'@vue/compiler-ssr': 3.3.10
'@vue/reactivity-transform': 3.3.10
'@vue/shared': 3.3.10
'@babel/parser': 7.24.1
'@vue/compiler-core': 3.4.21
'@vue/compiler-dom': 3.4.21
'@vue/compiler-ssr': 3.4.21
'@vue/shared': 3.4.21
estree-walker: 2.0.2
magic-string: 0.30.5
postcss: 8.4.32
source-map-js: 1.0.2
dev: true
/@vue/compiler-sfc@3.4.3:
resolution: {integrity: sha512-NuJqb5is9I4uzv316VRUDYgIlPZCG8D+ARt5P4t5UDShIHKL25J3TGZAUryY/Aiy0DsY7srJnZL5ryB6DD63Zw==}
dependencies:
'@babel/parser': 7.23.6
'@vue/compiler-core': 3.4.3
'@vue/compiler-dom': 3.4.3
'@vue/compiler-ssr': 3.4.3
'@vue/shared': 3.4.3
estree-walker: 2.0.2
magic-string: 0.30.5
magic-string: 0.30.8
postcss: 8.4.35
source-map-js: 1.0.2
dev: true
/@vue/compiler-ssr@3.3.10:
resolution: {integrity: sha512-12iM4jA4GEbskwXMmPcskK5wImc2ohKm408+o9iox3tfN9qua8xL0THIZtoe9OJHnXP4eOWZpgCAAThEveNlqQ==}
/@vue/compiler-ssr@3.4.21:
resolution: {integrity: sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==}
dependencies:
'@vue/compiler-dom': 3.3.10
'@vue/shared': 3.3.10
dev: true
/@vue/compiler-ssr@3.4.3:
resolution: {integrity: sha512-wnYQtMBkeFSxgSSQbYGQeXPhQacQiog2c6AlvMldQH6DB+gSXK/0F6DVXAJfEiuBSgBhUc8dwrrG5JQcqwalsA==}
dependencies:
'@vue/compiler-dom': 3.4.3
'@vue/shared': 3.4.3
'@vue/compiler-dom': 3.4.21
'@vue/shared': 3.4.21
dev: true
/@vue/devtools-api@6.5.1:
resolution: {integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==}
dev: true
/@vue/reactivity-transform@3.3.10:
resolution: {integrity: sha512-0xBdk+CKHWT+Gev8oZ63Tc0qFfj935YZx+UAynlutnrDZ4diFCVFMWixn65HzjE3S1iJppWOo6Tt1OzASH7VEg==}
/@vue/reactivity@3.4.21:
resolution: {integrity: sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==}
dependencies:
'@babel/parser': 7.23.6
'@vue/compiler-core': 3.3.10
'@vue/shared': 3.3.10
estree-walker: 2.0.2
magic-string: 0.30.5
'@vue/shared': 3.4.21
dev: true
/@vue/reactivity@3.3.10:
resolution: {integrity: sha512-H5Z7rOY/JLO+e5a6/FEXaQ1TMuOvY4LDVgT+/+HKubEAgs9qeeZ+NhADSeEtrNQeiKLDuzeKc8v0CUFpB6Pqgw==}
/@vue/runtime-core@3.4.21:
resolution: {integrity: sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==}
dependencies:
'@vue/shared': 3.3.10
'@vue/reactivity': 3.4.21
'@vue/shared': 3.4.21
dev: true
/@vue/reactivity@3.4.3:
resolution: {integrity: sha512-q5f9HLDU+5aBKizXHAx0w4whkIANs1Muiq9R5YXm0HtorSlflqv9u/ohaMxuuhHWCji4xqpQ1eL04WvmAmGnFg==}
/@vue/runtime-dom@3.4.21:
resolution: {integrity: sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==}
dependencies:
'@vue/shared': 3.4.3
dev: true
/@vue/runtime-core@3.3.10:
resolution: {integrity: sha512-DZ0v31oTN4YHX9JEU5VW1LoIVgFovWgIVb30bWn9DG9a7oA415idcwsRNNajqTx8HQJyOaWfRKoyuP2P2TYIag==}
dependencies:
'@vue/reactivity': 3.3.10
'@vue/shared': 3.3.10
dev: true
/@vue/runtime-core@3.4.3:
resolution: {integrity: sha512-C1r6QhB1qY7D591RCSFhMULyzL9CuyrGc+3PpB0h7dU4Qqw6GNyo4BNFjHZVvsWncrUlKX3DIKg0Y7rNNr06NQ==}
dependencies:
'@vue/reactivity': 3.4.3
'@vue/shared': 3.4.3
dev: true
/@vue/runtime-dom@3.3.10:
resolution: {integrity: sha512-c/jKb3ny05KJcYk0j1m7Wbhrxq7mZYr06GhKykDMNRRR9S+/dGT8KpHuNQjv3/8U4JshfkAk6TpecPD3B21Ijw==}
dependencies:
'@vue/runtime-core': 3.3.10
'@vue/shared': 3.3.10
'@vue/runtime-core': 3.4.21
'@vue/shared': 3.4.21
csstype: 3.1.3
dev: true
/@vue/runtime-dom@3.4.3:
resolution: {integrity: sha512-wrsprg7An5Ec+EhPngWdPuzkp0BEUxAKaQtN9dPU/iZctPyD9aaXmVtehPJerdQxQale6gEnhpnfywNw3zOv2A==}
dependencies:
'@vue/runtime-core': 3.4.3
'@vue/shared': 3.4.3
csstype: 3.1.3
dev: true
/@vue/server-renderer@3.3.10(vue@3.3.10):
resolution: {integrity: sha512-0i6ww3sBV3SKlF3YTjSVqKQ74xialMbjVYGy7cOTi7Imd8ediE7t72SK3qnvhrTAhOvlQhq6Bk6nFPdXxe0sAg==}
/@vue/server-renderer@3.4.21(vue@3.4.21):
resolution: {integrity: sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==}
peerDependencies:
vue: 3.3.10
vue: 3.4.21
dependencies:
'@vue/compiler-ssr': 3.3.10
'@vue/shared': 3.3.10
vue: 3.3.10(typescript@5.3.3)
'@vue/compiler-ssr': 3.4.21
'@vue/shared': 3.4.21
vue: 3.4.21(typescript@5.3.3)
dev: true
/@vue/server-renderer@3.4.3(vue@3.4.3):
resolution: {integrity: sha512-BUxt8oVGMKKsqSkM1uU3d3Houyfy4WAc2SpSQRebNd+XJGATVkW/rO129jkyL+kpB/2VRKzE63zwf5RtJ3XuZw==}
peerDependencies:
vue: 3.4.3
dependencies:
'@vue/compiler-ssr': 3.4.3
'@vue/shared': 3.4.3
vue: 3.4.3(typescript@5.3.3)
/@vue/shared@3.4.21:
resolution: {integrity: sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==}
dev: true
/@vue/shared@3.3.10:
resolution: {integrity: sha512-2y3Y2J1a3RhFa0WisHvACJR2ncvWiVHcP8t0Inxo+NKz+8RKO4ZV8eZgCxRgQoA6ITfV12L4E6POOL9HOU5nqw==}
dev: true
/@vue/shared@3.4.3:
resolution: {integrity: sha512-rIwlkkP1n4uKrRzivAKPZIEkHiuwY5mmhMJ2nZKCBLz8lTUlE73rQh4n1OnnMurXt1vcUNyH4ZPfdh8QweTjpQ==}
dev: true
/@vueuse/core@10.7.1(vue@3.4.3):
/@vueuse/core@10.7.1(vue@3.4.21):
resolution: {integrity: sha512-74mWHlaesJSWGp1ihg76vAnfVq9NTv1YT0SYhAQ6zwFNdBkkP+CKKJmVOEHcdSnLXCXYiL5e7MaewblfiYLP7g==}
dependencies:
'@types/web-bluetooth': 0.0.20
'@vueuse/metadata': 10.7.1
'@vueuse/shared': 10.7.1(vue@3.4.3)
vue-demi: 0.14.6(vue@3.4.3)
'@vueuse/shared': 10.7.1(vue@3.4.21)
vue-demi: 0.14.6(vue@3.4.21)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
dev: true
/@vueuse/integrations@10.7.1(focus-trap@7.5.4)(vue@3.4.3):
/@vueuse/integrations@10.7.1(focus-trap@7.5.4)(vue@3.4.21):
resolution: {integrity: sha512-cKo5LEeKVHdBRBtMTOrDPdR0YNtrmN9IBfdcnY2P3m5LHVrsD0xiHUtAH1WKjHQRIErZG6rJUa6GA4tWZt89Og==}
peerDependencies:
async-validator: '*'
@@ -1502,10 +1419,10 @@ packages:
universal-cookie:
optional: true
dependencies:
'@vueuse/core': 10.7.1(vue@3.4.3)
'@vueuse/shared': 10.7.1(vue@3.4.3)
'@vueuse/core': 10.7.1(vue@3.4.21)
'@vueuse/shared': 10.7.1(vue@3.4.21)
focus-trap: 7.5.4
vue-demi: 0.14.6(vue@3.4.3)
vue-demi: 0.14.6(vue@3.4.21)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
@@ -1515,10 +1432,10 @@ packages:
resolution: {integrity: sha512-jX8MbX5UX067DYVsbtrmKn6eG6KMcXxLRLlurGkZku5ZYT3vxgBjui2zajvUZ18QLIjrgBkFRsu7CqTAg18QFw==}
dev: true
/@vueuse/shared@10.7.1(vue@3.4.3):
/@vueuse/shared@10.7.1(vue@3.4.21):
resolution: {integrity: sha512-v0jbRR31LSgRY/C5i5X279A/WQjD6/JsMzGa+eqt658oJ75IvQXAeONmwvEMrvJQKnRElq/frzBR7fhmWY5uLw==}
dependencies:
vue-demi: 0.14.6(vue@3.4.3)
vue-demi: 0.14.6(vue@3.4.21)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
@@ -1542,8 +1459,8 @@ packages:
resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
engines: {node: '>=0.4.0'}
/acorn@8.11.2:
resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==}
/acorn@8.11.3:
resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==}
engines: {node: '>=0.4.0'}
hasBin: true
@@ -1800,22 +1717,21 @@ packages:
safe-json-stringify: 1.2.0
dev: false
/c12@1.5.1:
resolution: {integrity: sha512-BWZRJgDEveT8uI+cliCwvYSSSSvb4xKoiiu5S0jaDbKBopQLQF7E+bq9xKk1pTcG+mUa3yXuFO7bD9d8Lr9Xxg==}
/c12@1.10.0:
resolution: {integrity: sha512-0SsG7UDhoRWcuSvKWHaXmu5uNjDCDN3nkQLRL4Q42IlFy+ze58FcCoI3uPwINXinkz7ZinbhEgyzYFw9u9ZV8g==}
dependencies:
chokidar: 3.6.0
confbox: 0.1.3
defu: 6.1.4
dotenv: 16.3.1
giget: 1.1.3
dotenv: 16.4.5
giget: 1.2.3
jiti: 1.21.0
mlly: 1.4.2
mlly: 1.6.1
ohash: 1.1.3
pathe: 1.1.1
pathe: 1.1.2
perfect-debounce: 1.0.0
pkg-types: 1.0.3
rc9: 2.1.1
transitivePeerDependencies:
- supports-color
dev: false
/cac@6.7.14:
@@ -1929,7 +1845,6 @@ packages:
/ci-info@4.0.0:
resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==}
engines: {node: '>=8'}
dev: true
/citty@0.1.6:
resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==}
@@ -2051,6 +1966,10 @@ packages:
typedarray: 0.0.6
dev: false
/confbox@0.1.3:
resolution: {integrity: sha512-eH3ZxAihl1PhKfpr4VfEN6/vUd87fmgb6JkldHgg/YR6aEBhW63qUDgzP2Y6WM0UumdsYp5H3kibalXAdHfbgg==}
dev: false
/config-chain@1.1.13:
resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
dependencies:
@@ -2301,6 +2220,11 @@ packages:
engines: {node: '>=12'}
dev: false
/dotenv@16.4.5:
resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
engines: {node: '>=12'}
dev: false
/dtrace-provider@0.8.8:
resolution: {integrity: sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==}
engines: {node: '>=0.10'}
@@ -2764,6 +2688,20 @@ packages:
- supports-color
dev: false
/giget@1.2.3:
resolution: {integrity: sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==}
hasBin: true
dependencies:
citty: 0.1.6
consola: 3.2.3
defu: 6.1.4
node-fetch-native: 1.6.4
nypm: 0.3.8
ohash: 1.1.3
pathe: 1.1.2
tar: 6.2.0
dev: false
/glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -3530,7 +3468,7 @@ packages:
resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
engines: {node: '>=14'}
dependencies:
mlly: 1.4.2
mlly: 1.6.1
pkg-types: 1.0.3
/lodash.camelcase@4.3.0:
@@ -3603,10 +3541,16 @@ packages:
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
/magic-string@0.30.8:
resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
/magicast@0.3.3:
resolution: {integrity: sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==}
dependencies:
'@babel/parser': 7.23.6
'@babel/parser': 7.24.1
'@babel/types': 7.23.9
source-map-js: 1.0.2
dev: true
@@ -3737,7 +3681,16 @@ packages:
/mlly@1.4.2:
resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==}
dependencies:
acorn: 8.11.2
acorn: 8.11.3
pathe: 1.1.2
pkg-types: 1.0.3
ufo: 1.4.0
dev: false
/mlly@1.6.1:
resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==}
dependencies:
acorn: 8.11.3
pathe: 1.1.2
pkg-types: 1.0.3
ufo: 1.4.0
@@ -3822,6 +3775,10 @@ packages:
resolution: {integrity: sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w==}
dev: false
/node-fetch-native@1.6.4:
resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==}
dev: false
/node-forge@1.3.1:
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
engines: {node: '>= 6.13.0'}
@@ -3924,6 +3881,18 @@ packages:
ufo: 1.4.0
dev: false
/nypm@0.3.8:
resolution: {integrity: sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og==}
engines: {node: ^14.16.0 || >=16.10.0}
hasBin: true
dependencies:
citty: 0.1.6
consola: 3.2.3
execa: 8.0.1
pathe: 1.1.2
ufo: 1.4.0
dev: false
/object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
@@ -3951,7 +3920,7 @@ packages:
resolution: {integrity: sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg==}
dependencies:
destr: 2.0.2
node-fetch-native: 1.4.1
node-fetch-native: 1.6.4
ufo: 1.4.0
dev: false
@@ -4185,7 +4154,7 @@ packages:
resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
dependencies:
jsonc-parser: 3.2.0
mlly: 1.4.2
mlly: 1.6.1
pathe: 1.1.2
/postcss-load-config@4.0.1:
@@ -4204,15 +4173,6 @@ packages:
yaml: 2.3.4
dev: true
/postcss@8.4.32:
resolution: {integrity: sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
nanoid: 3.3.7
picocolors: 1.0.0
source-map-js: 1.0.2
dev: true
/postcss@8.4.35:
resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==}
engines: {node: ^10 || ^12 || >=14}
@@ -4908,7 +4868,7 @@ packages:
/strip-literal@1.3.0:
resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==}
dependencies:
acorn: 8.11.2
acorn: 8.11.3
/sucrase@3.32.0:
resolution: {integrity: sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==}
@@ -5221,7 +5181,7 @@ packages:
/unplugin@1.5.0:
resolution: {integrity: sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==}
dependencies:
acorn: 8.11.2
acorn: 8.11.3
chokidar: 3.6.0
webpack-sources: 3.2.3
webpack-virtual-modules: 0.5.0
@@ -5284,7 +5244,7 @@ packages:
dependencies:
cac: 6.7.14
debug: 4.3.4
pathe: 1.1.1
pathe: 1.1.2
picocolors: 1.0.0
vite: 5.1.3(@types/node@20.10.3)(sass@1.69.5)
transitivePeerDependencies:
@@ -5348,10 +5308,10 @@ packages:
'@docsearch/css': 3.5.2
'@docsearch/js': 3.5.2
'@types/markdown-it': 13.0.7
'@vitejs/plugin-vue': 5.0.2(vite@5.1.3)(vue@3.4.3)
'@vitejs/plugin-vue': 5.0.2(vite@5.1.3)(vue@3.4.21)
'@vue/devtools-api': 6.5.1
'@vueuse/core': 10.7.1(vue@3.4.3)
'@vueuse/integrations': 10.7.1(focus-trap@7.5.4)(vue@3.4.3)
'@vueuse/core': 10.7.1(vue@3.4.21)
'@vueuse/integrations': 10.7.1(focus-trap@7.5.4)(vue@3.4.21)
focus-trap: 7.5.4
mark.js: 8.11.1
minisearch: 6.3.0
@@ -5360,7 +5320,7 @@ packages:
shikiji-core: 0.9.16
shikiji-transformers: 0.9.16
vite: 5.1.3(@types/node@20.10.3)(sass@1.69.5)
vue: 3.4.3(typescript@5.3.3)
vue: 3.4.21(typescript@5.3.3)
transitivePeerDependencies:
- '@algolia/client-search'
- '@types/node'
@@ -5473,7 +5433,7 @@ packages:
resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==}
dev: true
/vue-demi@0.14.6(vue@3.4.3):
/vue-demi@0.14.6(vue@3.4.21):
resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
engines: {node: '>=12'}
hasBin: true
@@ -5485,38 +5445,22 @@ packages:
'@vue/composition-api':
optional: true
dependencies:
vue: 3.4.3(typescript@5.3.3)
vue: 3.4.21(typescript@5.3.3)
dev: true
/vue@3.3.10(typescript@5.3.3):
resolution: {integrity: sha512-zg6SIXZdTBwiqCw/1p+m04VyHjLfwtjwz8N57sPaBhEex31ND0RYECVOC1YrRwMRmxFf5T1dabl6SGUbMKKuVw==}
/vue@3.4.21(typescript@5.3.3):
resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@vue/compiler-dom': 3.3.10
'@vue/compiler-sfc': 3.3.10
'@vue/runtime-dom': 3.3.10
'@vue/server-renderer': 3.3.10(vue@3.3.10)
'@vue/shared': 3.3.10
typescript: 5.3.3
dev: true
/vue@3.4.3(typescript@5.3.3):
resolution: {integrity: sha512-GjN+culMAGv/mUbkIv8zMKItno8npcj5gWlXkSxf1SPTQf8eJ4A+YfHIvQFyL1IfuJcMl3soA7SmN1fRxbf/wA==}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@vue/compiler-dom': 3.4.3
'@vue/compiler-sfc': 3.4.3
'@vue/runtime-dom': 3.4.3
'@vue/server-renderer': 3.4.3(vue@3.4.3)
'@vue/shared': 3.4.3
'@vue/compiler-dom': 3.4.21
'@vue/compiler-sfc': 3.4.21
'@vue/runtime-dom': 3.4.21
'@vue/server-renderer': 3.4.21(vue@3.4.21)
'@vue/shared': 3.4.21
typescript: 5.3.3
dev: true
+12 -17
View File
@@ -8,6 +8,10 @@ import { consola } from 'consola';
import pMap from 'p-map';
import os from 'node:os';
import path from 'node:path';
import {
virtualModuleNames,
virtualEntrypointModuleNames,
} from '~/core/utils/virtual-modules';
const spinnerText = 'Building WXT';
const spinner = ora(spinnerText).start();
@@ -20,12 +24,7 @@ const preset = {
dts: true,
silent: true,
sourcemap: false,
external: [
'virtual:user-unlisted-script',
'virtual:user-content-script-isolated-world',
'virtual:user-content-script-main-world',
'virtual:user-background',
],
external: virtualEntrypointModuleNames.map((name) => `virtual:user-${name}`),
} satisfies tsup.Options;
function spinnerPMap(configs: tsup.Options[]) {
@@ -74,17 +73,13 @@ const config: tsup.Options[] = [
},
{
...preset,
entry: {
'virtual/background-entrypoint': 'src/virtual/background-entrypoint.ts',
'virtual/content-script-isolated-world-entrypoint':
'src/virtual/content-script-isolated-world-entrypoint.ts',
'virtual/content-script-main-world-entrypoint':
'src/virtual/content-script-main-world-entrypoint.ts',
'virtual/mock-browser': 'src/virtual/mock-browser.ts',
'virtual/reload-html': 'src/virtual/reload-html.ts',
'virtual/unlisted-script-entrypoint':
'src/virtual/unlisted-script-entrypoint.ts',
},
entry: virtualModuleNames.reduce<Record<string, string>>(
(acc, moduleName) => {
acc[`virtual/${moduleName}`] = `src/virtual/${moduleName}.ts`;
return acc;
},
{},
),
format: ['esm'],
splitting: false,
dts: false,
+3 -2
View File
@@ -1,5 +1,6 @@
import { CAC, Command } from 'cac';
import consola, { LogLevels } from 'consola';
import { filterTruthy, toArray } from '~/core/utils/arrays';
import { printHeader } from '~/core/utils/log';
import { formatDuration } from '~/core/utils/time';
import { ValidationError } from '~/core/utils/validation';
@@ -56,8 +57,8 @@ export function getArrayFromFlags<T>(
flags: any,
name: string,
): T[] | undefined {
const array = [flags[name]].flat() as Array<T | undefined>;
const result = array.filter((item) => item != null) as T[];
const array = toArray<T | undefined>(flags[name]);
const result = filterTruthy(array);
return result.length ? result : undefined;
}
@@ -404,4 +404,62 @@ describe('Content Script UIs', () => {
});
});
});
describe('mounted value', () => {
describe('integrated', () => {
it('should set the mounted value based on the onMounted return value', () => {
const expected = Symbol();
const ui = createIntegratedUi(new ContentScriptContext('test'), {
position: 'inline',
onMount: () => expected,
});
expect(ui.mounted).toBeUndefined();
ui.mount();
expect(ui.mounted).toBe(expected);
ui.remove();
expect(ui.mounted).toBeUndefined();
});
});
describe('iframe', () => {
it('should set the mounted value based on the onMounted return value', async () => {
const expected = Symbol();
const ui = createIframeUi(new ContentScriptContext('test'), {
page: '',
position: 'inline',
onMount: () => expected,
});
expect(ui.mounted).toBeUndefined();
ui.mount();
expect(ui.mounted).toBe(expected);
ui.remove();
expect(ui.mounted).toBeUndefined();
});
});
describe('shadow-root', () => {
it('should set the mounted value based on the onMounted return value', async () => {
const expected = Symbol();
const ui = await createShadowRootUi(new ContentScriptContext('test'), {
name: 'test',
position: 'inline',
onMount: () => expected,
});
expect(ui.mounted).toBeUndefined();
ui.mount();
expect(ui.mounted).toBe(expected);
ui.remove();
expect(ui.mounted).toBeUndefined();
});
});
});
});
+14 -4
View File
@@ -35,12 +35,15 @@ export function createIntegratedUi<TMounted>(
const remove = () => {
options.onRemove?.(mounted);
wrapper.remove();
mounted = undefined;
};
ctx.onInvalidated(remove);
return {
mounted,
get mounted() {
return mounted;
},
wrapper,
mount,
remove,
@@ -71,12 +74,15 @@ export function createIframeUi<TMounted>(
const remove = () => {
options.onRemove?.(mounted);
wrapper.remove();
mounted = undefined;
};
ctx.onInvalidated(remove);
return {
mounted,
get mounted() {
return mounted;
},
iframe,
wrapper,
mount,
@@ -116,7 +122,7 @@ export async function createShadowRootUi<TMounted>(
});
shadowHost.setAttribute('data-wxt-shadow-root', '');
let mounted: TMounted;
let mounted: TMounted | undefined;
const mount = () => {
// Add shadow root element to DOM
@@ -134,6 +140,8 @@ export async function createShadowRootUi<TMounted>(
// Remove children from uiContainer
while (uiContainer.lastChild)
uiContainer.removeChild(uiContainer.lastChild);
// Clear mounted value
mounted = undefined;
};
ctx.onInvalidated(remove);
@@ -144,7 +152,9 @@ export async function createShadowRootUi<TMounted>(
uiContainer,
mount,
remove,
mounted: mounted!,
get mounted() {
return mounted;
},
};
}
+28 -12
View File
@@ -3,19 +3,26 @@ import {
BuildStepOutput,
Entrypoint,
ResolvedConfig,
VirtualEntrypointType,
WxtBuilder,
WxtBuilderServer,
WxtDevServer,
WxtHooks,
} from '~/types';
import * as wxtPlugins from './plugins';
import {
getEntrypointBundlePath,
isHtmlEntrypoint,
} from '~/core/utils/entrypoints';
import {
VirtualEntrypointType,
VirtualModuleId,
} from '~/core/utils/virtual-modules';
import { Hookable } from 'hookable';
import { toArray } from '~/core/utils/arrays';
export async function createViteBuilder(
wxtConfig: ResolvedConfig,
hooks: Hookable<WxtHooks>,
server?: WxtDevServer,
): Promise<WxtBuilder> {
const vite = await import('vite');
@@ -24,7 +31,9 @@ export async function createViteBuilder(
* Returns the base vite config shared by all builds based on the inline and user config.
*/
const getBaseConfig = async () => {
const config: vite.InlineConfig = await wxtConfig.vite(wxtConfig.env);
const config: vite.InlineConfig = await wxtConfig.vite({
...wxtConfig.env,
});
config.root = wxtConfig.root;
config.configFile = false;
@@ -32,6 +41,8 @@ export async function createViteBuilder(
config.mode = wxtConfig.mode;
config.build ??= {};
config.publicDir = wxtConfig.publicDir;
config.build.copyPublicDir = false;
config.build.outDir = wxtConfig.outDir;
config.build.emptyOutDir = false;
// Disable minification for the dev command
@@ -48,10 +59,7 @@ export async function createViteBuilder(
wxtPlugins.download(wxtConfig),
wxtPlugins.devHtmlPrerender(wxtConfig, server),
wxtPlugins.unimport(wxtConfig),
wxtPlugins.virtualEntrypoint('background', wxtConfig),
wxtPlugins.virtualEntrypoint('content-script-isolated-world', wxtConfig),
wxtPlugins.virtualEntrypoint('content-script-main-world', wxtConfig),
wxtPlugins.virtualEntrypoint('unlisted-script', wxtConfig),
wxtPlugins.resolveVirtualModules(wxtConfig),
wxtPlugins.devServerGlobals(wxtConfig, server),
wxtPlugins.tsconfigPaths(wxtConfig),
wxtPlugins.noopBackground(),
@@ -196,6 +204,11 @@ export async function createViteBuilder(
else entryConfig = getLibModeConfig(group);
const buildConfig = vite.mergeConfig(await getBaseConfig(), entryConfig);
await hooks.callHook(
'vite:build:extendConfig',
toArray(group),
buildConfig,
);
const result = await vite.build(buildConfig);
return {
entrypoints: group,
@@ -212,9 +225,9 @@ export async function createViteBuilder(
},
};
const baseConfig = await getBaseConfig();
const viteServer = await vite.createServer(
vite.mergeConfig(baseConfig, serverConfig),
);
const finalConfig = vite.mergeConfig(baseConfig, serverConfig);
await hooks.callHook('vite:devServer:extendConfig', finalConfig);
const viteServer = await vite.createServer(finalConfig);
const server: WxtBuilderServer = {
async listen() {
@@ -268,7 +281,10 @@ function getRollupEntry(entrypoint: Entrypoint): string {
: 'content-script-isolated-world';
break;
}
return virtualEntrypointType
? `virtual:wxt-${virtualEntrypointType}?${entrypoint.inputPath}`
: entrypoint.inputPath;
if (virtualEntrypointType) {
const moduleId: VirtualModuleId = `virtual:wxt-${virtualEntrypointType}-entrypoint`;
return `${moduleId}?${entrypoint.inputPath}`;
}
return entrypoint.inputPath;
}
@@ -5,9 +5,7 @@ import path from 'node:path';
let increment = 0;
export function bundleAnalysis(
config: Omit<ResolvedConfig, 'builder'>,
): vite.Plugin {
export function bundleAnalysis(config: ResolvedConfig): vite.Plugin {
return visualizer({
template: 'raw-data',
filename: path.resolve(
@@ -14,7 +14,7 @@ import { getEntrypointBundlePath } from '~/core/utils/entrypoints';
*/
export function cssEntrypoints(
entrypoint: Entrypoint,
config: Omit<ResolvedConfig, 'builder'>,
config: ResolvedConfig,
): vite.Plugin {
return {
name: 'wxt:css-entrypoint',
@@ -12,7 +12,7 @@ let reactRefreshPreamble = '';
* Pre-renders the HTML entrypoints when building the extension to connect to the dev server.
*/
export function devHtmlPrerender(
config: Omit<ResolvedConfig, 'builder'>,
config: ResolvedConfig,
server: WxtDevServer | undefined,
): vite.PluginOption {
const htmlReloadId = '@wxt/reload-html';
@@ -133,7 +133,7 @@ export function devHtmlPrerender(
}
export function pointToDevServer(
config: Omit<ResolvedConfig, 'builder'>,
config: ResolvedConfig,
server: WxtDevServer,
id: string,
document: Document,
@@ -5,7 +5,7 @@ import { ResolvedConfig, WxtDevServer } from '~/types';
* Defines global constants about the dev server. Helps scripts connect to the server's web socket.
*/
export function devServerGlobals(
config: Omit<ResolvedConfig, 'builder'>,
config: ResolvedConfig,
server: WxtDevServer | undefined,
): Plugin {
return {
+1 -1
View File
@@ -9,7 +9,7 @@ import { fetchCached } from '~/core/utils/network';
* @example
* import "url:https://google-tagmanager.com/gtag?id=XYZ";
*/
export function download(config: Omit<ResolvedConfig, 'builder'>): Plugin {
export function download(config: ResolvedConfig): Plugin {
return {
name: 'wxt:download',
resolveId(id) {
@@ -6,9 +6,7 @@ import type * as vite from 'vite';
* `webextension-polyfill` module to a virtual module and exporting the `chrome` global from the
* virtual module.
*/
export function excludeBrowserPolyfill(
config: Omit<ResolvedConfig, 'builder'>,
): vite.Plugin {
export function excludeBrowserPolyfill(config: ResolvedConfig): vite.Plugin {
const virtualId = 'virtual:wxt-webextension-polyfill-disabled';
return {
+1 -3
View File
@@ -2,9 +2,7 @@ import type * as vite from 'vite';
import { ResolvedConfig } from '~/types';
import { getGlobals } from '~/core/utils/globals';
export function globals(
config: Omit<ResolvedConfig, 'builder'>,
): vite.PluginOption {
export function globals(config: ResolvedConfig): vite.PluginOption {
return {
name: 'wxt:globals',
config() {
+1 -1
View File
@@ -3,7 +3,7 @@ export * from './devServerGlobals';
export * from './download';
export * from './multipageMove';
export * from './unimport';
export * from './virtualEntrypoint';
export * from './resolveVirtualModules';
export * from './tsconfigPaths';
export * from './noopBackground';
export * from './cssEntrypoints';
@@ -20,7 +20,7 @@ import { normalizePath } from '~/core/utils/paths';
*/
export function multipageMove(
entrypoints: Entrypoint[],
config: Omit<ResolvedConfig, 'builder'>,
config: ResolvedConfig,
): vite.Plugin {
return {
name: 'wxt:multipage-move',
@@ -0,0 +1,41 @@
import { Plugin } from 'vite';
import { ResolvedConfig } from '~/types';
import { normalizePath } from '~/core/utils/paths';
import {
VirtualModuleId,
virtualModuleNames,
} from '~/core/utils/virtual-modules';
import fs from 'fs-extra';
import { resolve } from 'path';
/**
* Resolve all the virtual modules to the `node_modules/wxt/dist/virtual` directory.
*/
export function resolveVirtualModules(config: ResolvedConfig): Plugin[] {
return virtualModuleNames.map((name) => {
const virtualId: `${VirtualModuleId}?` = `virtual:wxt-${name}?`;
const resolvedVirtualId = '\0' + virtualId;
return {
name: `wxt:resolve-virtual-${name}`,
resolveId(id) {
// Id doesn't start with prefix, it looks like this:
// /path/to/project/virtual:wxt-background?/path/to/project/entrypoints/background.ts
const index = id.indexOf(virtualId);
if (index === -1) return;
const inputPath = normalizePath(id.substring(index + virtualId.length));
return resolvedVirtualId + inputPath;
},
async load(id) {
if (!id.startsWith(resolvedVirtualId)) return;
const inputPath = id.replace(resolvedVirtualId, '');
const template = await fs.readFile(
resolve(config.wxtModuleDir, `dist/virtual/${name}.js`),
'utf-8',
);
return template.replace(`virtual:user-${name}`, inputPath);
},
};
});
}
@@ -1,9 +1,7 @@
import { ResolvedConfig } from '~/types';
import type * as vite from 'vite';
export function tsconfigPaths(
config: Omit<ResolvedConfig, 'builder'>,
): vite.Plugin {
export function tsconfigPaths(config: ResolvedConfig): vite.Plugin {
return {
name: 'wxt:aliases',
async config() {
+1 -3
View File
@@ -15,9 +15,7 @@ const ENABLED_EXTENSIONS = new Set([
/**
* Inject any global imports defined by unimport
*/
export function unimport(
config: Omit<ResolvedConfig, 'builder'>,
): vite.PluginOption {
export function unimport(config: ResolvedConfig): vite.PluginOption {
const options = config.imports;
if (options === false) return [];
@@ -1,39 +0,0 @@
import { Plugin } from 'vite';
import { ResolvedConfig, VirtualEntrypointType } from '~/types';
import fs from 'fs-extra';
import { resolve } from 'path';
import { normalizePath } from '~/core/utils/paths';
/**
* Wraps a user's entrypoint with a vitual version with additional logic.
*/
export function virtualEntrypoint(
type: VirtualEntrypointType,
config: Omit<ResolvedConfig, 'builder'>,
): Plugin {
const virtualId = `virtual:wxt-${type}?`;
const resolvedVirtualId = `\0${virtualId}`;
return {
name: `wxt:virtual-entrypoint`,
resolveId(id) {
// Id doesn't start with prefix, it looks like this:
// /path/to/project/virtual:background?/path/to/project/entrypoints/background.ts
const index = id.indexOf(virtualId);
if (index === -1) return;
const inputPath = normalizePath(id.substring(index + virtualId.length));
return resolvedVirtualId + inputPath;
},
async load(id) {
if (!id.startsWith(resolvedVirtualId)) return;
const inputPath = id.replace(resolvedVirtualId, '');
const template = await fs.readFile(
resolve(config.wxtModuleDir, `dist/virtual/${type}-entrypoint.js`),
'utf-8',
);
return template.replace(`virtual:user-${type}`, inputPath);
},
};
}
@@ -16,7 +16,7 @@ import { ResolvedConfig } from '~/types';
* `npm list` and inline them automatically.
*/
export function webextensionPolyfillMock(
config: Omit<ResolvedConfig, 'builder'>,
config: ResolvedConfig,
): vite.PluginOption {
return {
name: 'wxt:testing-inline-deps',
+5 -2
View File
@@ -26,7 +26,10 @@ import pc from 'picocolors';
import { relative } from 'node:path';
import { registerWxt, wxt } from './wxt';
import { unnormalizePath } from './utils/paths';
import { mapWxtOptionsToRegisteredContentScript } from './utils/content-scripts';
import {
getContentScriptJs,
mapWxtOptionsToRegisteredContentScript,
} from './utils/content-scripts';
/**
* Creates a dev server and pre-builds all the files that need to exist before loading the extension.
@@ -232,7 +235,7 @@ function reloadContentScripts(steps: BuildStepOutput[], server: WxtDevServer) {
const entry = step.entrypoints;
if (Array.isArray(entry) || entry.type !== 'content-script') return;
const js = [getEntrypointBundlePath(entry, wxt.config.outDir, '.js')];
const js = getContentScriptJs(wxt.config, entry);
const cssMap = getContentScriptsCssMap(server.currentOutput, [entry]);
const css = getContentScriptCssFiles([entry], cssMap);
@@ -0,0 +1,20 @@
import { describe, it } from 'vitest';
import {
VirtualModuleId,
VirtualModuleName,
VirtualEntrypointType,
VirtualEntrypointModuleName,
} from '../virtual-modules';
describe('Virtual Modules', () => {
it('should resolve types to litteral values, not string', () => {
// @ts-expect-error
const _c: VirtualEntrypointType = '';
// @ts-expect-error
const _d: VirtualEntrypointModuleName = '';
// @ts-expect-error
const _b: VirtualModuleName = '';
// @ts-expect-error
const _a: VirtualModuleId = '';
});
});
+11
View File
@@ -21,3 +21,14 @@ export function some<T>(
if (predicate(array[i], i)) return true;
return false;
}
/**
* Convert an item or array to an array.
*/
export function toArray<T>(a: T | T[]): T[] {
return Array.isArray(a) ? a : [a];
}
export function filterTruthy<T>(array: Array<T | undefined>): T[] {
return array.filter((item) => !!item) as T[];
}
+2 -1
View File
@@ -5,6 +5,7 @@ import { dirname, resolve } from 'path';
import type { Ora } from 'ora';
import pc from 'picocolors';
import { wxt } from '../../wxt';
import { toArray } from '../arrays';
export async function buildEntrypoints(
groups: EntrypointGroup[],
@@ -13,7 +14,7 @@ export async function buildEntrypoints(
const steps: BuildStepOutput[] = [];
for (let i = 0; i < groups.length; i++) {
const group = groups[i];
const groupNames = [group].flat().map((e) => e.name);
const groupNames = toArray(group).map((e) => e.name);
const groupNameColored = groupNames.join(pc.dim(', '));
spinner.text =
pc.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNameColored}`;
+9 -1
View File
@@ -1,5 +1,6 @@
import type { Manifest, Scripting } from '~/browser';
import { ContentScriptEntrypoint } from '~/types';
import { ContentScriptEntrypoint, ResolvedConfig } from '~/types';
import { getEntrypointBundlePath } from './entrypoints';
/**
* Returns a unique and consistent string hash based on a content scripts options.
@@ -83,3 +84,10 @@ export function mapWxtOptionsToRegisteredContentScript(
world: options.world,
};
}
export function getContentScriptJs(
config: ResolvedConfig,
entrypoint: ContentScriptEntrypoint,
): string[] {
return [getEntrypointBundlePath(entrypoint, config.outDir, '.js')];
}
+1 -1
View File
@@ -1,7 +1,7 @@
import { ResolvedConfig } from '~/types';
export function getGlobals(
config: Omit<ResolvedConfig, 'builder'>,
config: ResolvedConfig,
): Array<{ name: string; value: any; type: string }> {
return [
{
+1 -1
View File
@@ -26,7 +26,7 @@ export async function isOnline(): Promise<boolean> {
*/
export async function fetchCached(
url: string,
config: Omit<ResolvedConfig, 'builder'>,
config: ResolvedConfig,
): Promise<string> {
let content: string = '';
+37
View File
@@ -0,0 +1,37 @@
export const virtualEntrypointTypes = [
'content-script-main-world' as const,
'content-script-isolated-world' as const,
'background' as const,
'unlisted-script' as const,
];
export type VirtualEntrypointType = (typeof virtualEntrypointTypes)[0];
/**
* All the names of entrypoint files in the `src/virtual/` and `dist/virtual/` directories, minus the extension.
*/
export const virtualEntrypointModuleNames = virtualEntrypointTypes.map(
(name) => `${name}-entrypoint` as const,
);
/**
* Name of entrypoint files in the `src/virtual/` and `dist/virtual/` directories, minus the extension.
*/
export type VirtualEntrypointModuleName =
(typeof virtualEntrypointModuleNames)[0];
/**
* All the names of files in the `src/virtual/` and `dist/virtual/` directories, minus the extension.
*/
export const virtualModuleNames = [
...virtualEntrypointModuleNames,
'mock-browser' as const,
'reload-html' as const,
];
/**
* Name of files in the `src/virtual/` and `dist/virtual/` directories, minus the extension.
*/
export type VirtualModuleName = (typeof virtualModuleNames)[0];
/**
* Import alias used for importing a virtual module
*/
export type VirtualModuleId = `virtual:wxt-${VirtualModuleName}`;
+1 -1
View File
@@ -28,7 +28,7 @@ export async function registerWxt(
const hooks = createHooks<WxtHooks>();
const config = await resolveConfig(inlineConfig, command);
const server = await getServer?.(config);
const builder = await createViteBuilder(config, server);
const builder = await createViteBuilder(config, hooks, server);
const pm = await createWxtPackageManager(config.root);
wxt = {
+2 -1
View File
@@ -8,6 +8,7 @@
import { Storage, browser } from '~/browser';
import { dequal } from 'dequal/lite';
import { logger } from './sandbox/utils/logger';
import { toArray } from './core/utils/arrays';
export const storage = createStorage();
@@ -107,7 +108,7 @@ function createStorage(): WxtStorage {
await driver.removeItem(metaKey);
} else {
const newFields = getMetaValue(await driver.getItem(metaKey));
[properties].flat().forEach((field) => delete newFields[field]);
toArray(properties).forEach((field) => delete newFields[field]);
await driver.setItem(metaKey, newFields);
}
};
+23 -7
View File
@@ -173,7 +173,7 @@ export interface InlineConfig {
*
* @example
* [
* "coverage", // Ignore the coverage directory in the `sourcesRoot`
* "coverage", // Include the coverage directory in the `sourcesRoot`
* ]
*/
excludeSources?: string[];
@@ -361,6 +361,28 @@ export type WxtViteConfig = Omit<
'root' | 'configFile' | 'mode'
>;
// TODO: Move into @wxt/vite-builder
export interface WxtHooks {
/**
* Called when WXT has created Vite's config for a build step. Useful if you
* want to add plugins or update the vite config per entrypoint group.
*
* @param entrypoints The list of entrypoints being built with the provided config.
* @param viteConfig The config that will be used for the dev server.
*/
'vite:build:extendConfig': (
entrypoints: readonly Entrypoint[],
viteConfig: vite.InlineConfig,
) => HookResult;
/**
* Called when WXT has created Vite's config for the dev server. Useful if
* you want to add plugins or update the vite config per entrypoint group.
*
* @param viteConfig The config that will be used to build the entrypoints. Can be updated by reference.
*/
'vite:devServer:extendConfig': (config: vite.InlineConfig) => HookResult;
}
export interface BuildOutput {
manifest: Manifest.WebExtensionManifest;
publicAssets: OutputAsset[];
@@ -1103,12 +1125,6 @@ export interface ExtensionRunner {
closeBrowser(): Promise<void>;
}
export type VirtualEntrypointType =
| 'content-script-main-world'
| 'content-script-isolated-world'
| 'background'
| 'unlisted-script';
export type EslintGlobalsPropValue =
| boolean
| 'readonly'
+1 -1
View File
@@ -1,4 +1,4 @@
import definition from 'virtual:user-background';
import definition from 'virtual:user-background-entrypoint';
import { setupWebSocket } from './utils/setup-web-socket';
import { logger } from '../sandbox/utils/logger';
import { browser } from 'wxt/browser';
@@ -1,4 +1,4 @@
import definition from 'virtual:user-content-script-isolated-world';
import definition from 'virtual:user-content-script-isolated-world-entrypoint';
import { logger } from '../sandbox/utils/logger';
import { ContentScriptContext } from 'wxt/client';
@@ -1,4 +1,4 @@
import definition from 'virtual:user-content-script-main-world';
import definition from 'virtual:user-content-script-main-world-entrypoint';
import { logger } from '../sandbox/utils/logger';
(async () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import definition from 'virtual:user-unlisted-script';
import definition from 'virtual:user-unlisted-script-entrypoint';
import { logger } from '../sandbox/utils/logger';
(async () => {
+4 -4
View File
@@ -1,11 +1,11 @@
// Types required to make the virtual modules happy.
declare module 'virtual:user-background' {
declare module 'virtual:user-background-entrypoint' {
const definition: { main: () => void };
export default definition;
}
declare module 'virtual:user-content-script-isolated-world' {
declare module 'virtual:user-content-script-isolated-world-entrypoint' {
const definition: {
main: (
ctx: import('wxt/client').ContentScriptContext,
@@ -14,12 +14,12 @@ declare module 'virtual:user-content-script-isolated-world' {
export default definition;
}
declare module 'virtual:user-content-script-main-world' {
declare module 'virtual:user-content-script-main-world-entrypoint' {
const definition: { main: () => void | Promise<void> };
export default definition;
}
declare module 'virtual:user-unlisted-script' {
declare module 'virtual:user-unlisted-script-entrypoint' {
const definition: { main: () => void | Promise<void> };
export default definition;
}