diff --git a/docs/guide/essentials/config/auto-imports.md b/docs/guide/essentials/config/auto-imports.md index 63bcc3dc..3619eb5c 100644 --- a/docs/guide/essentials/config/auto-imports.md +++ b/docs/guide/essentials/config/auto-imports.md @@ -11,19 +11,7 @@ export default defineConfig({ }); ``` -By default, WXT sets up auto-imports for all of it's own APIs: - -- [`browser`](/api/reference/wxt/browser/variables/browser) from `wxt/browser` -- [`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` -- [`createIntegratedUi`](/api/reference/wxt/client/functions/createIntegratedUi) from `wxt/client` -- [`createShadowRootUi`](/api/reference/wxt/client/functions/createShadowRootUi) from `wxt/client` -- [`createIframeUi`](/api/reference/wxt/client/functions/createIframeUi) from `wxt/client` -- [`fakeBrowser`](/api/reference/wxt/testing/variables/fakeBrowser) from `wxt/testing` -- And more! - -WXT also adds some project directories as auto-import sources automatically: +By default, WXT automatically sets up auto-imports for all of it's own APIs and some of your project directories: - `/components/*` - `/composables/*` @@ -32,6 +20,8 @@ WXT also adds some project directories as auto-import sources automatically: All named and default exports from files in these directories are available everywhere else in your project without having to import them. +To see the complete list of auto-imported APIs, run [`wxt prepare`](/api/cli/wxt-prepare) and look at your project's `.wxt/types/imports-module.d.ts` file. + ## TypeScript For TypeScript and your editor to recognize auto-imported variables, you need to run the [`wxt prepare` command](/api/cli/wxt-prepare). @@ -110,3 +100,19 @@ export default defineConfig({ imports: false, // [!code ++] }); ``` + +## Explicit Imports (`#imports`) + +You can manually import all of WXT's APIs via the `#imports` module: + +```ts +import { + createShadowRootUi, + ContentScriptContext, + MatchPattern, +} from '#imports'; +``` + +To learn more about how the `#imports` module works, read the [related blog post](/blog/2024-12-06-using-imports-module). + +If you've disabled auto-imports, you can use `#imports` to import all of WXT's APIs from a single place. diff --git a/docs/guide/essentials/config/runtime.md b/docs/guide/essentials/config/runtime.md index 2bdd8c8a..47f3c6fd 100644 --- a/docs/guide/essentials/config/runtime.md +++ b/docs/guide/essentials/config/runtime.md @@ -5,10 +5,10 @@ Define runtime configuration in a single place, `/app.config.ts`: ```ts -import { defineAppConfig } from 'wxt/sandbox'; +import { defineAppConfig } from '#imports'; // Define types for your config -declare module 'wxt/sandbox' { +declare module 'wxt/utils/define-app-config' { export interface WxtAppConfig { theme?: 'light' | 'dark'; } @@ -26,7 +26,7 @@ This file is committed to the repo, so don't put any secrets here. Instead, use To access runtime config, WXT provides the `useAppConfig` function: ```ts -import { useAppConfig } from 'wxt/sandbox'; +import { useAppConfig } from '#imports'; console.log(useAppConfig()); // { theme: "dark" } ``` @@ -36,7 +36,7 @@ console.log(useAppConfig()); // { theme: "dark" } You can use environment variables in the `app.config.ts` file. ```ts -declare module 'wxt/sandbox' { +declare module 'wxt/utils/define-app-config' { export interface WxtAppConfig { apiKey?: string; skipWelcome: boolean; diff --git a/docs/guide/essentials/content-scripts.md b/docs/guide/essentials/content-scripts.md index f007e558..f6cede47 100644 --- a/docs/guide/essentials/content-scripts.md +++ b/docs/guide/essentials/content-scripts.md @@ -256,13 +256,13 @@ export default defineContentScript({ ::: -See the [API Reference](/api/reference/wxt/client/functions/createIntegratedUi) for the complete list of options. +See the [API Reference](/api/reference/wxt/utils/content-script-ui/functions/createIntegratedUi) for the complete list of options. ### Shadow Root Often in web extensions, you don't want your content script's CSS affecting the page, or vise-versa. The [`ShadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot) API is ideal for this. -WXT's [`createShadowRootUi`](/api/reference/wxt/client/functions/createShadowRootUi) abstracts all the `ShadowRoot` setup away, making it easy to create UIs whose styles are isolated from the page. It also supports an optional `isolateEvents` parameter to further isolate user interactions. +WXT's [`createShadowRootUi`](/api/reference/wxt/utils/content-script-ui/functions/createShadowRootUi) abstracts all the `ShadowRoot` setup away, making it easy to create UIs whose styles are isolated from the page. It also supports an optional `isolateEvents` parameter to further isolate user interactions. To use `createShadowRootUi`, follow these steps: @@ -445,7 +445,7 @@ export default defineContentScript({ ::: -See the [API Reference](/api/reference/wxt/client/functions/createShadowRootUi) for the complete list of options. +See the [API Reference](/api/reference/wxt/utils/content-script-ui/functions/createShadowRootUi) for the complete list of options. Full examples: @@ -456,7 +456,7 @@ Full examples: If you don't need to run your UI in the same frame as the content script, you can use an IFrame to host your UI instead. Since an IFrame just hosts an HTML page, **_HMR is supported_**. -WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/client/functions/createIframeUi), which simplifies setting up the IFrame. +WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/utils/content-script-ui/functions/createIframeUi), which simplifies setting up the IFrame. 1. Create an HTML page that will be loaded into your IFrame: ```html @@ -510,7 +510,7 @@ WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/client/fun }); ``` -See the [API Reference](/api/reference/wxt/client/functions/createIframeUi) for the complete list of options. +See the [API Reference](/api/reference/wxt/utils/content-script-ui/functions/createIframeUi) for the complete list of options. ## Isolated World vs Main World diff --git a/docs/guide/essentials/unit-testing.md b/docs/guide/essentials/unit-testing.md index 43f38b5a..e1acfbd4 100644 --- a/docs/guide/essentials/unit-testing.md +++ b/docs/guide/essentials/unit-testing.md @@ -71,6 +71,34 @@ describe('isLoggedIn', () => { }); ``` +### Mocking WXT APIs + +First, you need to understand how the `#imports` module works. When WXT (and vitest) sees this import during a preprocessing step, the import is replaced with multiple imports pointing to their "real" import path. + +For example, this is what your write in your source code: + +```ts +// What you write +import { injectScript, createShadowRootUi } from '#imports'; +``` + +But Vitest sees this: + +```ts +import { injectScript } from 'wxt/browser'; +import { createShadowRootUi } from 'wxt/utils/content-script-ui/shadow-root'; +``` + +So in this case, if you wanted to mock `injectScript`, you need to pass in `"wxt/utils/inject-script"`, not `"#imports"`. + +```ts +vi.mock("wxt/utils/inject-script", () => ({ + injectScript: ... +})) +``` + +Refer to your project's `.wxt/types/imports-module.d.ts` file to lookup real import paths for `#imports`. If the file doesn't exist, run [`wxt prepare`](/guide/essentials/config/typescript). + ## Other Testing Frameworks To use a different framework, you will likely have to disable auto-imports, setup import aliases, manually mock the extension APIs, and setup the test environment to support all of WXT's features that you use. diff --git a/docs/guide/essentials/wxt-modules.md b/docs/guide/essentials/wxt-modules.md index cb60cfcc..07eb495e 100644 --- a/docs/guide/essentials/wxt-modules.md +++ b/docs/guide/essentials/wxt-modules.md @@ -111,12 +111,12 @@ export default defineWxtModule({ ```ts import { defineWxtModule } from 'wxt/modules'; -import 'wxt/sandbox'; +import 'wxt/utils/define-app-config'; export interface MyModuleRuntimeOptions { // Add your runtime options here... } -declare module 'wxt/sandbox' { +declare module 'wxt/utils/define-app-config' { export interface WxtAppConfig { myModule: MyModuleOptions; } diff --git a/packages/wxt-demo/src/app.config.ts b/packages/wxt-demo/src/app.config.ts index b2b1f8b0..5240edd9 100644 --- a/packages/wxt-demo/src/app.config.ts +++ b/packages/wxt-demo/src/app.config.ts @@ -1,6 +1,6 @@ -import { defineAppConfig } from 'wxt/sandbox'; +import { defineAppConfig } from '#imports'; -declare module 'wxt/sandbox' { +declare module 'wxt/utils/define-app-config' { export interface WxtAppConfig { example: string; } diff --git a/packages/wxt/build.config.ts b/packages/wxt/build.config.ts index 48fa5ccc..4614ed32 100644 --- a/packages/wxt/build.config.ts +++ b/packages/wxt/build.config.ts @@ -1,5 +1,5 @@ import { defineBuildConfig } from 'unbuild'; -import { version } from './package.json'; +import { version, exports } from './package.json'; import { readFile, writeFile } from 'fs/promises'; import { virtualEntrypointModuleNames, @@ -32,10 +32,7 @@ export default defineBuildConfig([ ...virtualEntrypointModuleNames.map((name) => `virtual:user-${name}`), 'virtual:wxt-plugins', 'virtual:app-config', - 'wxt/browser', - 'wxt/sandbox', - 'wxt/client', - 'wxt/testing', + ...Object.keys(exports).map((path) => 'wxt' + path.slice(1)), // ./storage => wxt/storage ], })), ]); diff --git a/packages/wxt/e2e/tests/__snapshots__/auto-imports.test.ts.snap b/packages/wxt/e2e/tests/__snapshots__/auto-imports.test.ts.snap index 0000ea9c..922eeab7 100644 --- a/packages/wxt/e2e/tests/__snapshots__/auto-imports.test.ts.snap +++ b/packages/wxt/e2e/tests/__snapshots__/auto-imports.test.ts.snap @@ -15,7 +15,6 @@ exports[`Auto Imports > eslintrc > "enabled: 8" should output a JSON config file "createShadowRootUi": true, "defineAppConfig": true, "defineBackground": true, - "defineConfig": true, "defineContentScript": true, "defineUnlistedScript": true, "defineWxtPlugin": true, @@ -42,7 +41,6 @@ const globals = { "createShadowRootUi": true, "defineAppConfig": true, "defineBackground": true, - "defineConfig": true, "defineContentScript": true, "defineUnlistedScript": true, "defineWxtPlugin": true, @@ -77,7 +75,6 @@ exports[`Auto Imports > eslintrc > "enabled: true" should output a JSON config f "createShadowRootUi": true, "defineAppConfig": true, "defineBackground": true, - "defineConfig": true, "defineContentScript": true, "defineUnlistedScript": true, "defineWxtPlugin": true, @@ -105,7 +102,6 @@ exports[`Auto Imports > eslintrc > should allow customizing the output 1`] = ` "createShadowRootUi": "readonly", "defineAppConfig": "readonly", "defineBackground": "readonly", - "defineConfig": "readonly", "defineContentScript": "readonly", "defineUnlistedScript": "readonly", "defineWxtPlugin": "readonly", diff --git a/packages/wxt/e2e/tests/auto-imports.test.ts b/packages/wxt/e2e/tests/auto-imports.test.ts index 144b972e..896bbd8c 100644 --- a/packages/wxt/e2e/tests/auto-imports.test.ts +++ b/packages/wxt/e2e/tests/auto-imports.test.ts @@ -17,24 +17,23 @@ describe('Auto Imports', () => { // Generated by wxt export {} declare global { - const ContentScriptContext: typeof import('wxt/client')['ContentScriptContext'] - const InvalidMatchPattern: typeof import('wxt/sandbox')['InvalidMatchPattern'] - const MatchPattern: typeof import('wxt/sandbox')['MatchPattern'] + const ContentScriptContext: typeof import('wxt/utils/content-script-context')['ContentScriptContext'] + const InvalidMatchPattern: typeof import('wxt/utils/match-patterns')['InvalidMatchPattern'] + const MatchPattern: typeof import('wxt/utils/match-patterns')['MatchPattern'] const MigrationError: typeof import('wxt/storage')['MigrationError'] const browser: typeof import('wxt/browser')['browser'] - const createIframeUi: typeof import('wxt/client')['createIframeUi'] - const createIntegratedUi: typeof import('wxt/client')['createIntegratedUi'] - const createShadowRootUi: typeof import('wxt/client')['createShadowRootUi'] - const defineAppConfig: typeof import('wxt/sandbox')['defineAppConfig'] - const defineBackground: typeof import('wxt/sandbox')['defineBackground'] - const defineConfig: typeof import('wxt')['defineConfig'] - const defineContentScript: typeof import('wxt/sandbox')['defineContentScript'] - const defineUnlistedScript: typeof import('wxt/sandbox')['defineUnlistedScript'] - const defineWxtPlugin: typeof import('wxt/sandbox')['defineWxtPlugin'] + const createIframeUi: typeof import('wxt/utils/content-script-ui/iframe')['createIframeUi'] + const createIntegratedUi: typeof import('wxt/utils/content-script-ui/integrated')['createIntegratedUi'] + const createShadowRootUi: typeof import('wxt/utils/content-script-ui/shadow-root')['createShadowRootUi'] + const defineAppConfig: typeof import('wxt/utils/define-app-config')['defineAppConfig'] + const defineBackground: typeof import('wxt/utils/define-background')['defineBackground'] + const defineContentScript: typeof import('wxt/utils/define-content-script')['defineContentScript'] + const defineUnlistedScript: typeof import('wxt/utils/define-unlisted-script')['defineUnlistedScript'] + const defineWxtPlugin: typeof import('wxt/utils/define-wxt-plugin')['defineWxtPlugin'] const fakeBrowser: typeof import('wxt/testing')['fakeBrowser'] - const injectScript: typeof import('wxt/client')['injectScript'] + const injectScript: typeof import('wxt/utils/inject-script')['injectScript'] const storage: typeof import('wxt/storage')['storage'] - const useAppConfig: typeof import('wxt/client')['useAppConfig'] + const useAppConfig: typeof import('wxt/utils/app-config')['useAppConfig'] } " `); @@ -55,10 +54,52 @@ describe('Auto Imports', () => { /// /// /// + /// /// " `); }); + + it('should generate the #imports module', async () => { + const project = new TestProject(); + project.addFile('entrypoints/popup.html', ``); + // Project auto-imports should also be present + project.addFile( + 'utils/time.ts', + `export function startOfDay(date: Date): Date { + throw Error("TODO") + }`, + ); + + await project.prepare(); + + expect(await project.serializeFile('.wxt/types/imports-module.d.ts')) + .toMatchInlineSnapshot(` + ".wxt/types/imports-module.d.ts + ---------------------------------------- + // Generated by wxt + // Types for the #import virtual module + declare module '#imports' { + export { browser } from 'wxt/browser'; + export { MigrationError, storage } from 'wxt/storage'; + export { useAppConfig } from 'wxt/utils/app-config'; + export { ContentScriptContext } from 'wxt/utils/content-script-context'; + export { createIframeUi } from 'wxt/utils/content-script-ui/iframe'; + export { createIntegratedUi } from 'wxt/utils/content-script-ui/integrated'; + export { createShadowRootUi } from 'wxt/utils/content-script-ui/shadow-root'; + export { defineAppConfig } from 'wxt/utils/define-app-config'; + export { defineBackground } from 'wxt/utils/define-background'; + export { defineContentScript } from 'wxt/utils/define-content-script'; + export { defineUnlistedScript } from 'wxt/utils/define-unlisted-script'; + export { defineWxtPlugin } from 'wxt/utils/define-wxt-plugin'; + export { injectScript } from 'wxt/utils/inject-script'; + export { InvalidMatchPattern, MatchPattern } from 'wxt/utils/match-patterns'; + export { fakeBrowser } from 'wxt/testing'; + export { startOfDay } from '../utils/time'; + } + " + `); + }); }); describe('imports: false', () => { @@ -74,7 +115,7 @@ describe('Auto Imports', () => { expect(await project.fileExists('.wxt/types/imports.d.ts')).toBe(false); }); - it('should not include imports.d.ts in the type references', async () => { + it('should only include imports-module.d.ts in the the project', async () => { const project = new TestProject(); project.setConfigFileConfig({ imports: false, @@ -94,10 +135,95 @@ describe('Auto Imports', () => { /// /// /// + /// " `, ); }); + + it('should only generate the #imports module', async () => { + const project = new TestProject(); + project.setConfigFileConfig({ + imports: false, + }); + project.addFile('entrypoints/popup.html', ``); + // Project auto-imports should also be present + project.addFile( + 'utils/time.ts', + `export function startOfDay(date: Date): Date { + throw Error("TODO") + }`, + ); + + await project.prepare(); + + expect(await project.serializeFile('.wxt/types/imports-module.d.ts')) + .toMatchInlineSnapshot(` + ".wxt/types/imports-module.d.ts + ---------------------------------------- + // Generated by wxt + // Types for the #import virtual module + declare module '#imports' { + export { browser } from 'wxt/browser'; + export { MigrationError, storage } from 'wxt/storage'; + export { useAppConfig } from 'wxt/utils/app-config'; + export { ContentScriptContext } from 'wxt/utils/content-script-context'; + export { createIframeUi } from 'wxt/utils/content-script-ui/iframe'; + export { createIntegratedUi } from 'wxt/utils/content-script-ui/integrated'; + export { createShadowRootUi } from 'wxt/utils/content-script-ui/shadow-root'; + export { defineAppConfig } from 'wxt/utils/define-app-config'; + export { defineBackground } from 'wxt/utils/define-background'; + export { defineContentScript } from 'wxt/utils/define-content-script'; + export { defineUnlistedScript } from 'wxt/utils/define-unlisted-script'; + export { defineWxtPlugin } from 'wxt/utils/define-wxt-plugin'; + export { injectScript } from 'wxt/utils/inject-script'; + export { InvalidMatchPattern, MatchPattern } from 'wxt/utils/match-patterns'; + export { fakeBrowser } from 'wxt/testing'; + } + " + `); + }); + + it('should still generate the #imports module', async () => { + const project = new TestProject(); + project.addFile('entrypoints/popup.html', ``); + // Project auto-imports should also be exported + project.addFile( + 'utils/time.ts', + `export function startOfDay(date: Date): Date { + throw Error("TODO") + }`, + ); + + await project.prepare(); + + expect(await project.serializeFile('.wxt/types/imports-module.d.ts')) + .toMatchInlineSnapshot(` + ".wxt/types/imports-module.d.ts + ---------------------------------------- + // Generated by wxt + // Types for the #import virtual module + declare module '#imports' { + export { browser } from 'wxt/browser'; + export { MigrationError, storage } from 'wxt/storage'; + export { useAppConfig } from 'wxt/utils/app-config'; + export { ContentScriptContext } from 'wxt/utils/content-script-context'; + export { createIframeUi } from 'wxt/utils/content-script-ui/iframe'; + export { createIntegratedUi } from 'wxt/utils/content-script-ui/integrated'; + export { createShadowRootUi } from 'wxt/utils/content-script-ui/shadow-root'; + export { defineAppConfig } from 'wxt/utils/define-app-config'; + export { defineBackground } from 'wxt/utils/define-background'; + export { defineContentScript } from 'wxt/utils/define-content-script'; + export { defineUnlistedScript } from 'wxt/utils/define-unlisted-script'; + export { defineWxtPlugin } from 'wxt/utils/define-wxt-plugin'; + export { injectScript } from 'wxt/utils/inject-script'; + export { InvalidMatchPattern, MatchPattern } from 'wxt/utils/match-patterns'; + export { fakeBrowser } from 'wxt/testing'; + export { startOfDay } from '../utils/time'; + } + " + `); + }); }); describe('eslintrc', () => { diff --git a/packages/wxt/e2e/tests/typescript-project.test.ts b/packages/wxt/e2e/tests/typescript-project.test.ts index ad53c38d..de933ce7 100644 --- a/packages/wxt/e2e/tests/typescript-project.test.ts +++ b/packages/wxt/e2e/tests/typescript-project.test.ts @@ -239,6 +239,7 @@ describe('TypeScript Project', () => { /// /// /// + /// /// " `); diff --git a/packages/wxt/package.json b/packages/wxt/package.json index 61920681..6bb5a244 100644 --- a/packages/wxt/package.json +++ b/packages/wxt/package.json @@ -3,69 +3,7 @@ "type": "module", "version": "0.19.29", "description": "⚡ Next-gen Web Extension Framework", - "repository": { - "type": "git", - "url": "git+https://github.com/wxt-dev/wxt.git" - }, - "homepage": "https://wxt.dev", - "keywords": [ - "vite", - "chrome", - "web", - "extension", - "browser", - "bundler", - "framework" - ], - "author": { - "name": "Aaron Klinker", - "email": "aaronklinker1+wxt@gmail.com" - }, "license": "MIT", - "funding": "https://github.com/sponsors/wxt-dev", - "files": [ - "bin", - "dist" - ], - "bin": { - "wxt": "./bin/wxt.mjs", - "wxt-publish-extension": "./bin/wxt-publish-extension.cjs" - }, - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.mjs" - }, - "./client": { - "types": "./dist/client/index.d.ts", - "default": "./dist/client/index.mjs" - }, - "./sandbox": { - "types": "./dist/sandbox/index.d.ts", - "default": "./dist/sandbox/index.mjs" - }, - "./browser": { - "types": "./dist/browser.d.ts", - "default": "./dist/browser.mjs" - }, - "./testing": { - "types": "./dist/testing/index.d.ts", - "default": "./dist/testing/index.mjs" - }, - "./storage": { - "types": "./dist/storage.d.ts", - "default": "./dist/storage.mjs" - }, - "./vite-builder-env": { - "types": "./dist/vite-builder-env.d.ts" - }, - "./modules": { - "types": "./dist/modules.d.ts", - "default": "./dist/modules.mjs" - } - }, "scripts": { "wxt": "tsx src/cli/index.ts", "build": "buildc -- unbuild", @@ -142,5 +80,111 @@ "vitest": "catalog:", "vitest-plugin-random-seed": "catalog:" }, - "peerDependenciesMeta": {} + "peerDependenciesMeta": {}, + "repository": { + "type": "git", + "url": "git+https://github.com/wxt-dev/wxt.git" + }, + "homepage": "https://wxt.dev", + "keywords": [ + "vite", + "chrome", + "web", + "extension", + "browser", + "bundler", + "framework" + ], + "author": { + "name": "Aaron Klinker", + "email": "aaronklinker1+wxt@gmail.com" + }, + "funding": "https://github.com/sponsors/wxt-dev", + "files": [ + "bin", + "dist" + ], + "bin": { + "wxt": "./bin/wxt.mjs", + "wxt-publish-extension": "./bin/wxt-publish-extension.cjs" + }, + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + }, + "./utils/app-config": { + "types": "./dist/utils/app-config.d.ts", + "default": "./dist/utils/app-config.mjs" + }, + "./utils/inject-script": { + "types": "./dist/utils/inject-script.d.ts", + "default": "./dist/utils/inject-script.mjs" + }, + "./utils/content-script-context": { + "types": "./dist/utils/content-script-context.d.ts", + "default": "./dist/utils/content-script-context.mjs" + }, + "./utils/content-script-ui/types": { + "types": "./dist/utils/content-script-ui/types.d.ts", + "default": "./dist/utils/content-script-ui/types.mjs" + }, + "./utils/content-script-ui/integrated": { + "types": "./dist/utils/content-script-ui/integrated.d.ts", + "default": "./dist/utils/content-script-ui/integrated.mjs" + }, + "./utils/content-script-ui/shadow-root": { + "types": "./dist/utils/content-script-ui/shadow-root.d.ts", + "default": "./dist/utils/content-script-ui/shadow-root.mjs" + }, + "./utils/content-script-ui/iframe": { + "types": "./dist/utils/content-script-ui/iframe.d.ts", + "default": "./dist/utils/content-script-ui/iframe.mjs" + }, + "./utils/define-app-config": { + "types": "./dist/utils/define-app-config.d.ts", + "default": "./dist/utils/define-app-config.mjs" + }, + "./utils/define-background": { + "types": "./dist/utils/define-background.d.ts", + "default": "./dist/utils/define-background.mjs" + }, + "./utils/define-content-script": { + "types": "./dist/utils/define-content-script.d.ts", + "default": "./dist/utils/define-content-script.mjs" + }, + "./utils/define-unlisted-script": { + "types": "./dist/utils/define-unlisted-script.d.ts", + "default": "./dist/utils/define-unlisted-script.mjs" + }, + "./utils/define-wxt-plugin": { + "types": "./dist/utils/define-wxt-plugin.d.ts", + "default": "./dist/utils/define-wxt-plugin.mjs" + }, + "./utils/match-patterns": { + "types": "./dist/utils/match-patterns.d.ts", + "default": "./dist/utils/match-patterns.mjs" + }, + "./browser": { + "types": "./dist/browser.d.ts", + "default": "./dist/browser.mjs" + }, + "./testing": { + "types": "./dist/testing/index.d.ts", + "default": "./dist/testing/index.mjs" + }, + "./storage": { + "types": "./dist/storage.d.ts", + "default": "./dist/storage.mjs" + }, + "./vite-builder-env": { + "types": "./dist/vite-builder-env.d.ts" + }, + "./modules": { + "types": "./dist/modules.d.ts", + "default": "./dist/modules.mjs" + } + } } diff --git a/packages/wxt/src/__tests__/modules.test.ts b/packages/wxt/src/__tests__/modules.test.ts index a0455d0a..6481e0f7 100644 --- a/packages/wxt/src/__tests__/modules.test.ts +++ b/packages/wxt/src/__tests__/modules.test.ts @@ -67,20 +67,5 @@ describe('Module Utilities', () => { expect(wxt.config.imports && wxt.config.imports.presets).toHaveLength(2); }); - - it("should not enable imports if they've been disabled", async () => { - const preset = 'vue'; - const wxt = fakeWxt({ - hooks: createHooks(), - config: { - imports: false, - }, - }); - - addImportPreset(wxt, preset); - await wxt.hooks.callHook('config:resolved', wxt); - - expect(wxt.config.imports).toBe(false); - }); }); }); diff --git a/packages/wxt/src/browser.ts b/packages/wxt/src/browser.ts index 9f0b96fd..0019efed 100644 --- a/packages/wxt/src/browser.ts +++ b/packages/wxt/src/browser.ts @@ -1,4 +1,12 @@ /** + * Contains the `browser` export which you should use to access the extension APIs in your project: + * ```ts + * import { browser } from 'wxt/browser'; + * + * browser.runtime.onInstalled.addListener(() => { + * // ... + * }) + * ``` * @module wxt/browser */ import { browser as _browser, type Browser } from '@wxt-dev/browser'; diff --git a/packages/wxt/src/builtin-modules/unimport.ts b/packages/wxt/src/builtin-modules/unimport.ts index 11bf88ba..8339adaa 100644 --- a/packages/wxt/src/builtin-modules/unimport.ts +++ b/packages/wxt/src/builtin-modules/unimport.ts @@ -1,28 +1,27 @@ import { addViteConfig, defineWxtModule } from '../modules'; import type { EslintGlobalsPropValue, + Wxt, WxtDirFileEntry, WxtModule, WxtResolvedUnimportOptions, } from '../types'; -import { type Unimport, createUnimport } from 'unimport'; +import { type Unimport, createUnimport, toExports } from 'unimport'; import UnimportPlugin from 'unimport/unplugin'; export default defineWxtModule({ name: 'wxt:built-in:unimport', setup(wxt) { - const options = wxt.config.imports; - if (options === false) return; - let unimport: Unimport; + const isEnabled = () => !wxt.config.imports.disabled; // Add user module imports to config wxt.hooks.hook('config:resolved', () => { const addModuleImports = (module: WxtModule) => { if (!module.imports) return; - options.imports ??= []; - options.imports.push(...module.imports); + wxt.config.imports.imports ??= []; + wxt.config.imports.imports.push(...module.imports); }; wxt.config.builtinModules.forEach(addModuleImports); @@ -33,7 +32,7 @@ export default defineWxtModule({ // config inside "config:resolved" are applied. wxt.hooks.afterEach((event) => { if (event.name === 'config:resolved') { - unimport = createUnimport(options); + unimport = createUnimport(wxt.config.imports); } }); @@ -42,17 +41,29 @@ export default defineWxtModule({ // Update cache before each rebuild await unimport.init(); + // Always generate the #import module types + entries.push(await getImportsModuleEntry(wxt, unimport)); + + if (!isEnabled()) return; + + // Only create global types when user has enabled auto-imports entries.push(await getImportsDeclarationEntry(unimport)); - if (options.eslintrc.enabled === false) return; + if (wxt.config.imports.eslintrc.enabled === false) return; + + // Only generate ESLint config if that feature is enabled entries.push( - await getEslintConfigEntry(unimport, options.eslintrc.enabled, options), + await getEslintConfigEntry( + unimport, + wxt.config.imports.eslintrc.enabled, + wxt.config.imports, + ), ); }); // Add vite plugin addViteConfig(wxt, () => ({ - plugins: [UnimportPlugin.vite(options)], + plugins: [UnimportPlugin.vite(wxt.config.imports)], })); }, }); @@ -60,9 +71,6 @@ export default defineWxtModule({ async function getImportsDeclarationEntry( unimport: Unimport, ): Promise { - // Load project imports into unimport memory so they are output via generateTypeDeclarations - await unimport.init(); - return { path: 'types/imports.d.ts', text: [ @@ -74,6 +82,25 @@ async function getImportsDeclarationEntry( }; } +async function getImportsModuleEntry( + wxt: Wxt, + unimport: Unimport, +): Promise { + const imports = await unimport.getImports(); + return { + path: 'types/imports-module.d.ts', + text: [ + '// Generated by wxt', + '// Types for the #import virtual module', + "declare module '#imports' {", + ' ' + toExports(imports, wxt.config.wxtDir).replaceAll('\n', '\n '), + '}', + '', + ].join('\n'), + tsReference: true, + }; +} + async function getEslintConfigEntry( unimport: Unimport, version: 8 | 9, diff --git a/packages/wxt/src/client/content-scripts/index.ts b/packages/wxt/src/client/content-scripts/index.ts deleted file mode 100644 index 538b3837..00000000 --- a/packages/wxt/src/client/content-scripts/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './content-script-context'; -export * from './ui'; diff --git a/packages/wxt/src/client/index.ts b/packages/wxt/src/client/index.ts deleted file mode 100644 index b6818d07..00000000 --- a/packages/wxt/src/client/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Any runtime APIs that use the web extension APIs. - * - * @module wxt/client - */ -export * from './content-scripts'; -export * from './app-config'; -export * from './inject-script'; diff --git a/packages/wxt/src/core/builders/vite/plugins/noopBackground.ts b/packages/wxt/src/core/builders/vite/plugins/noopBackground.ts index f6e06cad..660399e3 100644 --- a/packages/wxt/src/core/builders/vite/plugins/noopBackground.ts +++ b/packages/wxt/src/core/builders/vite/plugins/noopBackground.ts @@ -15,7 +15,7 @@ export function noopBackground(): Plugin { }, load(id) { if (id === resolvedVirtualModuleId) { - return `import { defineBackground } from 'wxt/sandbox';\nexport default defineBackground(() => void 0)`; + return `import { defineBackground } from 'wxt/utils/define-background';\nexport default defineBackground(() => void 0)`; } }, }; diff --git a/packages/wxt/src/core/generate-wxt-dir.ts b/packages/wxt/src/core/generate-wxt-dir.ts index 3e58d778..b6871b8c 100644 --- a/packages/wxt/src/core/generate-wxt-dir.ts +++ b/packages/wxt/src/core/generate-wxt-dir.ts @@ -232,10 +232,11 @@ async function getTsConfigEntry(): Promise { .flatMap(([alias, absolutePath]) => { const aliasPath = getTsconfigPath(absolutePath); return [ - ` "${alias}": ["${aliasPath}"]`, - ` "${alias}/*": ["${aliasPath}/*"]`, + `"${alias}": ["${aliasPath}"]`, + `"${alias}/*": ["${aliasPath}/*"]`, ]; }) + .map((line) => ` ${line}`) .join(',\n'); const text = `{ diff --git a/packages/wxt/src/core/resolve-config.ts b/packages/wxt/src/core/resolve-config.ts index cd693a2f..0eacdf4d 100644 --- a/packages/wxt/src/core/resolve-config.ts +++ b/packages/wxt/src/core/resolve-config.ts @@ -14,7 +14,6 @@ import { WxtModule, WxtModuleWithMetadata, ResolvedEslintrc, - Eslintrc, } from '../types'; import path from 'node:path'; import { createFsCache } from './utils/cache'; @@ -332,33 +331,40 @@ async function getUnimportOptions( srcDir: string, logger: Logger, config: InlineConfig, -): Promise { - if (config.imports === false) return false; - +): Promise { + const disabled = config.imports === false; + const eslintrc = await getUnimportEslintOptions(wxtDir, config.imports); + // mlly sometimes picks up things as exports that aren't. That's what this array contains. + const invalidExports = ['options']; const defaultOptions: WxtResolvedUnimportOptions = { - debugLog: logger.debug, - imports: [ - { name: 'defineConfig', from: 'wxt' }, - { name: 'fakeBrowser', from: 'wxt/testing' }, - ], + imports: [{ name: 'fakeBrowser', from: 'wxt/testing' }], + // prettier-ignore presets: [ - { - package: 'wxt/client', - // There seems to be a bug in unimport that thinks "options" is an - // export from wxt/client, but it doesn't actually exist... so it's - // ignored. - ignore: ['options'], - }, { package: 'wxt/browser' }, - { package: 'wxt/sandbox' }, { package: 'wxt/storage' }, + { package: 'wxt/utils/app-config' }, + { package: 'wxt/utils/content-script-context' }, + { package: 'wxt/utils/content-script-ui/iframe', ignore: invalidExports }, + { package: 'wxt/utils/content-script-ui/integrated', ignore: invalidExports }, + { package: 'wxt/utils/content-script-ui/shadow-root', ignore: invalidExports }, + { package: 'wxt/utils/content-script-ui/types' }, + { package: 'wxt/utils/define-app-config' }, + { package: 'wxt/utils/define-background' }, + { package: 'wxt/utils/define-content-script' }, + { package: 'wxt/utils/define-unlisted-script' }, + { package: 'wxt/utils/define-wxt-plugin' }, + { package: 'wxt/utils/inject-script', ignore: invalidExports }, + { package: 'wxt/utils/match-patterns' }, ], + virtualImports: ['#imports'], + debugLog: logger.debug, warn: logger.warn, - dirs: ['components', 'composables', 'hooks', 'utils'], dirsScanOptions: { cwd: srcDir, }, - eslintrc: await getUnimportEslintOptions(wxtDir, config.imports?.eslintrc), + eslintrc, + dirs: disabled ? [] : ['components', 'composables', 'hooks', 'utils'], + disabled, }; return defu( @@ -369,34 +375,34 @@ async function getUnimportOptions( async function getUnimportEslintOptions( wxtDir: string, - options: Eslintrc | undefined, + options: InlineConfig['imports'], ): Promise { - const rawEslintEnabled = options?.enabled ?? 'auto'; - let eslintEnabled: ResolvedEslintrc['enabled']; - switch (rawEslintEnabled) { + const inlineEnabled = + options === false ? false : (options?.eslintrc?.enabled ?? 'auto'); + + let enabled: ResolvedEslintrc['enabled']; + switch (inlineEnabled) { case 'auto': const version = await getEslintVersion(); let major = parseInt(version[0]); - if (isNaN(major)) eslintEnabled = false; - if (major <= 8) eslintEnabled = 8; - else if (major >= 9) eslintEnabled = 9; + if (isNaN(major)) enabled = false; + if (major <= 8) enabled = 8; + else if (major >= 9) enabled = 9; // NaN - else eslintEnabled = false; + else enabled = false; break; case true: - eslintEnabled = 8; + enabled = 8; break; default: - eslintEnabled = rawEslintEnabled; + enabled = inlineEnabled; } return { - enabled: eslintEnabled, + enabled, filePath: path.resolve( wxtDir, - eslintEnabled === 9 - ? 'eslint-auto-imports.mjs' - : 'eslintrc-auto-import.json', + enabled === 9 ? 'eslint-auto-imports.mjs' : 'eslintrc-auto-import.json', ), globalsPropValue: true, }; diff --git a/packages/wxt/src/core/utils/__tests__/transform.test.ts b/packages/wxt/src/core/utils/__tests__/transform.test.ts index 4a59b06d..4df3d61c 100644 --- a/packages/wxt/src/core/utils/__tests__/transform.test.ts +++ b/packages/wxt/src/core/utils/__tests__/transform.test.ts @@ -57,13 +57,13 @@ describe('Transform Utils', () => { it('should remove unused imports', () => { const input = ` - import { defineBackground } from "wxt/sandbox" + import { defineBackground } from "#imports" import { test1 } from "somewhere1" import test2 from "somewhere2" export default defineBackground(() => {}) `; - const expected = `import { defineBackground } from "wxt/sandbox" + const expected = `import { defineBackground } from "#imports" export default defineBackground();`; @@ -74,13 +74,13 @@ export default defineBackground();`; it('should remove explict side-effect imports', () => { const input = ` - import { defineBackground } from "wxt/sandbox" + import { defineBackground } from "#imports" import "my-polyfill" import "./style.css" export default defineBackground(() => {}) `; - const expected = `import { defineBackground } from "wxt/sandbox" + const expected = `import { defineBackground } from "#imports" export default defineBackground();`; diff --git a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/background.ts b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/background.ts index cc7d145e..d12bdb65 100644 --- a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/background.ts +++ b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/background.ts @@ -1,4 +1,4 @@ -import { defineBackground } from '../../../../../sandbox'; +import { defineBackground } from '../../../../../utils/define-background'; export default defineBackground({ main() {}, diff --git a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/content.ts b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/content.ts index 21d582a9..2377a6b3 100644 --- a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/content.ts +++ b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/content.ts @@ -1,4 +1,4 @@ -import { defineContentScript } from '../../../../../sandbox'; +import { defineContentScript } from '../../../../../utils/define-content-script'; export default defineContentScript({ matches: [''], diff --git a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/imported-option.ts b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/imported-option.ts index a5b54951..efdc50ed 100644 --- a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/imported-option.ts +++ b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/imported-option.ts @@ -1,4 +1,4 @@ -import { defineContentScript } from '../../../../../sandbox'; +import { defineContentScript } from '../../../../../utils/define-content-script'; import { faker } from '@faker-js/faker'; export default defineContentScript({ diff --git a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/react.tsx b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/react.tsx index b9bf6082..c0421d45 100644 --- a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/react.tsx +++ b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/react.tsx @@ -1,3 +1,3 @@ -import { defineUnlistedScript } from '../../../../../sandbox'; +import { defineUnlistedScript } from '../../../../../utils/define-unlisted-script'; export default defineUnlistedScript(() => {}); diff --git a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/unlisted.ts b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/unlisted.ts index b9bf6082..c0421d45 100644 --- a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/unlisted.ts +++ b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/unlisted.ts @@ -1,3 +1,3 @@ -import { defineUnlistedScript } from '../../../../../sandbox'; +import { defineUnlistedScript } from '../../../../../utils/define-unlisted-script'; export default defineUnlistedScript(() => {}); diff --git a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/with-named.ts b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/with-named.ts index 5b9d8930..1ed0e710 100644 --- a/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/with-named.ts +++ b/packages/wxt/src/core/utils/building/__tests__/test-entrypoints/with-named.ts @@ -1,4 +1,4 @@ -import { defineBackground } from '../../../../../sandbox'; +import { defineBackground } from '../../../../../utils/define-background'; export const a = {}; diff --git a/packages/wxt/src/core/utils/testing/fake-objects.ts b/packages/wxt/src/core/utils/testing/fake-objects.ts index dc6ec743..d8527b7d 100644 --- a/packages/wxt/src/core/utils/testing/fake-objects.ts +++ b/packages/wxt/src/core/utils/testing/fake-objects.ts @@ -243,6 +243,7 @@ export const fakeResolvedConfig = fakeObjectCreator(() => { env: { browser, command, manifestVersion, mode }, fsCache: mock(), imports: { + disabled: faker.datatype.boolean(), eslintrc: { enabled: faker.helpers.arrayElement([false, 8, 9]), filePath: fakeFile(), diff --git a/packages/wxt/src/index.ts b/packages/wxt/src/index.ts index 06ba588f..4dcba2c6 100644 --- a/packages/wxt/src/index.ts +++ b/packages/wxt/src/index.ts @@ -1,4 +1,9 @@ /** + * This module contains: + * - JS APIs used by the CLI to build extensions or start dev mode. + * - Helper functions for defining project config. + * - Types for building and extension or configuring WXT. + * * @module wxt */ export * from './core'; diff --git a/packages/wxt/src/modules.ts b/packages/wxt/src/modules.ts index d04c9b6f..2cb12a07 100644 --- a/packages/wxt/src/modules.ts +++ b/packages/wxt/src/modules.ts @@ -1,5 +1,5 @@ /** - * Utilities for creating reusable, build-time modules for WXT. + * Utilities for creating [WXT Modules](https://wxt.dev/guide/essentials/wxt-modules.html). * * @module wxt/modules */ @@ -167,6 +167,7 @@ export function addImportPreset( preset: UnimportOptions['presets'][0], ): void { wxt.hooks.hook('config:resolved', (wxt) => { + // In older versions of WXT, `wxt.config.imports` could be false if (!wxt.config.imports) return; wxt.config.imports.presets ??= []; diff --git a/packages/wxt/src/sandbox/index.ts b/packages/wxt/src/sandbox/index.ts deleted file mode 100644 index f3b339bc..00000000 --- a/packages/wxt/src/sandbox/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Any runtime APIs that don't use the web extension APIs. - * - * @module wxt/sandbox - */ -export * from './define-unlisted-script'; -export * from './define-background'; -export * from './define-content-script'; -export * from './define-wxt-plugin'; -export * from './define-app-config'; -export * from '@webext-core/match-patterns'; diff --git a/packages/wxt/src/storage.ts b/packages/wxt/src/storage.ts index cefb3a95..abf76ee1 100644 --- a/packages/wxt/src/storage.ts +++ b/packages/wxt/src/storage.ts @@ -1,4 +1,5 @@ /** - * @module @wxt-dev/storage + * Re-export the [`@wxt-dev/storage` package](https://www.npmjs.com/package/@wxt-dev/storage). + * @module wxt/storage */ export * from '@wxt-dev/storage'; diff --git a/packages/wxt/src/testing/index.ts b/packages/wxt/src/testing/index.ts index ccb6f1f5..6de0fafd 100644 --- a/packages/wxt/src/testing/index.ts +++ b/packages/wxt/src/testing/index.ts @@ -1,4 +1,5 @@ /** + * Utilities for unit testing WXT extensions. * @module wxt/testing */ export * from './fake-browser'; diff --git a/packages/wxt/src/testing/wxt-vitest-plugin.ts b/packages/wxt/src/testing/wxt-vitest-plugin.ts index de526cbe..cd59f338 100644 --- a/packages/wxt/src/testing/wxt-vitest-plugin.ts +++ b/packages/wxt/src/testing/wxt-vitest-plugin.ts @@ -37,9 +37,7 @@ export async function WxtVitest( resolveAppConfig(wxt.config), extensionApiMock(wxt.config), ]; - if (wxt.config.imports !== false) { - plugins.push(UnimportPlugin.vite(wxt.config.imports)); - } + plugins.push(UnimportPlugin.vite(wxt.config.imports)); return plugins; } diff --git a/packages/wxt/src/types.ts b/packages/wxt/src/types.ts index 3312075c..ebcacaa5 100644 --- a/packages/wxt/src/types.ts +++ b/packages/wxt/src/types.ts @@ -1,7 +1,7 @@ import type * as vite from 'vite'; import { UnimportOptions, Import } from 'unimport'; import { LogLevel } from 'consola'; -import type { ContentScriptContext } from './client/content-scripts/content-script-context'; +import type { ContentScriptContext } from './utils/content-script-context'; import type { PluginVisualizerOptions } from '@aklinker1/rollup-plugin-visualizer'; import { ResolvedConfig as C12ResolvedConfig } from 'c12'; import { Hookable, NestedHooks } from 'hookable'; @@ -1297,7 +1297,7 @@ export interface ResolvedConfig { manifestVersion: TargetManifestVersion; env: ConfigEnv; logger: Logger; - imports: false | WxtResolvedUnimportOptions; + imports: WxtResolvedUnimportOptions; manifest: UserManifest; fsCache: FsCache; runnerConfig: C12ResolvedConfig; @@ -1441,6 +1441,12 @@ export type WxtUnimportOptions = Partial & { }; export type WxtResolvedUnimportOptions = Partial & { + /** + * Set to `true` when the user disabled auto-imports. We still use unimport for the #imports module, but other features should be disabled. + * + * You don't need to check this value before modifying the auto-import options. Even if `disabled` is `true`, there's no harm in adding imports to the config - they'll just be ignored. + */ + disabled: boolean; eslintrc: ResolvedEslintrc; }; diff --git a/packages/wxt/src/utils/README.md b/packages/wxt/src/utils/README.md new file mode 100644 index 00000000..1d9f1720 --- /dev/null +++ b/packages/wxt/src/utils/README.md @@ -0,0 +1 @@ +This folder is for public utils, not internal utils. Put generic helpers and other utils in the core/utils folder. diff --git a/packages/wxt/src/client/content-scripts/__tests__/content-script-context.test.ts b/packages/wxt/src/utils/__tests__/content-script-context.test.ts similarity index 97% rename from packages/wxt/src/client/content-scripts/__tests__/content-script-context.test.ts rename to packages/wxt/src/utils/__tests__/content-script-context.test.ts index 548beb3d..f7a5ffc8 100644 --- a/packages/wxt/src/client/content-scripts/__tests__/content-script-context.test.ts +++ b/packages/wxt/src/utils/__tests__/content-script-context.test.ts @@ -1,7 +1,7 @@ /** @vitest-environment happy-dom */ import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { ContentScriptContext } from '..'; +import { ContentScriptContext } from '../content-script-context'; import { fakeBrowser } from '@webext-core/fake-browser'; /** diff --git a/packages/wxt/src/sandbox/__tests__/define-background.test.ts b/packages/wxt/src/utils/__tests__/define-background.test.ts similarity index 100% rename from packages/wxt/src/sandbox/__tests__/define-background.test.ts rename to packages/wxt/src/utils/__tests__/define-background.test.ts diff --git a/packages/wxt/src/sandbox/__tests__/define-content-script.test.ts b/packages/wxt/src/utils/__tests__/define-content-script.test.ts similarity index 100% rename from packages/wxt/src/sandbox/__tests__/define-content-script.test.ts rename to packages/wxt/src/utils/__tests__/define-content-script.test.ts diff --git a/packages/wxt/src/sandbox/__tests__/define-unlisted-script.test.ts b/packages/wxt/src/utils/__tests__/define-unlisted-script.test.ts similarity index 100% rename from packages/wxt/src/sandbox/__tests__/define-unlisted-script.test.ts rename to packages/wxt/src/utils/__tests__/define-unlisted-script.test.ts diff --git a/packages/wxt/src/client/app-config.ts b/packages/wxt/src/utils/app-config.ts similarity index 61% rename from packages/wxt/src/client/app-config.ts rename to packages/wxt/src/utils/app-config.ts index 482d345f..7a22143f 100644 --- a/packages/wxt/src/client/app-config.ts +++ b/packages/wxt/src/utils/app-config.ts @@ -1,6 +1,7 @@ +/** @module wxt/utils/app-config */ // @ts-expect-error: Untyped virtual module import appConfig from 'virtual:app-config'; -import type { WxtAppConfig } from '../sandbox/define-app-config'; +import type { WxtAppConfig } from '../utils/define-app-config'; export function useAppConfig(): WxtAppConfig { return appConfig; diff --git a/packages/wxt/src/client/content-scripts/content-script-context.ts b/packages/wxt/src/utils/content-script-context.ts similarity index 95% rename from packages/wxt/src/client/content-scripts/content-script-context.ts rename to packages/wxt/src/utils/content-script-context.ts index 48165b61..5a488019 100644 --- a/packages/wxt/src/client/content-scripts/content-script-context.ts +++ b/packages/wxt/src/utils/content-script-context.ts @@ -1,8 +1,12 @@ -import { ContentScriptDefinition } from '../../types'; +/** @module wxt/utils/content-script-context */ +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'; +import { logger } from '../utils/internal/logger'; +import { + WxtLocationChangeEvent, + getUniqueEventName, +} from './internal/custom-events'; +import { createLocationWatcher } from './internal/location-watcher'; /** * Implements [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). @@ -14,7 +18,7 @@ import { createLocationWatcher } from './location-watcher'; * To create context for testing, you can use the class's constructor: * * ```ts - * import { ContentScriptContext } from 'wxt/client'; + * import { ContentScriptContext } from 'wxt/utils/content-scripts-context'; * * test("storage listener should be removed when context is invalidated", () => { * const ctx = new ContentScriptContext('test'); diff --git a/packages/wxt/src/client/content-scripts/ui/__tests__/index.test.ts b/packages/wxt/src/utils/content-script-ui/__tests__/index.test.ts similarity index 98% rename from packages/wxt/src/client/content-scripts/ui/__tests__/index.test.ts rename to packages/wxt/src/utils/content-script-ui/__tests__/index.test.ts index 4913265f..57972a22 100644 --- a/packages/wxt/src/client/content-scripts/ui/__tests__/index.test.ts +++ b/packages/wxt/src/utils/content-script-ui/__tests__/index.test.ts @@ -1,12 +1,10 @@ /** @vitest-environment happy-dom */ -import { describe, it, beforeEach, afterEach, vi, expect } from 'vitest'; -import { - createIntegratedUi, - createIframeUi, - createShadowRootUi, - ContentScriptUi, -} from '..'; +import { describe, it, beforeEach, vi, expect, afterEach } from 'vitest'; +import { createIntegratedUi } from '../integrated'; +import { createIframeUi } from '../iframe'; +import { createShadowRootUi } from '../shadow-root'; import { ContentScriptContext } from '../../content-script-context'; +import { ContentScriptUi } from '../types'; /** * Util for floating promise. diff --git a/packages/wxt/src/utils/content-script-ui/iframe.ts b/packages/wxt/src/utils/content-script-ui/iframe.ts new file mode 100644 index 00000000..f667f135 --- /dev/null +++ b/packages/wxt/src/utils/content-script-ui/iframe.ts @@ -0,0 +1,50 @@ +/** @module wxt/utils/content-script-ui/iframe */ +import { browser } from 'wxt/browser'; +import { ContentScriptContext } from '../content-script-context'; +import type { + IframeContentScriptUi, + IframeContentScriptUiOptions, +} from './types'; +import { applyPosition, createMountFunctions, mountUi } from './shared'; + +/** + * Create a content script UI using an iframe. + * + * @see https://wxt.dev/guide/essentials/content-scripts.html#iframe + */ +export function createIframeUi( + ctx: ContentScriptContext, + options: IframeContentScriptUiOptions, +): IframeContentScriptUi { + const wrapper = document.createElement('div'); + wrapper.setAttribute('data-wxt-iframe', ''); + const iframe = document.createElement('iframe'); + // @ts-expect-error: getURL is defined per-project, but not inside the package + iframe.src = browser.runtime.getURL(options.page); + wrapper.appendChild(iframe); + + let mounted: TMounted | undefined = undefined; + const mount = () => { + applyPosition(wrapper, iframe, options); + mountUi(wrapper, options); + mounted = options.onMount?.(wrapper, iframe); + }; + const remove = () => { + options.onRemove?.(mounted); + wrapper.remove(); + mounted = undefined; + }; + + const mountFunctions = createMountFunctions({ mount, remove }, options); + + ctx.onInvalidated(remove); + + return { + get mounted() { + return mounted; + }, + iframe, + wrapper, + ...mountFunctions, + }; +} diff --git a/packages/wxt/src/utils/content-script-ui/integrated.ts b/packages/wxt/src/utils/content-script-ui/integrated.ts new file mode 100644 index 00000000..78d53db1 --- /dev/null +++ b/packages/wxt/src/utils/content-script-ui/integrated.ts @@ -0,0 +1,51 @@ +/** @module wxt/utils/content-script-ui/integrated */ +import { ContentScriptContext } from '../content-script-context'; +import type { + IntegratedContentScriptUi, + IntegratedContentScriptUiOptions, +} from './types'; +import { applyPosition, createMountFunctions, mountUi } from './shared'; + +/** + * Create a content script UI without any isolation. + * + * @see https://wxt.dev/guide/essentials/content-scripts.html#integrated + */ +export function createIntegratedUi( + ctx: ContentScriptContext, + options: IntegratedContentScriptUiOptions, +): IntegratedContentScriptUi { + const wrapper = document.createElement(options.tag || 'div'); + wrapper.setAttribute('data-wxt-integrated', ''); + + let mounted: TMounted | undefined = undefined; + const mount = () => { + applyPosition(wrapper, undefined, options); + mountUi(wrapper, options); + mounted = options.onMount?.(wrapper); + }; + const remove = () => { + options.onRemove?.(mounted); + wrapper.replaceChildren(); + wrapper.remove(); + mounted = undefined; + }; + + const mountFunctions = createMountFunctions( + { + mount, + remove, + }, + options, + ); + + ctx.onInvalidated(remove); + + return { + get mounted() { + return mounted; + }, + wrapper, + ...mountFunctions, + }; +} diff --git a/packages/wxt/src/utils/content-script-ui/shadow-root.ts b/packages/wxt/src/utils/content-script-ui/shadow-root.ts new file mode 100644 index 00000000..07babfdd --- /dev/null +++ b/packages/wxt/src/utils/content-script-ui/shadow-root.ts @@ -0,0 +1,104 @@ +/** @module wxt/utils/content-script-ui/shadow-root */ +import { ContentScriptContext } from '../content-script-context'; +import type { + ShadowRootContentScriptUi, + ShadowRootContentScriptUiOptions, +} from './types'; +import { createIsolatedElement } from '@webext-core/isolated-element'; +import { applyPosition, createMountFunctions, mountUi } from './shared'; +import { logger } from '../internal/logger'; + +/** + * Create a content script UI inside a [`ShadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot). + * + * > This function is async because it has to load the CSS via a network call. + * + * @see https://wxt.dev/guide/essentials/content-scripts.html#shadow-root + */ +export async function createShadowRootUi( + ctx: ContentScriptContext, + options: ShadowRootContentScriptUiOptions, +): Promise> { + const css = [options.css ?? '']; + if (ctx.options?.cssInjectionMode === 'ui') { + const entryCss = await loadCss(); + // Replace :root selectors with :host since we're in a shadow root + css.push(entryCss.replaceAll(':root', ':host')); + } + + const { + isolatedElement: uiContainer, + parentElement: shadowHost, + shadow, + } = await createIsolatedElement({ + name: options.name, + css: { + textContent: css.join('\n').trim(), + }, + mode: options.mode ?? 'open', + isolateEvents: options.isolateEvents, + }); + shadowHost.setAttribute('data-wxt-shadow-root', ''); + + let mounted: TMounted | undefined; + + const mount = () => { + // Add shadow root element to DOM + mountUi(shadowHost, options); + applyPosition(shadowHost, shadow.querySelector('html'), options); + // Mount UI inside shadow root + mounted = options.onMount(uiContainer, shadow, shadowHost); + }; + + const remove = () => { + // Cleanup mounted state + options.onRemove?.(mounted); + // Detach shadow root from DOM + shadowHost.remove(); + // Remove children from uiContainer + while (uiContainer.lastChild) + uiContainer.removeChild(uiContainer.lastChild); + // Clear mounted value + mounted = undefined; + }; + + const mountFunctions = createMountFunctions( + { + mount, + remove, + }, + options, + ); + + ctx.onInvalidated(remove); + + return { + shadow, + shadowHost, + uiContainer, + ...mountFunctions, + get mounted() { + return mounted; + }, + }; +} + +/** + * Load the CSS for the current entrypoint. + */ +async function loadCss(): Promise { + // @ts-expect-error: getURL is defined per-project, but not inside the package + const url = browser.runtime.getURL( + `/content-scripts/${import.meta.env.ENTRYPOINT}.css`, + ); + try { + const res = await fetch(url); + return await res.text(); + } catch (err) { + logger.warn( + `Failed to load styles @ ${url}. Did you forget to import the stylesheet in your entrypoint?`, + err, + ); + return ''; + } +} diff --git a/packages/wxt/src/client/content-scripts/ui/index.ts b/packages/wxt/src/utils/content-script-ui/shared.ts similarity index 51% rename from packages/wxt/src/client/content-scripts/ui/index.ts rename to packages/wxt/src/utils/content-script-ui/shared.ts index 49182bb4..c23b52eb 100644 --- a/packages/wxt/src/client/content-scripts/ui/index.ts +++ b/packages/wxt/src/utils/content-script-ui/shared.ts @@ -1,197 +1,20 @@ -import { browser } from 'wxt/browser'; +import type { + ContentScriptAnchoredOptions, + ContentScriptPositioningOptions, + AutoMount, + AutoMountOptions, + BaseMountFunctions, + ContentScriptUiOptions, + MountFunctions, +} from './types'; import { waitElement } from '@1natsu/wait-element'; import { isExist as mountDetector, isNotExist as removeDetector, } from '@1natsu/wait-element/detectors'; -import { ContentScriptContext } from '..'; -import { - AutoMount, - AutoMountOptions, - BaseMountFunctions, - ContentScriptAnchoredOptions, - ContentScriptPositioningOptions, - ContentScriptUiOptions, - IframeContentScriptUi, - IframeContentScriptUiOptions, - IntegratedContentScriptUi, - IntegratedContentScriptUiOptions, - MountFunctions, - ShadowRootContentScriptUi, - ShadowRootContentScriptUiOptions, -} from './types'; -import { logger } from '../../../sandbox/utils/logger'; -import { createIsolatedElement } from '@webext-core/isolated-element'; -export * from './types'; +import { logger } from '../../utils/internal/logger'; -/** - * Create a content script UI without any isolation. - * - * @see https://wxt.dev/guide/essentials/content-scripts.html#integrated - */ -export function createIntegratedUi( - ctx: ContentScriptContext, - options: IntegratedContentScriptUiOptions, -): IntegratedContentScriptUi { - const wrapper = document.createElement(options.tag || 'div'); - wrapper.setAttribute('data-wxt-integrated', ''); - - let mounted: TMounted | undefined = undefined; - const mount = () => { - applyPosition(wrapper, undefined, options); - mountUi(wrapper, options); - mounted = options.onMount?.(wrapper); - }; - const remove = () => { - options.onRemove?.(mounted); - wrapper.replaceChildren(); - wrapper.remove(); - mounted = undefined; - }; - - const mountFunctions = createMountFunctions( - { - mount, - remove, - }, - options, - ); - - ctx.onInvalidated(remove); - - return { - get mounted() { - return mounted; - }, - wrapper, - ...mountFunctions, - }; -} - -/** - * Create a content script UI using an iframe. - * - * @see https://wxt.dev/guide/essentials/content-scripts.html#iframe - */ -export function createIframeUi( - ctx: ContentScriptContext, - options: IframeContentScriptUiOptions, -): IframeContentScriptUi { - const wrapper = document.createElement('div'); - wrapper.setAttribute('data-wxt-iframe', ''); - const iframe = document.createElement('iframe'); - // @ts-expect-error: getURL is defined per-project, but not inside the package - iframe.src = browser.runtime.getURL(options.page); - wrapper.appendChild(iframe); - - let mounted: TMounted | undefined = undefined; - const mount = () => { - applyPosition(wrapper, iframe, options); - mountUi(wrapper, options); - mounted = options.onMount?.(wrapper, iframe); - }; - const remove = () => { - options.onRemove?.(mounted); - wrapper.remove(); - mounted = undefined; - }; - - const mountFunctions = createMountFunctions( - { - mount, - remove, - }, - options, - ); - - ctx.onInvalidated(remove); - - return { - get mounted() { - return mounted; - }, - iframe, - wrapper, - ...mountFunctions, - }; -} - -/** - * Create a content script UI inside a [`ShadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot). - * - * > This function is async because it has to load the CSS via a network call. - * - * @see https://wxt.dev/guide/essentials/content-scripts.html#shadow-root - */ -export async function createShadowRootUi( - ctx: ContentScriptContext, - options: ShadowRootContentScriptUiOptions, -): Promise> { - const css = [options.css ?? '']; - if (ctx.options?.cssInjectionMode === 'ui') { - const entryCss = await loadCss(); - // Replace :root selectors with :host since we're in a shadow root - css.push(entryCss.replaceAll(':root', ':host')); - } - - const { - isolatedElement: uiContainer, - parentElement: shadowHost, - shadow, - } = await createIsolatedElement({ - name: options.name, - css: { - textContent: css.join('\n').trim(), - }, - mode: options.mode ?? 'open', - isolateEvents: options.isolateEvents, - }); - shadowHost.setAttribute('data-wxt-shadow-root', ''); - - let mounted: TMounted | undefined; - - const mount = () => { - // Add shadow root element to DOM - mountUi(shadowHost, options); - applyPosition(shadowHost, shadow.querySelector('html'), options); - // Mount UI inside shadow root - mounted = options.onMount(uiContainer, shadow, shadowHost); - }; - - const remove = () => { - // Cleanup mounted state - options.onRemove?.(mounted); - // Detach shadow root from DOM - shadowHost.remove(); - // Remove children from uiContainer - while (uiContainer.lastChild) - uiContainer.removeChild(uiContainer.lastChild); - // Clear mounted value - mounted = undefined; - }; - - const mountFunctions = createMountFunctions( - { - mount, - remove, - }, - options, - ); - - ctx.onInvalidated(remove); - - return { - shadow, - shadowHost, - uiContainer, - ...mountFunctions, - get mounted() { - return mounted; - }, - }; -} - -function applyPosition( +export function applyPosition( root: HTMLElement, positionedElement: HTMLElement | undefined | null, options: ContentScriptPositioningOptions, @@ -227,7 +50,9 @@ function applyPosition( } } -function getAnchor(options: ContentScriptAnchoredOptions): Element | undefined { +export function getAnchor( + options: ContentScriptAnchoredOptions, +): Element | undefined { if (options.anchor == null) return document.body; let resolved = @@ -254,7 +79,7 @@ function getAnchor(options: ContentScriptAnchoredOptions): Element | undefined { return resolved ?? undefined; } -function mountUi( +export function mountUi( root: HTMLElement, options: ContentScriptAnchoredOptions, ): void { @@ -287,7 +112,7 @@ function mountUi( } } -function createMountFunctions( +export function createMountFunctions( baseFunctions: BaseMountFunctions, options: ContentScriptUiOptions, ): MountFunctions { @@ -392,23 +217,3 @@ function autoMountUi( return { stopAutoMount: _stopAutoMount }; } - -/** - * Load the CSS for the current entrypoint. - */ -async function loadCss(): Promise { - // @ts-expect-error: getURL is defined per-project, but not inside the package - const url = browser.runtime.getURL( - `/content-scripts/${import.meta.env.ENTRYPOINT}.css`, - ); - try { - const res = await fetch(url); - return await res.text(); - } catch (err) { - logger.warn( - `Failed to load styles @ ${url}. Did you forget to import the stylesheet in your entrypoint?`, - err, - ); - return ''; - } -} diff --git a/packages/wxt/src/client/content-scripts/ui/types.ts b/packages/wxt/src/utils/content-script-ui/types.ts similarity index 98% rename from packages/wxt/src/client/content-scripts/ui/types.ts rename to packages/wxt/src/utils/content-script-ui/types.ts index 7e4da3ff..544fa311 100644 --- a/packages/wxt/src/client/content-scripts/ui/types.ts +++ b/packages/wxt/src/utils/content-script-ui/types.ts @@ -1,3 +1,7 @@ +/** + * Shared types for the different `wxt/utils/content-script-ui/*` modules. + * @module wxt/utils/content-script-ui/types + */ export interface IntegratedContentScriptUi extends ContentScriptUi { /** diff --git a/packages/wxt/src/sandbox/define-app-config.ts b/packages/wxt/src/utils/define-app-config.ts similarity index 78% rename from packages/wxt/src/sandbox/define-app-config.ts rename to packages/wxt/src/utils/define-app-config.ts index 164264c0..57db98e8 100644 --- a/packages/wxt/src/sandbox/define-app-config.ts +++ b/packages/wxt/src/utils/define-app-config.ts @@ -1,3 +1,4 @@ +/** @module wxt/utils/define-app-config */ export interface WxtAppConfig {} /** @@ -7,9 +8,9 @@ export interface WxtAppConfig {} * * ```ts * // app.config.ts - * import 'wxt/sandbox'; + * import 'wxt/utils/define-app-config'; * - * declare module "wxt/sandbox" { + * declare module "wxt/utils/define-app-config" { * export interface WxtAppConfig { * analytics: AnalyticsConfig * } diff --git a/packages/wxt/src/sandbox/define-background.ts b/packages/wxt/src/utils/define-background.ts similarity index 90% rename from packages/wxt/src/sandbox/define-background.ts rename to packages/wxt/src/utils/define-background.ts index bfc074bd..18a8c92e 100644 --- a/packages/wxt/src/sandbox/define-background.ts +++ b/packages/wxt/src/utils/define-background.ts @@ -1,3 +1,4 @@ +/** @module wxt/utils/define-background */ import type { BackgroundDefinition } from '../types'; export function defineBackground(main: () => void): BackgroundDefinition; diff --git a/packages/wxt/src/sandbox/define-content-script.ts b/packages/wxt/src/utils/define-content-script.ts similarity index 79% rename from packages/wxt/src/sandbox/define-content-script.ts rename to packages/wxt/src/utils/define-content-script.ts index de3ac5c1..4d250cc5 100644 --- a/packages/wxt/src/sandbox/define-content-script.ts +++ b/packages/wxt/src/utils/define-content-script.ts @@ -1,3 +1,4 @@ +/** @module wxt/utils/define-content-script */ import type { ContentScriptDefinition } from '../types'; export function defineContentScript( diff --git a/packages/wxt/src/sandbox/define-unlisted-script.ts b/packages/wxt/src/utils/define-unlisted-script.ts similarity index 90% rename from packages/wxt/src/sandbox/define-unlisted-script.ts rename to packages/wxt/src/utils/define-unlisted-script.ts index 4716aaa2..6ee1dbba 100644 --- a/packages/wxt/src/sandbox/define-unlisted-script.ts +++ b/packages/wxt/src/utils/define-unlisted-script.ts @@ -1,3 +1,4 @@ +/** @module wxt/utils/define-unlisted-script */ import type { UnlistedScriptDefinition } from '../types'; export function defineUnlistedScript( diff --git a/packages/wxt/src/sandbox/define-wxt-plugin.ts b/packages/wxt/src/utils/define-wxt-plugin.ts similarity index 74% rename from packages/wxt/src/sandbox/define-wxt-plugin.ts rename to packages/wxt/src/utils/define-wxt-plugin.ts index f2f9e8a4..ed487271 100644 --- a/packages/wxt/src/sandbox/define-wxt-plugin.ts +++ b/packages/wxt/src/utils/define-wxt-plugin.ts @@ -1,3 +1,4 @@ +/** @module wxt/utils/define-wxt-plugin */ import type { WxtPlugin } from '../types'; export function defineWxtPlugin(plugin: WxtPlugin): WxtPlugin { diff --git a/packages/wxt/src/client/inject-script.ts b/packages/wxt/src/utils/inject-script.ts similarity index 97% rename from packages/wxt/src/client/inject-script.ts rename to packages/wxt/src/utils/inject-script.ts index 989ba248..2043e2da 100644 --- a/packages/wxt/src/client/inject-script.ts +++ b/packages/wxt/src/utils/inject-script.ts @@ -1,3 +1,4 @@ +/** @module wxt/utils/inject-script */ import { browser } from 'wxt/browser'; export type ScriptPublicPath = Extract< diff --git a/packages/wxt/src/client/content-scripts/custom-events.ts b/packages/wxt/src/utils/internal/custom-events.ts similarity index 100% rename from packages/wxt/src/client/content-scripts/custom-events.ts rename to packages/wxt/src/utils/internal/custom-events.ts diff --git a/packages/wxt/src/sandbox/dev-server-websocket.ts b/packages/wxt/src/utils/internal/dev-server-websocket.ts similarity index 98% rename from packages/wxt/src/sandbox/dev-server-websocket.ts rename to packages/wxt/src/utils/internal/dev-server-websocket.ts index 91961303..9e2abae7 100644 --- a/packages/wxt/src/sandbox/dev-server-websocket.ts +++ b/packages/wxt/src/utils/internal/dev-server-websocket.ts @@ -1,4 +1,4 @@ -import { logger } from './utils/logger'; +import { logger } from './logger'; interface WebSocketMessage { type: string; diff --git a/packages/wxt/src/client/content-scripts/location-watcher.ts b/packages/wxt/src/utils/internal/location-watcher.ts similarity index 92% rename from packages/wxt/src/client/content-scripts/location-watcher.ts rename to packages/wxt/src/utils/internal/location-watcher.ts index d0ae2769..085844e8 100644 --- a/packages/wxt/src/client/content-scripts/location-watcher.ts +++ b/packages/wxt/src/utils/internal/location-watcher.ts @@ -1,4 +1,4 @@ -import { ContentScriptContext } from '.'; +import { ContentScriptContext } from '../content-script-context'; import { WxtLocationChangeEvent } from './custom-events'; /** diff --git a/packages/wxt/src/sandbox/utils/logger.ts b/packages/wxt/src/utils/internal/logger.ts similarity index 100% rename from packages/wxt/src/sandbox/utils/logger.ts rename to packages/wxt/src/utils/internal/logger.ts diff --git a/packages/wxt/src/utils/match-patterns.ts b/packages/wxt/src/utils/match-patterns.ts new file mode 100644 index 00000000..ffe24d5e --- /dev/null +++ b/packages/wxt/src/utils/match-patterns.ts @@ -0,0 +1,5 @@ +/** + * Re-export the [`@webext-core/match-patterns` package](https://www.npmjs.com/package/@webext-core/match-patterns). + * @module wxt/utils/match-patterns + */ +export * from '@webext-core/match-patterns'; diff --git a/packages/wxt/src/virtual/background-entrypoint.ts b/packages/wxt/src/virtual/background-entrypoint.ts index b25bac9a..44c4be0a 100644 --- a/packages/wxt/src/virtual/background-entrypoint.ts +++ b/packages/wxt/src/virtual/background-entrypoint.ts @@ -1,7 +1,7 @@ import definition from 'virtual:user-background-entrypoint'; import { initPlugins } from 'virtual:wxt-plugins'; -import { getDevServerWebSocket } from '../sandbox/dev-server-websocket'; -import { logger } from '../sandbox/utils/logger'; +import { getDevServerWebSocket } from '../utils/internal/dev-server-websocket'; +import { logger } from '../utils/internal/logger'; import { browser } from 'wxt/browser'; import { keepServiceWorkerAlive } from './utils/keep-service-worker-alive'; import { reloadContentScript } from './utils/reload-content-scripts'; diff --git a/packages/wxt/src/virtual/content-script-isolated-world-entrypoint.ts b/packages/wxt/src/virtual/content-script-isolated-world-entrypoint.ts index a80399d3..4bd38833 100644 --- a/packages/wxt/src/virtual/content-script-isolated-world-entrypoint.ts +++ b/packages/wxt/src/virtual/content-script-isolated-world-entrypoint.ts @@ -1,6 +1,6 @@ import definition from 'virtual:user-content-script-isolated-world-entrypoint'; -import { logger } from '../sandbox/utils/logger'; -import { ContentScriptContext } from 'wxt/client'; +import { logger } from '../utils/internal/logger'; +import { ContentScriptContext } from 'wxt/utils/content-script-context'; import { initPlugins } from 'virtual:wxt-plugins'; const result = (async () => { diff --git a/packages/wxt/src/virtual/content-script-main-world-entrypoint.ts b/packages/wxt/src/virtual/content-script-main-world-entrypoint.ts index 15db16d3..1241bad6 100644 --- a/packages/wxt/src/virtual/content-script-main-world-entrypoint.ts +++ b/packages/wxt/src/virtual/content-script-main-world-entrypoint.ts @@ -1,5 +1,5 @@ import definition from 'virtual:user-content-script-main-world-entrypoint'; -import { logger } from '../sandbox/utils/logger'; +import { logger } from '../utils/internal/logger'; import { initPlugins } from 'virtual:wxt-plugins'; const result = (async () => { diff --git a/packages/wxt/src/virtual/reload-html.ts b/packages/wxt/src/virtual/reload-html.ts index 12fa4947..3f3742bb 100644 --- a/packages/wxt/src/virtual/reload-html.ts +++ b/packages/wxt/src/virtual/reload-html.ts @@ -1,5 +1,5 @@ -import { logger } from '../sandbox/utils/logger'; -import { getDevServerWebSocket } from '../sandbox/dev-server-websocket'; +import { logger } from '../utils/internal/logger'; +import { getDevServerWebSocket } from '../utils/internal/dev-server-websocket'; if (import.meta.env.COMMAND === 'serve') { try { diff --git a/packages/wxt/src/virtual/unlisted-script-entrypoint.ts b/packages/wxt/src/virtual/unlisted-script-entrypoint.ts index a2a65bbb..843d9ac4 100644 --- a/packages/wxt/src/virtual/unlisted-script-entrypoint.ts +++ b/packages/wxt/src/virtual/unlisted-script-entrypoint.ts @@ -1,5 +1,5 @@ import definition from 'virtual:user-unlisted-script-entrypoint'; -import { logger } from '../sandbox/utils/logger'; +import { logger } from '../utils/internal/logger'; import { initPlugins } from 'virtual:wxt-plugins'; const result = (async () => { diff --git a/packages/wxt/src/virtual/utils/reload-content-scripts.ts b/packages/wxt/src/virtual/utils/reload-content-scripts.ts index 3b82417a..0caa3570 100644 --- a/packages/wxt/src/virtual/utils/reload-content-scripts.ts +++ b/packages/wxt/src/virtual/utils/reload-content-scripts.ts @@ -1,7 +1,7 @@ import { browser } from 'wxt/browser'; -import { logger } from '../../sandbox/utils/logger'; -import { MatchPattern } from 'wxt/sandbox'; -import type { ReloadContentScriptPayload } from '../../sandbox/dev-server-websocket'; +import { logger } from '../../utils/internal/logger'; +import { MatchPattern } from 'wxt/utils/match-patterns'; +import type { ReloadContentScriptPayload } from '../../utils/internal/dev-server-websocket'; export function reloadContentScript(payload: ReloadContentScriptPayload) { const manifest = browser.runtime.getManifest(); diff --git a/packages/wxt/typedoc.json b/packages/wxt/typedoc.json index fa919313..ff0aefc0 100644 --- a/packages/wxt/typedoc.json +++ b/packages/wxt/typedoc.json @@ -1,11 +1,22 @@ { "entryPoints": [ - "src/client/index.ts", - "src/testing/index.ts", - "src/sandbox/index.ts", - "src/browser.ts", "src/index.ts", - "src/modules.ts", - "src/storage.ts" + "src/utils/app-config.ts", + "src/utils/inject-script.ts", + "src/utils/content-script-context.ts", + "src/utils/content-script-ui/types.ts", + "src/utils/content-script-ui/integrated.ts", + "src/utils/content-script-ui/shadow-root.ts", + "src/utils/content-script-ui/iframe.ts", + "src/utils/define-app-config.ts", + "src/utils/define-background.ts", + "src/utils/define-content-script.ts", + "src/utils/define-unlisted-script.ts", + "src/utils/define-wxt-plugin.ts", + "src/utils/match-patterns.ts", + "src/browser.ts", + "src/testing/index.ts", + "src/storage.ts", + "src/modules.ts" ] }