Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 229dfc822d | |||
| 7177405c11 | |||
| 24e4abc087 | |||
| ac9a4380b1 | |||
| 71620a02ab | |||
| 0aca961629 | |||
| d64af5d4f0 | |||
| 7eb0a36245 | |||
| 14bae66bba | |||
| e4ec4a28f9 | |||
| 7b32dd7062 | |||
| b1ef71a77b | |||
| 2f7fb30467 | |||
| 4c684e7966 | |||
| 8d5fbb2a32 | |||
| 5eb5be7123 | |||
| 886b2081c2 | |||
| c69e51ce50 | |||
| 861efa3415 | |||
| 792b57542d | |||
| 97e6678e5b | |||
| 66c4ec3f99 | |||
| 8988d6a241 | |||
| b52856bea4 | |||
| 16fee19b85 | |||
| 14011c19cb | |||
| 005a9dff16 | |||
| 3109bbadbe | |||
| 34ae689569 | |||
| 1f216dd57b | |||
| a7963e23db | |||
| 069bd6c435 | |||
| 88a1244ca9 | |||
| 7ee391f688 | |||
| 2b3eab9c2a | |||
| a3fc9e1e18 | |||
| 559d32e6eb | |||
| f904b79367 | |||
| 9cd7cca81c | |||
| 3366c1e35f | |||
| 82be31a408 | |||
| d767f3f598 | |||
| 48967c7c5f | |||
| 6c4da7225d | |||
| e9025fb13e | |||
| 8db6b3187b | |||
| a19f9e12c4 | |||
| a82eb46511 |
@@ -35,7 +35,7 @@ jobs:
|
||||
- uses: ./.github/actions/setup
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
- name: pnpm test:coverage
|
||||
run: pnpm test:coverage --reporter=default --reporter=hanging-process
|
||||
run: pnpm test:coverage -- --reporter=default --reporter=hanging-process
|
||||
- uses: codecov/codecov-action@v4
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup
|
||||
- run: pnpm test run
|
||||
- run: pnpm test
|
||||
template:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
## Demo
|
||||
|
||||
<video src="https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94"></video>
|
||||
https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ const chromeExtensionIds = [
|
||||
'khjdmjcmpolknpccmaaipmidphjokhdf', // WorkFlowy MultiFlow
|
||||
'fencadnndhdeggodopebjgdfdlhcimfk', // 香草布丁🌿🍮- https://github.com/Xdy1579883916/vanilla-pudding
|
||||
'bnacincmbaknlbegecpioobkfgejlojp', // MaxFocus: Link Preview
|
||||
'bcpgdpedphodjcjlminjbdeejccjbimp', // 汇率转换-中文版本
|
||||
'loeilaonggnalkaiiaepbegccilkmjjp', // Currency Converter Plus
|
||||
'npcnninnjghigjfiecefheeibomjpkak', // Respond Easy
|
||||
];
|
||||
|
||||
const { data, err, isLoading } = useListExtensionDetails(chromeExtensionIds);
|
||||
|
||||
@@ -17,7 +17,7 @@ In WXT, you create an entrypoint by adding a file to the `entrypoints/` director
|
||||
|
||||
Some entrypoint filesname patterns are reserved by WXT and effect how the manifest is generated.
|
||||
|
||||
- `popup` adds a `action` to the manifest
|
||||
- `popup` adds an `action` to the manifest
|
||||
- `background` adds a background script/service worker
|
||||
- `*.content.ts` adds a content script
|
||||
- ...
|
||||
|
||||
@@ -25,7 +25,7 @@ In general, you'll need to:
|
||||
 <input type="checkbox" /> Convert custom import syntax to be compatible with Vite<br />
|
||||
 <input type="checkbox" /> Add a default export to JS entrypoints<br />
|
||||
 <input type="checkbox" /> Use the `browser` global instead of `chrome`<br />
|
||||
 <input type="checkbox" /> Compare final `manifest.json` files, making sure permissions and host permissions are unchanged<br />
|
||||
 <input type="checkbox" /> Compare final `manifest.json` files, making sure permissions and host permissions are unchanged. Use [Google's update testing tool](https://github.com/GoogleChromeLabs/extension-update-testing-tool) if your extension is already live on the Chrome Web Store<br />
|
||||
 <input type="checkbox" /> Extension output by `wxt build` works the same way as before the migration<br />
|
||||
|
||||
Every project is different, so there's no one-solution-fits-all to migrating your project. Just make sure `wxt dev` runs, `wxt build` results in a working extension, and the list of permissions in the `manifest.json` hasn't changed. If all that looks good, you've finished migrating your extension!
|
||||
|
||||
@@ -19,7 +19,7 @@ There are other options for unit tests however, like [Jest](https://jestjs.io/),
|
||||
If you want to try to use a different framework for unit tests, you will need to configure the environment manually:
|
||||
|
||||
- **Auto-imports**: Add `unimport` to your test environment or disable them by setting `imports: false` in your `wxt.config.ts` file
|
||||
- **`browser` mock**: Mock the `webextension-polyfill` module globally with `wxt/dist/virtual/mock-browser.js`
|
||||
- **`browser` mock**: Mock the `webextension-polyfill` module globally with `wxt/dist/virtual/mock-browser.mjs`
|
||||
- **[Remote Code Bundling](/guide/go-further/remote-code)**: If you use it, configure your environment to handle the `url:` module prefix
|
||||
- **Global Variables**: If you consume them, manually define globals provided by WXT (like `import.meta.env.BROWSER`) by adding them to the global scope before accessing them (`import.meta.env.BROWSER = "chrome"`)
|
||||
- **Import paths**: If you use the `@/` or `~/` path aliases, add them to your test environment
|
||||
|
||||
@@ -6,7 +6,7 @@ WXT uses the same tool as Nuxt for auto-imports, [`unimport`](https://github.com
|
||||
|
||||
Some WXT APIs can be used without importing them:
|
||||
|
||||
- [`browser`](/api/reference/wxt/browser/variables/browser) from `wxt/browser`, a small wrapper around `webextension-polyfill`
|
||||
- [`browser`](/api/reference/wxt/browser/#browser) from `wxt/browser`, a small wrapper around `webextension-polyfill`
|
||||
- [`defineContentScript`](/api/reference/wxt/sandbox/functions/defineContentScript) from `wxt/sandbox`
|
||||
- [`defineBackground`](/api/reference/wxt/sandbox/functions/defineBackground) from `wxt/sandbox`
|
||||
- [`defineUnlistedScript`](/api/reference/wxt/sandbox/functions/defineUnlistedScript) from `wxt/sandbox`
|
||||
|
||||
@@ -95,7 +95,7 @@ Usually, this means each entrypoint should be a directory with it's own files in
|
||||
├ App.vue
|
||||
├ main.ts
|
||||
├ style.css
|
||||
└ rotuer.ts
|
||||
└ router.ts
|
||||
```
|
||||
|
||||
## Configuring Routers
|
||||
|
||||
@@ -147,6 +147,31 @@ export default defineConfig({
|
||||
});
|
||||
```
|
||||
|
||||
### Host Permissions
|
||||
|
||||
[Host Permissions](https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions#host-permissions) must be listed in the manifest config.
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
manifest: {
|
||||
host_permissions: ['*://*.google.com/*'],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
:::warning
|
||||
If you use host permissions and target both MV2 and MV3, make sure to only include the required host permissions for each version:
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
manifest: ({ manifestVersion }) => ({
|
||||
host_permissions: manifestVersion === 2 ? [...] : [...],
|
||||
}),
|
||||
});
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Localization
|
||||
|
||||
Similar to the icon, the [`_locales` directory](https://developer.chrome.com/docs/extensions/reference/i18n/) should be placed inside the the WXT's [`public` directory](/guide/directory-structure/public/).
|
||||
@@ -229,7 +254,7 @@ The `manifest` option can also be set equal to a function, letting you use logic
|
||||
```ts
|
||||
// wxt.config.ts
|
||||
export default defineConfig({
|
||||
manifest: ({ manifestVersion, browser, mode, comamnd }) => {
|
||||
manifest: ({ manifestVersion, browser, mode, command }) => {
|
||||
return { ... }
|
||||
}
|
||||
})
|
||||
|
||||
+10
-12
@@ -5,11 +5,11 @@
|
||||
"node": ">=18.20.3",
|
||||
"pnpm": "^8.6.3"
|
||||
},
|
||||
"packageManager": "pnpm@8.15.8",
|
||||
"packageManager": "pnpm@8.15.9",
|
||||
"scripts": {
|
||||
"check": "check && pnpm -r --sequential run check",
|
||||
"test": "vitest",
|
||||
"test:coverage": "vitest run --coverage.enabled \"--coverage.include=packages/wxt/src/**\" \"--coverage.exclude=packages/wxt/src/core/utils/testing/**\" \"--coverage.exclude=**/*.d.ts\" \"--coverage.exclude=**/fixtures/**\"",
|
||||
"test": "pnpm -r --sequential run test run",
|
||||
"test:coverage": "pnpm -r --sequential run test:coverage",
|
||||
"prepare": "simple-git-hooks",
|
||||
"prepublish": "pnpm -s build",
|
||||
"docs:gen": "typedoc --options docs/typedoc.json",
|
||||
@@ -18,10 +18,10 @@
|
||||
"docs:preview": "pnpm -s docs:gen && vitepress preview docs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/buildc": "^1.0.10",
|
||||
"@aklinker1/buildc": "^1.0.11",
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@vitest/coverage-v8": "^1.6.0",
|
||||
"@vitest/coverage-v8": "^2.0.0",
|
||||
"changelogen": "^0.5.5",
|
||||
"consola": "^3.2.3",
|
||||
"dependency-graph": "^1.0.0",
|
||||
@@ -31,18 +31,16 @@
|
||||
"hasha": "^6.0.0",
|
||||
"lint-staged": "^15.2.7",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier": "^3.3.3",
|
||||
"simple-git-hooks": "^2.11.1",
|
||||
"tsx": "4.15.7",
|
||||
"typedoc": "^0.25.4",
|
||||
"typedoc-plugin-markdown": "4.0.0-next.23",
|
||||
"typedoc-vitepress-theme": "1.0.0-next.3",
|
||||
"typescript": "^5.5.2",
|
||||
"vitepress": "^1.2.3",
|
||||
"vitest": "^1.6.0",
|
||||
"vitest-mock-extended": "^1.3.1",
|
||||
"vitest-plugin-random-seed": "^1.1.0",
|
||||
"vue": "^3.4.31",
|
||||
"typescript": "^5.5.3",
|
||||
"vitepress": "^1.3.1",
|
||||
"vitest-mock-extended": "^1.3.2",
|
||||
"vue": "^3.4.33",
|
||||
"wxt": "workspace:*",
|
||||
"yaml": "^2.4.5"
|
||||
},
|
||||
|
||||
@@ -9,6 +9,7 @@ export default defineWxtModule<ReactModuleOptions>({
|
||||
const { vite } = options ?? {};
|
||||
|
||||
addViteConfig(wxt, () => ({
|
||||
// @ts-expect-error: Vite version conflicts
|
||||
plugins: [react(vite)],
|
||||
}));
|
||||
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"publint": "^0.2.8",
|
||||
"publint": "^0.2.9",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"typescript": "^5.5.2",
|
||||
"typescript": "^5.5.3",
|
||||
"unbuild": "^2.0.0",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ export default defineWxtModule<SolidModuleOptions>({
|
||||
const { vite } = options ?? {};
|
||||
|
||||
addViteConfig(wxt, () => ({
|
||||
// @ts-expect-error: Vite version mismatch
|
||||
plugins: [solid(vite)],
|
||||
build: {
|
||||
target: 'esnext',
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"publint": "^0.2.8",
|
||||
"solid-js": "^1.8.17",
|
||||
"typescript": "^5.5.2",
|
||||
"publint": "^0.2.9",
|
||||
"solid-js": "^1.8.18",
|
||||
"typescript": "^5.5.3",
|
||||
"unbuild": "^2.0.0",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ Enables the use of [Svelte](https://svelte.dev/) in your web extension, in HTML
|
||||
This plugin makes a few changes:
|
||||
|
||||
1. Adds `@sveltejs/vite-plugin-svelte` to vite
|
||||
2. Adds the [`svelte` preset](https://github.com/unjs/unimport/blob/main/src/presets/vue.ts) to auto-imports
|
||||
2. Adds the [`svelte` preset](https://github.com/unjs/unimport/blob/main/src/presets/svelte.ts) to auto-imports
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"publint": "^0.2.8",
|
||||
"typescript": "^5.5.2",
|
||||
"publint": "^0.2.9",
|
||||
"typescript": "^5.5.3",
|
||||
"unbuild": "^2.0.0",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ export default defineWxtModule<SvelteModuleOptions>({
|
||||
|
||||
addViteConfig(wxt, () => ({
|
||||
plugins: [
|
||||
// @ts-expect-error: Vite version mismatch
|
||||
svelte({
|
||||
// Using a svelte.config.js file causes a segmentation fault when importing the file
|
||||
configFile: false,
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"publint": "^0.2.8",
|
||||
"typescript": "^5.5.2",
|
||||
"publint": "^0.2.9",
|
||||
"typescript": "^5.5.3",
|
||||
"unbuild": "^2.0.0",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "buildc --deps-only -- wxt",
|
||||
"build": "buildc -- wxt build",
|
||||
"build": "buildc --deps-only -- wxt build",
|
||||
"build:all": "buildc --deps-only -- run-s -s 'build:all:*'",
|
||||
"build:all:chrome-mv3": "wxt build",
|
||||
"build:all:chrome-mv2": "wxt build --mv2",
|
||||
@@ -21,10 +21,13 @@
|
||||
"react-dom": "^18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chrome": "^0.0.268",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"sass": "^1.77.6",
|
||||
"typescript": "^5.5.2",
|
||||
"sass": "^1.77.8",
|
||||
"typescript": "^5.5.3",
|
||||
"vitest": "^2.0.3",
|
||||
"vitest-plugin-random-seed": "^1.1.0",
|
||||
"wxt": "workspace:*"
|
||||
},
|
||||
"buildc": {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"extends": ["../../tsconfig.base.json", "./.wxt/tsconfig.json"],
|
||||
"compilerOptions": {
|
||||
"allowImportingTsExtensions": true,
|
||||
"jsx": "react-jsx"
|
||||
"jsx": "react-jsx",
|
||||
"types": ["vitest-plugin-random-seed/types"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,8 @@ export default defineProject({
|
||||
mockReset: true,
|
||||
restoreMocks: true,
|
||||
},
|
||||
plugins: [WxtVitest()],
|
||||
plugins: [
|
||||
// @ts-expect-error: Vite version mismatch
|
||||
WxtVitest(),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@ import { defineConfig } from 'wxt';
|
||||
|
||||
export default defineConfig({
|
||||
srcDir: 'src',
|
||||
extensionApi: 'chrome',
|
||||
manifest: {
|
||||
permissions: ['storage'],
|
||||
default_locale: 'en',
|
||||
|
||||
@@ -1,5 +1,48 @@
|
||||
# Changelog
|
||||
|
||||
## v0.18.15
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.18.14...wxt-v0.18.15)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Don't throw error if localization file is missing ([#832](https://github.com/wxt-dev/wxt/pull/832))
|
||||
- Build latest version of package before packing ([88a1244](https://github.com/wxt-dev/wxt/commit/88a1244))
|
||||
- Externalize app config during dependency optimization ([#833](https://github.com/wxt-dev/wxt/pull/833))
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Fix links to Guide pages ([#821](https://github.com/wxt-dev/wxt/pull/821))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Eetann ([@eetann](http://github.com/eetann))
|
||||
|
||||
## v0.18.14
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.18.13...wxt-v0.18.14)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- **modules:** Add types from all wxt node_modules, not just ones with config ([#817](https://github.com/wxt-dev/wxt/pull/817))
|
||||
|
||||
## v0.18.13
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.18.12...wxt-v0.18.13)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- **config:** `dev.server.hostname` ([#807](https://github.com/wxt-dev/wxt/pull/807))
|
||||
- Add XPath support to getAnchor() ([#813](https://github.com/wxt-dev/wxt/pull/813))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Add debug logs for vite builder ([#816](https://github.com/wxt-dev/wxt/pull/816))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Ayub Kokabi ([@sir-kokabi](http://github.com/sir-kokabi))
|
||||
|
||||
## v0.18.12
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.18.11...wxt-v0.18.12)
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
## Demo
|
||||
|
||||
<video src="https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94"></video>
|
||||
https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/usr/bin/env node
|
||||
import '../dist/cli.js';
|
||||
import '../dist/cli/index.mjs';
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
import { version } from './package.json';
|
||||
import { readFile, writeFile } from 'fs/promises';
|
||||
import {
|
||||
virtualEntrypointModuleNames,
|
||||
virtualModuleNames,
|
||||
} from './src/core/utils/virtual-modules';
|
||||
|
||||
export default defineBuildConfig([
|
||||
// Non-virtual modules can be transpiled with mkdist
|
||||
{
|
||||
entries: [
|
||||
{
|
||||
builder: 'mkdist',
|
||||
input: 'src',
|
||||
pattern: ['**/*', '!**/__tests__', '!**/*.md', '!virtual', '!@types'],
|
||||
declaration: true,
|
||||
},
|
||||
],
|
||||
hooks: {
|
||||
async 'build:done'() {
|
||||
// Replace any template variables in output files
|
||||
await replaceVars('dist/version.mjs', { version });
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Virtual modules must be bundled individually
|
||||
...virtualModuleNames.map((moduleName) => ({
|
||||
entries: [`src/virtual/${moduleName}.ts`],
|
||||
externals: [
|
||||
...virtualEntrypointModuleNames.map((name) => `virtual:user-${name}`),
|
||||
'virtual:wxt-plugins',
|
||||
'virtual:app-config',
|
||||
'wxt/browser',
|
||||
'wxt/sandbox',
|
||||
'wxt/client',
|
||||
'wxt/testing',
|
||||
],
|
||||
})),
|
||||
]);
|
||||
|
||||
async function replaceVars(file: string, vars: Record<string, string>) {
|
||||
let text = await readFile(file, 'utf8');
|
||||
Object.entries(vars).forEach(([name, value]) => {
|
||||
text = text.replaceAll(`{{${name}}}`, value);
|
||||
});
|
||||
await writeFile(file, text, 'utf8');
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import { TestProject } from '../utils';
|
||||
import { resetBundleIncrement } from '~/core/builders/vite/plugins';
|
||||
import { resetBundleIncrement } from '../../src/core/builders/vite/plugins';
|
||||
import open from 'open';
|
||||
|
||||
vi.mock('open');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { TestProject } from '../utils';
|
||||
import { WxtHooks } from '~/types';
|
||||
import { WxtHooks } from '../../src/types';
|
||||
|
||||
const hooks: WxtHooks = {
|
||||
ready: vi.fn(),
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { TestProject } from '../utils';
|
||||
import { TestProject, WXT_PACKAGE_DIR } from '../utils';
|
||||
import { execaCommand } from 'execa';
|
||||
import glob from 'fast-glob';
|
||||
import { mkdir, writeJson } from 'fs-extra';
|
||||
import { WXT_PACKAGE_DIR } from '../utils';
|
||||
|
||||
describe('Init command', () => {
|
||||
it('should download and create a template', async () => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { describe, it, expect, vi } from 'vitest';
|
||||
import { TestProject } from '../utils';
|
||||
import type { GenericEntrypoint, InlineConfig } from '../../src/types';
|
||||
import { readFile } from 'fs-extra';
|
||||
import { normalizePath } from '~/core/utils/paths';
|
||||
import { normalizePath } from '../../src/core/utils/paths';
|
||||
|
||||
describe('Module Helpers', () => {
|
||||
describe('options', () => {
|
||||
@@ -192,10 +192,8 @@ describe('Module Helpers', () => {
|
||||
const expectedText = addPluginModule(project);
|
||||
|
||||
await project.build({
|
||||
experimental: {
|
||||
// reduce build output when comparing test failures
|
||||
includeBrowserPolyfill: false,
|
||||
},
|
||||
// reduce build output when comparing test failures
|
||||
extensionApi: 'chrome',
|
||||
});
|
||||
|
||||
await expect(project.serializeOutput()).resolves.toContain(expectedText);
|
||||
@@ -214,10 +212,8 @@ describe('Module Helpers', () => {
|
||||
const expectedText = addPluginModule(project);
|
||||
|
||||
await project.build({
|
||||
experimental: {
|
||||
// reduce build output when comparing test failures
|
||||
includeBrowserPolyfill: false,
|
||||
},
|
||||
// reduce build output when comparing test failures
|
||||
extensionApi: 'chrome',
|
||||
});
|
||||
|
||||
await expect(project.serializeOutput()).resolves.toContain(expectedText);
|
||||
@@ -237,10 +233,8 @@ describe('Module Helpers', () => {
|
||||
const expectedText = addPluginModule(project);
|
||||
|
||||
await project.build({
|
||||
experimental: {
|
||||
// reduce build output when comparing test failures
|
||||
includeBrowserPolyfill: false,
|
||||
},
|
||||
// reduce build output when comparing test failures
|
||||
extensionApi: 'chrome',
|
||||
});
|
||||
|
||||
await expect(project.serializeOutput()).resolves.toContain(expectedText);
|
||||
@@ -255,10 +249,8 @@ describe('Module Helpers', () => {
|
||||
const expectedText = addPluginModule(project);
|
||||
|
||||
await project.build({
|
||||
experimental: {
|
||||
// reduce build output when comparing test failures
|
||||
includeBrowserPolyfill: false,
|
||||
},
|
||||
// reduce build output when comparing test failures
|
||||
extensionApi: 'chrome',
|
||||
});
|
||||
|
||||
await expect(project.serializeOutput()).resolves.toContain(expectedText);
|
||||
|
||||
@@ -262,10 +262,9 @@ describe('Output Directory Structure', () => {
|
||||
project.addFile('entrypoints/popup/main.ts', `logHello('popup')`);
|
||||
|
||||
await project.build({
|
||||
experimental: {
|
||||
// Simplify the build output for comparison
|
||||
includeBrowserPolyfill: false,
|
||||
},
|
||||
// Simplify the build output for comparison
|
||||
extensionApi: 'chrome',
|
||||
|
||||
vite: () => ({
|
||||
build: {
|
||||
// Make output for snapshot readible
|
||||
@@ -278,6 +277,7 @@ describe('Output Directory Structure', () => {
|
||||
.toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/background.js
|
||||
----------------------------------------
|
||||
var _a, _b;
|
||||
import { l as logHello, i as initPlugins } from "./chunks/_virtual_wxt-plugins-OjKtWpmY.js";
|
||||
function defineBackground(arg) {
|
||||
if (typeof arg === "function") return { main: arg };
|
||||
@@ -289,17 +289,21 @@ describe('Output Directory Structure', () => {
|
||||
logHello("background");
|
||||
}
|
||||
});
|
||||
chrome;
|
||||
// @ts-expect-error
|
||||
((_b = (_a = globalThis.browser) == null ? void 0 : _a.runtime) == null ? void 0 : _b.id) == null ? globalThis.chrome : (
|
||||
// @ts-expect-error
|
||||
globalThis.browser
|
||||
);
|
||||
function print(method, ...args) {
|
||||
return;
|
||||
}
|
||||
var logger = {
|
||||
const logger = {
|
||||
debug: (...args) => print(console.debug, ...args),
|
||||
log: (...args) => print(console.log, ...args),
|
||||
warn: (...args) => print(console.warn, ...args),
|
||||
error: (...args) => print(console.error, ...args)
|
||||
};
|
||||
var result;
|
||||
let result;
|
||||
try {
|
||||
initPlugins();
|
||||
result = definition.main();
|
||||
@@ -343,10 +347,9 @@ describe('Output Directory Structure', () => {
|
||||
project.addFile('entrypoints/popup/main.ts', `logHello('popup')`);
|
||||
|
||||
await project.build({
|
||||
experimental: {
|
||||
// Simplify the build output for comparison
|
||||
includeBrowserPolyfill: false,
|
||||
},
|
||||
// Simplify the build output for comparison
|
||||
extensionApi: 'chrome',
|
||||
|
||||
vite: () => ({
|
||||
build: {
|
||||
// Make output for snapshot readible
|
||||
@@ -361,6 +364,7 @@ describe('Output Directory Structure', () => {
|
||||
----------------------------------------
|
||||
var _background = function() {
|
||||
"use strict";
|
||||
var _a, _b;
|
||||
function defineBackground(arg) {
|
||||
if (typeof arg === "function") return { main: arg };
|
||||
return arg;
|
||||
@@ -377,17 +381,21 @@ describe('Output Directory Structure', () => {
|
||||
_background;
|
||||
function initPlugins() {
|
||||
}
|
||||
chrome;
|
||||
// @ts-expect-error
|
||||
((_b = (_a = globalThis.browser) == null ? void 0 : _a.runtime) == null ? void 0 : _b.id) == null ? globalThis.chrome : (
|
||||
// @ts-expect-error
|
||||
globalThis.browser
|
||||
);
|
||||
function print(method, ...args) {
|
||||
return;
|
||||
}
|
||||
var logger = {
|
||||
const logger = {
|
||||
debug: (...args) => print(console.debug, ...args),
|
||||
log: (...args) => print(console.log, ...args),
|
||||
warn: (...args) => print(console.warn, ...args),
|
||||
error: (...args) => print(console.error, ...args)
|
||||
};
|
||||
var result;
|
||||
let result;
|
||||
try {
|
||||
initPlugins();
|
||||
result = definition.main();
|
||||
@@ -400,8 +408,8 @@ describe('Output Directory Structure', () => {
|
||||
logger.error("The background crashed on startup!");
|
||||
throw err;
|
||||
}
|
||||
var background_entrypoint_default = result;
|
||||
return background_entrypoint_default;
|
||||
const result$1 = result;
|
||||
return result$1;
|
||||
}();
|
||||
_background;
|
||||
"
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('TypeScript Project', () => {
|
||||
| "/popup.html"
|
||||
| "/sandbox.html"
|
||||
type HtmlPublicPath = Extract<PublicPath, \`\${string}.html\`>
|
||||
export interface WxtRuntime extends Runtime.Static {
|
||||
export interface WxtRuntime {
|
||||
getURL(path: PublicPath): string;
|
||||
getURL(path: \`\${HtmlPublicPath}\${string}\`): string;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { TestProject } from '../utils';
|
||||
import { InlineConfig } from '~/types';
|
||||
import { InlineConfig } from '../../src/types';
|
||||
|
||||
describe('User Config', () => {
|
||||
// Root directory is tested with all tests.
|
||||
@@ -88,7 +88,7 @@ describe('User Config', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should exclude the polyfill when the experimental setting is set to false', async () => {
|
||||
it('should exclude the polyfill when extensionApi="chrome"', async () => {
|
||||
const buildBackground = async (config?: InlineConfig) => {
|
||||
const background = `export default defineBackground(() => console.log(browser.runtime.id));`;
|
||||
const projectWithPolyfill = new TestProject();
|
||||
@@ -101,9 +101,7 @@ describe('User Config', () => {
|
||||
|
||||
const withPolyfill = await buildBackground();
|
||||
const withoutPolyfill = await buildBackground({
|
||||
experimental: {
|
||||
includeBrowserPolyfill: false,
|
||||
},
|
||||
extensionApi: 'chrome',
|
||||
});
|
||||
expect(withoutPolyfill).not.toBe(withPolyfill);
|
||||
});
|
||||
|
||||
+53
-58
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "wxt",
|
||||
"type": "module",
|
||||
"version": "0.18.12",
|
||||
"version": "0.19.0-alpha1",
|
||||
"description": "Next gen framework for developing web extensions",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -30,75 +30,59 @@
|
||||
"wxt": "./bin/wxt.mjs",
|
||||
"wxt-publish-extension": "./bin/wxt-publish-extension.cjs"
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/index.d.cts",
|
||||
"default": "./dist/index.cjs"
|
||||
}
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"./client": {
|
||||
"types": "./dist/client.d.ts",
|
||||
"import": "./dist/client.js"
|
||||
"types": "./dist/client/index.d.ts",
|
||||
"default": "./dist/client/index.mjs"
|
||||
},
|
||||
"./sandbox": {
|
||||
"types": "./dist/sandbox.d.ts",
|
||||
"import": "./dist/sandbox.js"
|
||||
"types": "./dist/sandbox/index.d.ts",
|
||||
"default": "./dist/sandbox/index.mjs"
|
||||
},
|
||||
"./browser": {
|
||||
"types": "./dist/browser.d.ts",
|
||||
"import": "./dist/browser.js"
|
||||
"types": "./dist/browser/index.d.ts",
|
||||
"default": "./dist/browser/index.mjs"
|
||||
},
|
||||
"./browser/chrome": {
|
||||
"types": "./dist/browser/chrome.d.ts",
|
||||
"import": "./dist/browser/chrome.mjs"
|
||||
},
|
||||
"./browser/webextension-polyfill": {
|
||||
"types": "./dist/browser/webextension-polyfill.d.ts",
|
||||
"import": "./dist/browser/webextension-polyfill.mjs"
|
||||
},
|
||||
"./testing": {
|
||||
"import": {
|
||||
"types": "./dist/testing.d.ts",
|
||||
"default": "./dist/testing.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/testing.d.cts",
|
||||
"default": "./dist/testing.cjs"
|
||||
}
|
||||
"types": "./dist/testing/index.d.ts",
|
||||
"default": "./dist/testing/index.mjs"
|
||||
},
|
||||
"./storage": {
|
||||
"import": {
|
||||
"types": "./dist/storage.d.ts",
|
||||
"default": "./dist/storage.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/storage.d.cts",
|
||||
"default": "./dist/storage.cjs"
|
||||
}
|
||||
"types": "./dist/storage.d.ts",
|
||||
"default": "./dist/storage.mjs"
|
||||
},
|
||||
"./vite-builder-env": {
|
||||
"types": "./dist/vite-builder-env.d.ts"
|
||||
},
|
||||
"./modules": {
|
||||
"import": {
|
||||
"types": "./dist/modules.d.ts",
|
||||
"default": "./dist/modules.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/modules.d.cts",
|
||||
"default": "./dist/modules.cjs"
|
||||
}
|
||||
"types": "./dist/modules.d.ts",
|
||||
"default": "./dist/modules.mjs"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"wxt": "tsx src/cli/index.ts",
|
||||
"build": "buildc -- tsx scripts/build.ts",
|
||||
"build": "buildc -- unbuild",
|
||||
"check": "buildc --deps-only -- run-s -c check:*",
|
||||
"check:default": "check",
|
||||
"check:tsc-virtual": "tsc --noEmit -p src/virtual",
|
||||
"test": "buildc --deps-only -- vitest",
|
||||
"test:e2e": "buildc --deps-only -- vitest -r e2e",
|
||||
"sync-releases": "pnpx changelogen@latest gh release"
|
||||
"test:coverage": "pnpm test -- run --coverage",
|
||||
"sync-releases": "pnpx changelogen@latest gh release",
|
||||
"prepack": "pnpm build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aklinker1/rollup-plugin-visualizer": "5.12.0",
|
||||
@@ -106,16 +90,16 @@
|
||||
"@webext-core/fake-browser": "^1.3.1",
|
||||
"@webext-core/isolated-element": "^1.1.2",
|
||||
"@webext-core/match-patterns": "^1.0.3",
|
||||
"async-mutex": "^0.4.1",
|
||||
"async-mutex": "^0.5.0",
|
||||
"c12": "^1.11.1",
|
||||
"cac": "^6.7.14",
|
||||
"chokidar": "^3.6.0",
|
||||
"ci-info": "^4.0.0",
|
||||
"defu": "^6.1.4",
|
||||
"dequal": "^2.0.3",
|
||||
"esbuild": "^0.19.12",
|
||||
"esbuild": "^0.23.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"filesize": "^10.1.2",
|
||||
"filesize": "^10.1.4",
|
||||
"fs-extra": "^11.2.0",
|
||||
"get-port": "^7.1.0",
|
||||
"giget": "^1.2.3",
|
||||
@@ -126,39 +110,50 @@
|
||||
"jszip": "^3.10.1",
|
||||
"linkedom": "^0.18.4",
|
||||
"magicast": "^0.3.4",
|
||||
"minimatch": "^9.0.5",
|
||||
"minimatch": "^10.0.1",
|
||||
"natural-compare": "^1.4.0",
|
||||
"normalize-path": "^3.0.0",
|
||||
"nypm": "^0.3.9",
|
||||
"ohash": "^1.1.3",
|
||||
"open": "^10.1.0",
|
||||
"ora": "^7.0.1",
|
||||
"ora": "^8.0.1",
|
||||
"picocolors": "^1.0.1",
|
||||
"prompts": "^2.4.2",
|
||||
"publish-browser-extension": "^2.1.3",
|
||||
"unimport": "^3.7.2",
|
||||
"vite": "^5.3.2",
|
||||
"vite-node": "^1.6.0",
|
||||
"unimport": "^3.9.0",
|
||||
"vite": "^5.3.4",
|
||||
"vite-node": "^2.0.0",
|
||||
"web-ext-run": "^0.2.1",
|
||||
"webextension-polyfill": "^0.10.0"
|
||||
"webextension-polyfill": "^0.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"@faker-js/faker": "^8.4.1",
|
||||
"@types/chrome": "^0.0.268",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/lodash.merge": "^4.6.9",
|
||||
"@types/natural-compare": "^1.4.3",
|
||||
"@types/node": "^20.14.9",
|
||||
"@types/node": "^20.14.11",
|
||||
"@types/normalize-path": "^3.0.2",
|
||||
"@types/prompts": "^2.4.9",
|
||||
"execa": "^9.3.0",
|
||||
"extract-zip": "^2.0.1",
|
||||
"happy-dom": "^13.10.1",
|
||||
"happy-dom": "^14.12.3",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"p-map": "^7.0.2",
|
||||
"publint": "^0.2.8",
|
||||
"tsup": "^8.1.0",
|
||||
"publint": "^0.2.9",
|
||||
"tsx": "4.15.7",
|
||||
"typescript": "^5.5.2"
|
||||
"typescript": "^5.5.3",
|
||||
"unbuild": "^2.0.0",
|
||||
"vitest": "^2.0.3",
|
||||
"vitest-plugin-random-seed": "^1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/chrome": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/chrome": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
import tsup from 'tsup';
|
||||
import glob from 'fast-glob';
|
||||
import { printFileList } from '~/core/utils/log';
|
||||
import { formatDuration } from '~/core/utils/time';
|
||||
import ora from 'ora';
|
||||
import fs from 'fs-extra';
|
||||
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();
|
||||
|
||||
const startTime = Date.now();
|
||||
const outDir = 'dist';
|
||||
await fs.rm(path.join(outDir, '*'), { recursive: true, force: true });
|
||||
|
||||
const preset = {
|
||||
dts: true,
|
||||
silent: true,
|
||||
sourcemap: false,
|
||||
external: [
|
||||
...virtualEntrypointModuleNames.map((name) => `virtual:user-${name}`),
|
||||
'virtual:wxt-plugins',
|
||||
'virtual:app-config',
|
||||
],
|
||||
} satisfies tsup.Options;
|
||||
|
||||
function spinnerPMap(configs: tsup.Options[]) {
|
||||
let progress = 1;
|
||||
const updateSpinner = () => {
|
||||
spinner.text = `${spinnerText} [${progress}/${configs.length}]`;
|
||||
};
|
||||
updateSpinner();
|
||||
|
||||
return pMap(
|
||||
config,
|
||||
async (config) => {
|
||||
const res = await tsup.build(config);
|
||||
progress++;
|
||||
updateSpinner();
|
||||
return res;
|
||||
},
|
||||
{
|
||||
stopOnError: true,
|
||||
concurrency: process.env.CI === 'true' ? os.cpus().length : Infinity,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const config: tsup.Options[] = [
|
||||
// CJS/ESM
|
||||
{
|
||||
...preset,
|
||||
entry: {
|
||||
index: 'src/index.ts',
|
||||
testing: 'src/testing/index.ts',
|
||||
storage: 'src/storage.ts',
|
||||
modules: 'src/modules.ts',
|
||||
},
|
||||
format: ['cjs', 'esm'],
|
||||
clean: true,
|
||||
},
|
||||
// ESM-only
|
||||
{
|
||||
...preset,
|
||||
entry: {
|
||||
browser: 'src/browser.ts',
|
||||
sandbox: 'src/sandbox/index.ts',
|
||||
client: 'src/client/index.ts',
|
||||
},
|
||||
format: ['esm'],
|
||||
},
|
||||
{
|
||||
...preset,
|
||||
entry: virtualModuleNames.reduce<Record<string, string>>(
|
||||
(acc, moduleName) => {
|
||||
acc[`virtual/${moduleName}`] = `src/virtual/${moduleName}.ts`;
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
),
|
||||
format: ['esm'],
|
||||
splitting: false,
|
||||
dts: false,
|
||||
external: [...preset.external, 'wxt'],
|
||||
},
|
||||
// CJS-only
|
||||
{
|
||||
...preset,
|
||||
entry: {
|
||||
cli: 'src/cli/index.ts',
|
||||
},
|
||||
format: ['esm'],
|
||||
banner: {
|
||||
// Fixes dynamic require of nodejs modules. See https://github.com/wxt-dev/wxt/issues/355
|
||||
// https://github.com/evanw/esbuild/issues/1921#issuecomment-1152991694
|
||||
js: "import { createRequire } from 'module';const require = createRequire(import.meta.url);",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
await spinnerPMap(config).catch((err) => {
|
||||
spinner.fail();
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Copy "public" files that need shipped inside WXT
|
||||
await fs.copyFile('src/vite-builder-env.d.ts', 'dist/vite-builder-env.d.ts');
|
||||
|
||||
spinner.clear().stop();
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
const outFiles = await glob(`${outDir}/**`, { absolute: true });
|
||||
await printFileList(
|
||||
consola.success,
|
||||
`Built WXT in ${formatDuration(duration)}`,
|
||||
outDir,
|
||||
outFiles,
|
||||
);
|
||||
@@ -49,8 +49,3 @@ declare module 'web-ext-run/util/logger' {
|
||||
}
|
||||
export const consoleStream: IConsoleStream;
|
||||
}
|
||||
|
||||
declare module 'wxt/browser' {
|
||||
// Overridden when types are generated per project
|
||||
export type PublicPath = string;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { fakeWxt } from '~/core/utils/testing/fake-objects';
|
||||
import { fakeWxt } from '../core/utils/testing/fake-objects';
|
||||
import { addImportPreset, addViteConfig } from '../modules';
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { createHooks } from 'hookable';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { fakeBrowser } from '@webext-core/fake-browser';
|
||||
import { describe, it, expect, beforeEach, vi, expectTypeOf } from 'vitest';
|
||||
import { browser } from '~/browser';
|
||||
import { WxtStorageItem, storage } from '~/storage';
|
||||
import { browser } from 'wxt/browser';
|
||||
import { WxtStorageItem, storage } from '../storage';
|
||||
|
||||
/**
|
||||
* This works because fakeBrowser is synchronous, and is will finish any number of chained
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/// <reference types="chrome" />
|
||||
/**
|
||||
* EXPERIMENTAL
|
||||
*
|
||||
* Includes the `chrome` API and types when using `extensionApi: 'chrome'`.
|
||||
*
|
||||
* @module wxt/browser/chrome
|
||||
*/
|
||||
|
||||
export interface WxtRuntime {
|
||||
// Overriden per-project
|
||||
}
|
||||
export interface WxtI18n {
|
||||
// Overriden per-project
|
||||
}
|
||||
|
||||
export type Chrome = typeof chrome;
|
||||
export type WxtBrowser = Omit<Chrome, 'runtime' | 'i18n'> & {
|
||||
runtime: WxtRuntime & Omit<Chrome['runtime'], 'getURL'>;
|
||||
i18n: WxtI18n & Omit<Chrome['i18n'], 'getMessage'>;
|
||||
};
|
||||
|
||||
export const browser: WxtBrowser =
|
||||
// @ts-expect-error
|
||||
globalThis.browser?.runtime?.id == null
|
||||
? globalThis.chrome
|
||||
: // @ts-expect-error
|
||||
globalThis.browser;
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* @module wxt/browser
|
||||
*/
|
||||
export * from './webextension-polyfill';
|
||||
@@ -1,6 +1,9 @@
|
||||
/**
|
||||
* @module wxt/browser
|
||||
* Includes the `browser` API and types when using `extensionApi: 'webextension-polyfill'` (the default).
|
||||
*
|
||||
* @module wxt/browser/webextension-polyfill
|
||||
*/
|
||||
|
||||
import originalBrowser, { Browser, Runtime, I18n } from 'webextension-polyfill';
|
||||
|
||||
export interface AugmentedBrowser extends Browser {
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WxtModule } from '~/types';
|
||||
import { WxtModule } from '../types';
|
||||
import unimport from './unimport';
|
||||
|
||||
export const builtinModules: WxtModule<any>[] = [unimport];
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { addViteConfig, defineWxtModule } from '~/modules';
|
||||
import { addViteConfig, defineWxtModule } from '../modules';
|
||||
import type {
|
||||
EslintGlobalsPropValue,
|
||||
WxtDirFileEntry,
|
||||
WxtModule,
|
||||
WxtResolvedUnimportOptions,
|
||||
} from '~/types';
|
||||
} from '../types';
|
||||
import { type Unimport, createUnimport } from 'unimport';
|
||||
import { Plugin } from 'vite';
|
||||
import { extname } from 'node:path';
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
import { describe, it, vi, beforeEach, expect } from 'vitest';
|
||||
import { build } from '~/core/build';
|
||||
import { createServer } from '~/core/create-server';
|
||||
import { zip } from '~/core/zip';
|
||||
import { prepare } from '~/core/prepare';
|
||||
import { clean } from '~/core/clean';
|
||||
import { initialize } from '~/core/initialize';
|
||||
import { build } from '../../core/build';
|
||||
import { createServer } from '../../core/create-server';
|
||||
import { zip } from '../../core/zip';
|
||||
import { prepare } from '../../core/prepare';
|
||||
import { clean } from '../../core/clean';
|
||||
import { initialize } from '../../core/initialize';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import consola from 'consola';
|
||||
|
||||
vi.mock('~/core/build');
|
||||
vi.mock('../../core/build');
|
||||
const buildMock = vi.mocked(build);
|
||||
|
||||
vi.mock('~/core/create-server');
|
||||
vi.mock('../../core/create-server');
|
||||
const createServerMock = vi.mocked(createServer);
|
||||
|
||||
vi.mock('~/core/zip');
|
||||
vi.mock('../../core/zip');
|
||||
const zipMock = vi.mocked(zip);
|
||||
|
||||
vi.mock('~/core/prepare');
|
||||
vi.mock('../../core/prepare');
|
||||
const prepareMock = vi.mocked(prepare);
|
||||
|
||||
vi.mock('~/core/clean');
|
||||
vi.mock('../../core/clean');
|
||||
const cleanMock = vi.mocked(clean);
|
||||
|
||||
vi.mock('~/core/initialize');
|
||||
vi.mock('../../core/initialize');
|
||||
const initializeMock = vi.mocked(initialize);
|
||||
|
||||
consola.wrapConsole();
|
||||
@@ -35,7 +35,7 @@ function mockArgv(...args: string[]) {
|
||||
}
|
||||
|
||||
async function importCli() {
|
||||
await import('~/cli');
|
||||
await import('../../cli');
|
||||
}
|
||||
|
||||
describe('CLI', () => {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
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';
|
||||
import { registerWxt } from '~/core/wxt';
|
||||
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';
|
||||
import { registerWxt } from '../core/wxt';
|
||||
|
||||
/**
|
||||
* Wrap an action handler to add a timer, error handling, and maybe enable debug mode.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import cac from 'cac';
|
||||
import { build, clean, createServer, initialize, prepare, zip } from '~/core';
|
||||
import { build, clean, createServer, initialize, prepare, zip } from '../core';
|
||||
import {
|
||||
createAliasedCommand,
|
||||
getArrayFromFlags,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import cli from './commands';
|
||||
import { version } from '~/version';
|
||||
import { version } from '../version';
|
||||
import { isAliasedCommand } from './cli-utils';
|
||||
|
||||
// TODO: Remove. See https://github.com/wxt-dev/wxt/issues/277
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @ts-expect-error: Untyped virtual module
|
||||
import appConfig from 'virtual:app-config';
|
||||
import type { WxtAppConfig } from '~/sandbox/define-app-config';
|
||||
import type { WxtAppConfig } from '../sandbox/define-app-config';
|
||||
|
||||
export function useAppConfig(): WxtAppConfig {
|
||||
return appConfig;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ContentScriptDefinition } from '~/types';
|
||||
import { browser } from '~/browser';
|
||||
import { logger } from '~/sandbox/utils/logger';
|
||||
import { ContentScriptDefinition } from '../../types';
|
||||
import { browser } from 'wxt/browser';
|
||||
import { logger } from '../../sandbox/utils/logger';
|
||||
import { WxtLocationChangeEvent, getUniqueEventName } from './custom-events';
|
||||
import { createLocationWatcher } from './location-watcher';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { browser } from '~/browser';
|
||||
import { browser } from 'wxt/browser';
|
||||
|
||||
export class WxtLocationChangeEvent extends Event {
|
||||
static EVENT_NAME = getUniqueEventName('wxt:locationchange');
|
||||
@@ -22,5 +22,5 @@ export function getUniqueEventName(eventName: string): string {
|
||||
? 'build'
|
||||
: import.meta.env.ENTRYPOINT;
|
||||
|
||||
return `${browser.runtime.id}:${entrypointName}:${eventName}`;
|
||||
return `${browser?.runtime?.id}:${entrypointName}:${eventName}`;
|
||||
}
|
||||
|
||||
@@ -252,6 +252,24 @@ describe('Content Script UIs', () => {
|
||||
document.querySelector('#parent > div[data-wxt-integrated]'),
|
||||
).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should append the element using an XPath string', () => {
|
||||
vi.stubGlobal('XPathResult', { FIRST_ORDERED_NODE_TYPE: 9 });
|
||||
document.evaluate = vi.fn().mockReturnValue({
|
||||
singleNodeValue: document.querySelector('#three'),
|
||||
});
|
||||
|
||||
const ui = createIntegratedUi(ctx, {
|
||||
position: 'inline',
|
||||
onMount: appendTestApp,
|
||||
anchor: '//p[@id="three"]',
|
||||
});
|
||||
ui.mount();
|
||||
|
||||
expect(
|
||||
document.querySelector('#three > div[data-wxt-integrated]'),
|
||||
).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Element', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { browser } from '~/browser';
|
||||
import { browser } from 'wxt/browser';
|
||||
import { ContentScriptContext } from '..';
|
||||
import {
|
||||
ContentScriptAnchoredOptions,
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
ShadowRootContentScriptUi,
|
||||
ShadowRootContentScriptUiOptions,
|
||||
} from './types';
|
||||
import { logger } from '~/sandbox/utils/logger';
|
||||
import { logger } from '../../../sandbox/utils/logger';
|
||||
import { createIsolatedElement } from '@webext-core/isolated-element';
|
||||
export * from './types';
|
||||
|
||||
@@ -199,8 +199,25 @@ function getAnchor(options: ContentScriptAnchoredOptions): Element | undefined {
|
||||
|
||||
let resolved =
|
||||
typeof options.anchor === 'function' ? options.anchor() : options.anchor;
|
||||
if (typeof resolved === 'string')
|
||||
return document.querySelector<Element>(resolved) ?? undefined;
|
||||
|
||||
if (typeof resolved === 'string') {
|
||||
// If the string is an XPath expression (starts with '//' or '/')
|
||||
if (resolved.startsWith('/')) {
|
||||
// Evaluate the XPath and return the first ordered node
|
||||
const result = document.evaluate(
|
||||
resolved,
|
||||
document,
|
||||
null,
|
||||
XPathResult.FIRST_ORDERED_NODE_TYPE,
|
||||
null,
|
||||
);
|
||||
return (result.singleNodeValue as Element) ?? undefined;
|
||||
} else {
|
||||
// If the string is a CSS selector, query the document and return the element
|
||||
return document.querySelector<Element>(resolved) ?? undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return resolved ?? undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ export type ContentScriptPositioningOptions =
|
||||
|
||||
export interface ContentScriptAnchoredOptions {
|
||||
/**
|
||||
* A CSS selector, element, or function that returns one of the two. Along with `append`, the
|
||||
* A CSS selector, XPath expression, element, or function that returns one of the three. Along with `append`, the
|
||||
* `anchor` dictates where in the page the UI will be added.
|
||||
*/
|
||||
anchor?:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BuildOutput, InlineConfig } from '~/types';
|
||||
import { BuildOutput, InlineConfig } from '../types';
|
||||
import { internalBuild } from './utils/building';
|
||||
import { registerWxt } from './wxt';
|
||||
|
||||
|
||||
@@ -7,20 +7,20 @@ import {
|
||||
WxtBuilderServer,
|
||||
WxtDevServer,
|
||||
WxtHooks,
|
||||
} from '~/types';
|
||||
} from '../../../types';
|
||||
import * as wxtPlugins from './plugins';
|
||||
import {
|
||||
getEntrypointBundlePath,
|
||||
isHtmlEntrypoint,
|
||||
} from '~/core/utils/entrypoints';
|
||||
} from '../../utils/entrypoints';
|
||||
import {
|
||||
VirtualEntrypointType,
|
||||
VirtualModuleId,
|
||||
} from '~/core/utils/virtual-modules';
|
||||
} from '../../utils/virtual-modules';
|
||||
import { Hookable } from 'hookable';
|
||||
import { toArray } from '~/core/utils/arrays';
|
||||
import { safeVarName } from '~/core/utils/strings';
|
||||
import { importEntrypointFile } from '~/core/utils/building';
|
||||
import { toArray } from '../../utils/arrays';
|
||||
import { safeVarName } from '../../utils/strings';
|
||||
import { importEntrypointFile } from '../../utils/building';
|
||||
import { ViteNodeServer } from 'vite-node/server';
|
||||
import { ViteNodeRunner } from 'vite-node/client';
|
||||
import { installSourcemapsSupport } from 'vite-node/source-map';
|
||||
@@ -66,7 +66,7 @@ export async function createViteBuilder(
|
||||
wxtPlugins.tsconfigPaths(wxtConfig),
|
||||
wxtPlugins.noopBackground(),
|
||||
wxtPlugins.globals(wxtConfig),
|
||||
wxtPlugins.excludeBrowserPolyfill(wxtConfig),
|
||||
wxtPlugins.resolveExtensionApi(wxtConfig),
|
||||
wxtPlugins.defineImportMeta(),
|
||||
wxtPlugins.wxtPluginLoader(wxtConfig),
|
||||
wxtPlugins.resolveAppConfig(wxtConfig),
|
||||
@@ -218,7 +218,7 @@ export async function createViteBuilder(
|
||||
const baseConfig = await getBaseConfig();
|
||||
const envConfig: vite.InlineConfig = {
|
||||
plugins: [
|
||||
wxtPlugins.webextensionPolyfillMock(wxtConfig),
|
||||
wxtPlugins.extensionApiMock(wxtConfig),
|
||||
wxtPlugins.removeEntrypointMainFunction(wxtConfig, path),
|
||||
],
|
||||
};
|
||||
@@ -238,7 +238,7 @@ export async function createViteBuilder(
|
||||
baseConfig.optimizeDeps.include = [];
|
||||
const envConfig: vite.InlineConfig = {
|
||||
plugins: [
|
||||
wxtPlugins.webextensionPolyfillMock(wxtConfig),
|
||||
wxtPlugins.extensionApiMock(wxtConfig),
|
||||
wxtPlugins.removeEntrypointMainFunction(wxtConfig, path),
|
||||
],
|
||||
};
|
||||
|
||||
@@ -4,8 +4,8 @@ import { pointToDevServer } from '../devHtmlPrerender';
|
||||
import {
|
||||
fakeDevServer,
|
||||
fakeResolvedConfig,
|
||||
} from '~/core/utils/testing/fake-objects';
|
||||
import { normalizePath } from '~/core/utils/paths';
|
||||
} from '../../../../utils/testing/fake-objects';
|
||||
import { normalizePath } from '../../../../utils/paths';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
describe('Dev HTML Prerender Plugin', () => {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import type * as vite from 'vite';
|
||||
import { visualizer } from '@aklinker1/rollup-plugin-visualizer';
|
||||
import { ResolvedConfig } from '~/types';
|
||||
import { ResolvedConfig } from '../../../../types';
|
||||
import path from 'node:path';
|
||||
|
||||
let increment = 0;
|
||||
|
||||
export function bundleAnalysis(config: ResolvedConfig): vite.Plugin {
|
||||
// @ts-expect-error: Vite version mismatch
|
||||
return visualizer({
|
||||
template: 'raw-data',
|
||||
filename: path.resolve(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type * as vite from 'vite';
|
||||
import { Entrypoint, ResolvedConfig } from '~/types';
|
||||
import { getEntrypointBundlePath } from '~/core/utils/entrypoints';
|
||||
import { Entrypoint, ResolvedConfig } from '../../../../types';
|
||||
import { getEntrypointBundlePath } from '../../../utils/entrypoints';
|
||||
|
||||
/**
|
||||
* Rename CSS entrypoint outputs to ensure a JS file is not generated, and that the CSS file is
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type * as vite from 'vite';
|
||||
import { ResolvedConfig, WxtDevServer } from '~/types';
|
||||
import { getEntrypointName } from '~/core/utils/entrypoints';
|
||||
import { ResolvedConfig, WxtDevServer } from '../../../../types';
|
||||
import { getEntrypointName } from '../../../utils/entrypoints';
|
||||
import { parseHTML } from 'linkedom';
|
||||
import { dirname, relative, resolve } from 'node:path';
|
||||
import { normalizePath } from '~/core/utils/paths';
|
||||
import { normalizePath } from '../../../utils/paths';
|
||||
import { murmurHash } from 'ohash';
|
||||
|
||||
// Stored outside the plugin to effect all instances of the devHtmlPrerender plugin.
|
||||
@@ -19,7 +19,7 @@ export function devHtmlPrerender(
|
||||
const htmlReloadId = '@wxt/reload-html';
|
||||
const resolvedHtmlReloadId = resolve(
|
||||
config.wxtModuleDir,
|
||||
'dist/virtual/reload-html.js',
|
||||
'dist/virtual/reload-html.mjs',
|
||||
);
|
||||
|
||||
const virtualInlineScript = 'virtual:wxt-inline-script';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Plugin } from 'vite';
|
||||
import { ResolvedConfig, WxtDevServer } from '~/types';
|
||||
import { ResolvedConfig, WxtDevServer } from '../../../../types';
|
||||
|
||||
/**
|
||||
* Defines global constants about the dev server. Helps scripts connect to the server's web socket.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Plugin } from 'vite';
|
||||
import { ResolvedConfig } from '~/types';
|
||||
import { fetchCached } from '~/core/utils/network';
|
||||
import { ResolvedConfig } from '../../../../types';
|
||||
import { fetchCached } from '../../../utils/network';
|
||||
|
||||
/**
|
||||
* Downloads any URL imports, like Google Analytics, into virtual modules so they are bundled with
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type * as vite from 'vite';
|
||||
import { EntrypointGroup } from '~/types';
|
||||
import { getEntrypointGlobals } from '~/core/utils/globals';
|
||||
import { EntrypointGroup } from '../../../../types';
|
||||
import { getEntrypointGlobals } from '../../../utils/globals';
|
||||
|
||||
/**
|
||||
* Define a set of global variables specific to an entrypoint.
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import { ResolvedConfig } from '~/types';
|
||||
import type * as vite from 'vite';
|
||||
|
||||
/**
|
||||
* Apply the experimental config for disabling the polyfill. It works by aliasing the
|
||||
* `webextension-polyfill` module to a virtual module and exporting the `chrome` global from the
|
||||
* virtual module.
|
||||
*/
|
||||
export function excludeBrowserPolyfill(config: ResolvedConfig): vite.Plugin {
|
||||
const virtualId = 'virtual:wxt-webextension-polyfill-disabled';
|
||||
|
||||
return {
|
||||
name: 'wxt:exclude-browser-polyfill',
|
||||
config() {
|
||||
// Only apply the config if we're disabling the polyfill
|
||||
if (config.experimental.includeBrowserPolyfill) return;
|
||||
|
||||
return {
|
||||
resolve: {
|
||||
alias: {
|
||||
'webextension-polyfill': virtualId,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
load(id) {
|
||||
if (id === virtualId) {
|
||||
// Use chrome instead of the polyfill when disabled.
|
||||
return 'export default chrome';
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import path from 'node:path';
|
||||
import type * as vite from 'vite';
|
||||
import { ResolvedConfig } from '../../../../types';
|
||||
|
||||
/**
|
||||
* Mock `webextension-polyfill`, `wxt/browser`, and `wxt/browser/*` by inlining
|
||||
* all dependencies that import them and adding a custom alias so that Vite
|
||||
* resolves to a mocked version of the module.
|
||||
*
|
||||
* TODO: Detect non-wxt dependencies (like `@webext-core/*`) that import `webextension-polyfill` via
|
||||
* `npm list` and inline them automatically.
|
||||
*/
|
||||
export function extensionApiMock(config: ResolvedConfig): vite.PluginOption {
|
||||
return {
|
||||
name: 'wxt:extension-api-mock',
|
||||
config() {
|
||||
const replacement = path.resolve(
|
||||
config.wxtModuleDir,
|
||||
'dist/virtual/mock-browser',
|
||||
);
|
||||
return {
|
||||
resolve: {
|
||||
alias: [
|
||||
{ find: 'webextension-polyfill', replacement },
|
||||
// wxt/browser, wxt/browser/...
|
||||
{ find: /^wxt\/browser.*/, replacement },
|
||||
],
|
||||
},
|
||||
ssr: {
|
||||
// Inline all WXT modules so vite processes them so the aliases can
|
||||
// be resolved
|
||||
noExternal: ['wxt'],
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import type * as vite from 'vite';
|
||||
import { ResolvedConfig } from '~/types';
|
||||
import { getGlobals } from '~/core/utils/globals';
|
||||
import { ResolvedConfig } from '../../../../types';
|
||||
import { getGlobals } from '../../../utils/globals';
|
||||
|
||||
export function globals(config: ResolvedConfig): vite.PluginOption {
|
||||
return {
|
||||
|
||||
@@ -8,8 +8,8 @@ export * from './noopBackground';
|
||||
export * from './cssEntrypoints';
|
||||
export * from './bundleAnalysis';
|
||||
export * from './globals';
|
||||
export * from './webextensionPolyfillMock';
|
||||
export * from './excludeBrowserPolyfill';
|
||||
export * from './extensionApiMock';
|
||||
export * from './resolveExtensionApi';
|
||||
export * from './entrypointGroupGlobals';
|
||||
export * from './defineImportMeta';
|
||||
export * from './removeEntrypointMainFunction';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type * as vite from 'vite';
|
||||
import { Entrypoint, ResolvedConfig } from '~/types';
|
||||
import { Entrypoint, ResolvedConfig } from '../../../../types';
|
||||
import { dirname, extname, resolve, join } from 'node:path';
|
||||
import { getEntrypointBundlePath } from '~/core/utils/entrypoints';
|
||||
import { getEntrypointBundlePath } from '../../../utils/entrypoints';
|
||||
import fs, { ensureDir } from 'fs-extra';
|
||||
import { normalizePath } from '~/core/utils/paths';
|
||||
import { normalizePath } from '../../../utils/paths';
|
||||
|
||||
/**
|
||||
* Ensures the HTML files output by a multipage build are in the correct location. This does two
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Plugin } from 'vite';
|
||||
import { VIRTUAL_NOOP_BACKGROUND_MODULE_ID } from '~/core/utils/constants';
|
||||
import { VIRTUAL_NOOP_BACKGROUND_MODULE_ID } from '../../../utils/constants';
|
||||
|
||||
/**
|
||||
* In dev mode, if there's not a background script listed, we need to add one so that the web socket
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ResolvedConfig } from '~/types';
|
||||
import { ResolvedConfig } from '../../../../types';
|
||||
import * as vite from 'vite';
|
||||
import { normalizePath } from '~/core/utils/paths';
|
||||
import { removeMainFunctionCode } from '~/core/utils/transform';
|
||||
import { normalizePath } from '../../../utils/paths';
|
||||
import { removeMainFunctionCode } from '../../../utils/transform';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { exists } from 'fs-extra';
|
||||
import { resolve } from 'node:path';
|
||||
import type * as vite from 'vite';
|
||||
import { ResolvedConfig } from '~/types';
|
||||
import { ResolvedConfig } from '../../../../types';
|
||||
|
||||
/**
|
||||
* When importing `virtual:app-config`, resolve it to the `app.config.ts` file in the project.
|
||||
@@ -13,6 +13,15 @@ export function resolveAppConfig(config: ResolvedConfig): vite.Plugin {
|
||||
|
||||
return {
|
||||
name: 'wxt:resolve-app-config',
|
||||
config() {
|
||||
return {
|
||||
optimizeDeps: {
|
||||
// Prevent ESBuild from attempting to resolve the virtual module
|
||||
// while optimizing WXT.
|
||||
exclude: [virtualModuleId],
|
||||
},
|
||||
};
|
||||
},
|
||||
async resolveId(id) {
|
||||
if (id !== virtualModuleId) return;
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ResolvedConfig } from '../../../../types';
|
||||
import type * as vite from 'vite';
|
||||
|
||||
/**
|
||||
* Apply the experimental config for which extension API is used. This only
|
||||
* effects the extension API included at RUNTIME - during development, types
|
||||
* depend on the import.
|
||||
*
|
||||
* NOTE: this only works if we import `wxt/browser` instead of using the relative path.
|
||||
*/
|
||||
export function resolveExtensionApi(config: ResolvedConfig): vite.Plugin {
|
||||
return {
|
||||
name: 'wxt:resolve-extension-api',
|
||||
config() {
|
||||
// Only apply the config if we're disabling the polyfill
|
||||
if (config.extensionApi === 'webextension-polyfill') return;
|
||||
|
||||
return {
|
||||
resolve: {
|
||||
alias: [
|
||||
{ find: /^wxt\/browser$/, replacement: 'wxt/browser/chrome' },
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Plugin } from 'vite';
|
||||
import { ResolvedConfig } from '~/types';
|
||||
import { normalizePath } from '~/core/utils/paths';
|
||||
import { ResolvedConfig } from '../../../../types';
|
||||
import { normalizePath } from '../../../utils/paths';
|
||||
import {
|
||||
VirtualModuleId,
|
||||
virtualModuleNames,
|
||||
} from '~/core/utils/virtual-modules';
|
||||
} from '../../../utils/virtual-modules';
|
||||
import fs from 'fs-extra';
|
||||
import { resolve } from 'path';
|
||||
|
||||
@@ -31,7 +31,7 @@ export function resolveVirtualModules(config: ResolvedConfig): Plugin[] {
|
||||
|
||||
const inputPath = id.replace(resolvedVirtualId, '');
|
||||
const template = await fs.readFile(
|
||||
resolve(config.wxtModuleDir, `dist/virtual/${name}.js`),
|
||||
resolve(config.wxtModuleDir, `dist/virtual/${name}.mjs`),
|
||||
'utf-8',
|
||||
);
|
||||
return template.replace(`virtual:user-${name}`, inputPath);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ResolvedConfig } from '~/types';
|
||||
import { ResolvedConfig } from '../../../../types';
|
||||
import type * as vite from 'vite';
|
||||
|
||||
export function tsconfigPaths(config: ResolvedConfig): vite.Plugin {
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import path from 'node:path';
|
||||
import type * as vite from 'vite';
|
||||
import { ResolvedConfig } from '~/types';
|
||||
|
||||
/**
|
||||
* Mock `webextension-polyfill` by inlining all dependencies that import it and adding a custom
|
||||
* alias so that Vite resolves to a mocked version of the module.
|
||||
*
|
||||
* There are two ways to mark a module as inline:
|
||||
* 1. Use partial file paths ("wxt/dist/browser.js") in the `test.server.deps.inline` option.
|
||||
* 2. Use module names ("wxt" or "@webext-core/messaging") in the `ssr.noExternalize` option.
|
||||
*
|
||||
* This plugin uses the second approach since it's a little more intuative to understand.
|
||||
*
|
||||
* TODO: Detect non-wxt dependencies (like `@webext-core/*`) that import `webextension-polyfill` via
|
||||
* `npm list` and inline them automatically.
|
||||
*/
|
||||
export function webextensionPolyfillMock(
|
||||
config: ResolvedConfig,
|
||||
): vite.PluginOption {
|
||||
return {
|
||||
name: 'wxt:testing-inline-deps',
|
||||
config() {
|
||||
return {
|
||||
resolve: {
|
||||
alias: {
|
||||
// Alias to use a mocked version of the polyfill
|
||||
'webextension-polyfill': path.resolve(
|
||||
config.wxtModuleDir,
|
||||
'dist/virtual/mock-browser',
|
||||
),
|
||||
},
|
||||
},
|
||||
ssr: {
|
||||
// Inline all WXT modules
|
||||
noExternal: ['wxt'],
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { parseHTML } from 'linkedom';
|
||||
import type * as vite from 'vite';
|
||||
import { normalizePath } from '~/core/utils/paths';
|
||||
import { ResolvedConfig } from '~/types';
|
||||
import { normalizePath } from '../../../utils/paths';
|
||||
import { ResolvedConfig } from '../../../../types';
|
||||
|
||||
/**
|
||||
* Resolve and load plugins for each entrypoint. This handles both JS entrypoints via the `virtual:wxt-plugins` import, and HTML files by adding `virtual:wxt-html-plugins` to the document's `<head>`
|
||||
|
||||
@@ -2,7 +2,7 @@ import path from 'node:path';
|
||||
import glob from 'fast-glob';
|
||||
import fs from 'fs-extra';
|
||||
import pc from 'picocolors';
|
||||
import { InlineConfig } from '~/types';
|
||||
import { InlineConfig } from '../types';
|
||||
import { registerWxt, wxt } from './wxt';
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,22 +4,19 @@ import {
|
||||
InlineConfig,
|
||||
ServerInfo,
|
||||
WxtDevServer,
|
||||
} from '~/types';
|
||||
import {
|
||||
getEntrypointBundlePath,
|
||||
isHtmlEntrypoint,
|
||||
} from '~/core/utils/entrypoints';
|
||||
} from '../types';
|
||||
import { getEntrypointBundlePath, isHtmlEntrypoint } from './utils/entrypoints';
|
||||
import {
|
||||
getContentScriptCssFiles,
|
||||
getContentScriptsCssMap,
|
||||
} from '~/core/utils/manifest';
|
||||
} from './utils/manifest';
|
||||
import {
|
||||
internalBuild,
|
||||
detectDevChanges,
|
||||
rebuild,
|
||||
findEntrypoints,
|
||||
} from '~/core/utils/building';
|
||||
import { createExtensionRunner } from '~/core/runners';
|
||||
} from './utils/building';
|
||||
import { createExtensionRunner } from './runners';
|
||||
import { Mutex } from 'async-mutex';
|
||||
import pc from 'picocolors';
|
||||
import { relative } from 'node:path';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UserConfig } from '~/types';
|
||||
import { UserConfig } from '../types';
|
||||
|
||||
export function defineConfig(config: UserConfig): UserConfig {
|
||||
return config;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ExtensionRunnerConfig } from '~/types';
|
||||
import { ExtensionRunnerConfig } from '../types';
|
||||
|
||||
export function defineRunnerConfig(
|
||||
config: ExtensionRunnerConfig,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
PackageManager,
|
||||
PackageManagerName,
|
||||
} from 'nypm';
|
||||
import { WxtPackageManager } from '~/types';
|
||||
import { WxtPackageManager } from '../../types';
|
||||
import { bun } from './bun';
|
||||
import { WxtPackageManagerImpl } from './types';
|
||||
import { yarn } from './yarn';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Dependency } from '~/types';
|
||||
import { Dependency } from '../../types';
|
||||
import { WxtPackageManagerImpl } from './types';
|
||||
import path from 'node:path';
|
||||
import { ensureDir } from 'fs-extra';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WxtPackageManager } from '~/types';
|
||||
import { WxtPackageManager } from '../../types';
|
||||
|
||||
export type WxtPackageManagerImpl = Pick<
|
||||
WxtPackageManager,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Dependency } from '~/types';
|
||||
import { Dependency } from '../../types';
|
||||
import { WxtPackageManagerImpl } from './types';
|
||||
import { dedupeDependencies, npm } from './npm';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { InlineConfig } from '~/types';
|
||||
import { findEntrypoints, generateTypesDir } from '~/core/utils/building';
|
||||
import { InlineConfig } from '../types';
|
||||
import { findEntrypoints, generateTypesDir } from './utils/building';
|
||||
import { registerWxt, wxt } from './wxt';
|
||||
|
||||
export async function prepare(config: InlineConfig) {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { createExtensionRunner } from '..';
|
||||
import { setFakeWxt } from '~/core/utils/testing/fake-objects';
|
||||
import { setFakeWxt } from '../../utils/testing/fake-objects';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import { createSafariRunner } from '../safari';
|
||||
import { createWslRunner } from '../wsl';
|
||||
import { createManualRunner } from '../manual';
|
||||
import { isWsl } from '../../utils/wsl';
|
||||
import { createWebExtRunner } from '../web-ext';
|
||||
import { ExtensionRunner } from '~/types';
|
||||
import { ExtensionRunner } from '../../../types';
|
||||
|
||||
vi.mock('../../utils/wsl');
|
||||
const isWslMock = vi.mocked(isWsl);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ExtensionRunner } from '~/types';
|
||||
import { ExtensionRunner } from '../../types';
|
||||
import { createWslRunner } from './wsl';
|
||||
import { createWebExtRunner } from './web-ext';
|
||||
import { createSafariRunner } from './safari';
|
||||
import { createManualRunner } from './manual';
|
||||
import { isWsl } from '~/core/utils/wsl';
|
||||
import { isWsl } from '../utils/wsl';
|
||||
import { wxt } from '../wxt';
|
||||
|
||||
export async function createExtensionRunner(): Promise<ExtensionRunner> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ExtensionRunner } from '~/types';
|
||||
import { ExtensionRunner } from '../../types';
|
||||
import { relative } from 'node:path';
|
||||
import { wxt } from '../wxt';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ExtensionRunner } from '~/types';
|
||||
import { ExtensionRunner } from '../../types';
|
||||
import { relative } from 'node:path';
|
||||
import { wxt } from '../wxt';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { WebExtRunInstance } from 'web-ext-run';
|
||||
import { ExtensionRunner } from '~/types';
|
||||
import { ExtensionRunner } from '../../types';
|
||||
import { formatDuration } from '../utils/time';
|
||||
import defu from 'defu';
|
||||
import { wxt } from '../wxt';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ExtensionRunner } from '~/types';
|
||||
import { ExtensionRunner } from '../../types';
|
||||
import { relative } from 'node:path';
|
||||
import { wxt } from '../wxt';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { every, some } from '~/core/utils/arrays';
|
||||
import { every, some } from '../arrays';
|
||||
|
||||
describe('Array Utils', () => {
|
||||
describe('every', () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it, beforeEach } from 'vitest';
|
||||
import { hashContentScriptOptions } from '~/core/utils/content-scripts';
|
||||
import { setFakeWxt } from '~/core/utils/testing/fake-objects';
|
||||
import { hashContentScriptOptions } from '../content-scripts';
|
||||
import { setFakeWxt } from '../testing/fake-objects';
|
||||
|
||||
describe('Content Script Utils', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { ContentSecurityPolicy } from '~/core/utils/content-security-policy';
|
||||
import { ContentSecurityPolicy } from '../content-security-policy';
|
||||
|
||||
describe('Content Security Policy Builder', () => {
|
||||
it('should add values to new directives correctly', () => {
|
||||
|
||||
@@ -3,8 +3,8 @@ import {
|
||||
getEntrypointName,
|
||||
getEntrypointOutputFile,
|
||||
resolvePerBrowserOption,
|
||||
} from '~/core/utils/entrypoints';
|
||||
import { Entrypoint } from '~/types';
|
||||
} from '../entrypoints';
|
||||
import { Entrypoint } from '../../../types';
|
||||
import { resolve } from 'path';
|
||||
|
||||
describe('Entrypoint Utils', () => {
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
ContentScriptEntrypoint,
|
||||
Entrypoint,
|
||||
OutputAsset,
|
||||
} from '~/types';
|
||||
} from '../../../types';
|
||||
import { wxt } from '../../wxt';
|
||||
|
||||
const outDir = '/output';
|
||||
|
||||
@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vitest';
|
||||
import { getPackageJson } from '../package';
|
||||
import { setFakeWxt } from '../testing/fake-objects';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import { Logger } from '~/types';
|
||||
import { Logger } from '../../../types';
|
||||
import { WXT_PACKAGE_DIR } from '../../../../e2e/utils';
|
||||
|
||||
describe('Package JSON Utils', () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
import { DevModeChange, detectDevChanges } from '~/core/utils/building';
|
||||
import { DevModeChange, detectDevChanges } from '../../../utils/building';
|
||||
import {
|
||||
fakeBackgroundEntrypoint,
|
||||
fakeContentScriptEntrypoint,
|
||||
@@ -12,8 +12,8 @@ import {
|
||||
fakeOutputChunk,
|
||||
fakeWxt,
|
||||
setFakeWxt,
|
||||
} from '~/core/utils/testing/fake-objects';
|
||||
import { BuildOutput, BuildStepOutput } from '~/types';
|
||||
} from '../../../utils/testing/fake-objects';
|
||||
import { BuildOutput, BuildStepOutput } from '../../../../types';
|
||||
import { setWxtForTesting } from '../../../wxt';
|
||||
|
||||
describe('Detect Dev Changes', () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
OptionsEntrypoint,
|
||||
PopupEntrypoint,
|
||||
SidepanelEntrypoint,
|
||||
} from '~/types';
|
||||
} from '../../../../types';
|
||||
import { resolve } from 'path';
|
||||
import { findEntrypoints } from '../find-entrypoints';
|
||||
import fs from 'fs-extra';
|
||||
@@ -16,9 +16,9 @@ import glob from 'fast-glob';
|
||||
import {
|
||||
fakeResolvedConfig,
|
||||
setFakeWxt,
|
||||
} from '~/core/utils/testing/fake-objects';
|
||||
import { unnormalizePath } from '~/core/utils/paths';
|
||||
import { wxt } from '~/core/wxt';
|
||||
} from '../../../utils/testing/fake-objects';
|
||||
import { unnormalizePath } from '../../../utils/paths';
|
||||
import { wxt } from '../../../wxt';
|
||||
|
||||
vi.mock('fast-glob');
|
||||
const globMock = vi.mocked(glob);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user