diff --git a/docs/guide/essentials/extension-apis.md b/docs/guide/essentials/extension-apis.md index 898857e0..5d0187b9 100644 --- a/docs/guide/essentials/extension-apis.md +++ b/docs/guide/essentials/extension-apis.md @@ -4,61 +4,41 @@ Different browsers provide different global variables for accessing the extension APIs (chrome provides `chrome`, firefox provides `browser`, etc). -WXT simplifies this - always use `browser`: +WXT merges these two into a unified API accessed through the `browser` variable. ```ts +import { browser } from 'wxt/browser'; + browser.action.onClicked.addListener(() => { // ... }); ``` -Other than that, refer to Chrome and Mozilla's documentation for how to use specific APIs. Everything a normal extension can do, WXT can do as well, just via `browser` instead of `chrome`. +:::tip +With auto-imports enabled, you don't even need to import this variable from `wxt/browser`! +::: -## Webextension Polyfill - -> Since `v0.1.0` - -By default, WXT uses the [`webextension-polyfill` by Mozilla](https://www.npmjs.com/package/webextension-polyfill) to make the extension API consistent between browsers. - -To access types, you should import the relevant namespace from `wxt/browser`: - -```ts -import { Runtime } from 'wxt/browser'; - -function handleMessage(message: any, sender: Runtime.Sender) { - // ... -} -``` - -### Disabling the polyfill - -> Since `v0.19.0` - -After the release of MV3 and Chrome's official deprecation of MV2 in June 2024, the polyfill isn't really doing anything useful anymore. - -You can disable it with a single line: - -```ts [wxt.config.ts] -export default defineConfig({ - extensionApi: 'chrome', -}); -``` - -This will change `wxt/browser` to simply export the `browser` or `chrome` globals based on browser at runtime: +The `browser` variable WXT provides is a simple export of the `browser` or `chrome` globals provided by the browser at runtime: <<< @/../packages/browser/src/index.mjs#snippet -Accessing types is a little different with the polyfill disabled. They do not need to be imported; they're available on the `browser` object itself: +This means you can use the promise-style API for both MV2 and MV3, and it will work across all browsers (Chromium, Firefox, Safari, etc). + +## Accessing Types + +All types can be accessed via WXT's `Browser` namespace: ```ts -function handleMessage(message: any, sender: browser.runtime.Sender) { +import { Browser } from 'wxt/browser'; + +function handleMessage(message: any, sender: Browser.runtime.MessageSender) { // ... } ``` ## Feature Detection -Depending on the manifest version and browser, some APIs are not available at runtime. If an API is not available, it will be `undefined`. +Depending on the manifest version, browser, and permissions, some APIs are not available at runtime. If an API is not available, it will be `undefined`. :::warning Types will not help you here. The types WXT provides for `browser` assume all APIs exist. You are responsible for knowing whether an API is available or not. diff --git a/packages/browser/src/__tests__/index.test.ts b/packages/browser/src/__tests__/index.test.ts index 1fb8330c..07b40f51 100644 --- a/packages/browser/src/__tests__/index.test.ts +++ b/packages/browser/src/__tests__/index.test.ts @@ -1,6 +1,6 @@ /// import { describe, expectTypeOf, it } from 'vitest'; -import { browser, Browser } from '../index'; +import { browser, type Browser } from '../index'; describe('browser', () => { describe('types', () => { diff --git a/packages/wxt-demo/src/entrypoints/__tests__/background.test.ts b/packages/wxt-demo/src/entrypoints/__tests__/background.test.ts index 62f79bed..c46f84d2 100644 --- a/packages/wxt-demo/src/entrypoints/__tests__/background.test.ts +++ b/packages/wxt-demo/src/entrypoints/__tests__/background.test.ts @@ -1,7 +1,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import background from '../background'; -chrome.i18n.getMessage = () => 'fake-message'; +browser.i18n.getMessage = () => 'fake-message'; const logMock = vi.fn(); console.log = logMock; @@ -11,7 +11,7 @@ describe('Background Entrypoint', () => { fakeBrowser.reset(); }); - it("should log the extenion's runtime ID", () => { + it("should log the extension's runtime ID", () => { const id = 'some-id'; fakeBrowser.runtime.id = id; diff --git a/packages/wxt-demo/wxt.config.ts b/packages/wxt-demo/wxt.config.ts index 6961eea2..eee9f5d3 100644 --- a/packages/wxt-demo/wxt.config.ts +++ b/packages/wxt-demo/wxt.config.ts @@ -3,7 +3,6 @@ import { presetUno } from 'unocss'; export default defineConfig({ srcDir: 'src', - extensionApi: 'chrome', manifest: { permissions: ['storage'], default_locale: 'en', diff --git a/packages/wxt/e2e/tests/modules.test.ts b/packages/wxt/e2e/tests/modules.test.ts index 11d86688..dcbe6c90 100644 --- a/packages/wxt/e2e/tests/modules.test.ts +++ b/packages/wxt/e2e/tests/modules.test.ts @@ -191,10 +191,7 @@ describe('Module Helpers', () => { ); const expectedText = addPluginModule(project); - await project.build({ - // reduce build output when comparing test failures - extensionApi: 'chrome', - }); + await project.build(); await expect(project.serializeOutput()).resolves.toContain(expectedText); }); @@ -211,10 +208,7 @@ describe('Module Helpers', () => { ); const expectedText = addPluginModule(project); - await project.build({ - // reduce build output when comparing test failures - extensionApi: 'chrome', - }); + await project.build(); await expect(project.serializeOutput()).resolves.toContain(expectedText); }); @@ -232,10 +226,7 @@ describe('Module Helpers', () => { ); const expectedText = addPluginModule(project); - await project.build({ - // reduce build output when comparing test failures - extensionApi: 'chrome', - }); + await project.build(); await expect(project.serializeOutput()).resolves.toContain(expectedText); }); @@ -248,10 +239,7 @@ describe('Module Helpers', () => { ); const expectedText = addPluginModule(project); - await project.build({ - // reduce build output when comparing test failures - extensionApi: 'chrome', - }); + await project.build(); await expect(project.serializeOutput()).resolves.toContain(expectedText); }); diff --git a/packages/wxt/e2e/tests/output-structure.test.ts b/packages/wxt/e2e/tests/output-structure.test.ts index 260157ae..4145eaab 100644 --- a/packages/wxt/e2e/tests/output-structure.test.ts +++ b/packages/wxt/e2e/tests/output-structure.test.ts @@ -262,9 +262,6 @@ describe('Output Directory Structure', () => { project.addFile('entrypoints/popup/main.ts', `logHello('popup')`); await project.build({ - // Simplify the build output for comparison - extensionApi: 'chrome', - vite: () => ({ build: { // Make output for snapshot readible @@ -289,11 +286,7 @@ describe('Output Directory Structure', () => { logHello("background"); } }); - // @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 - ); + ((_b = (_a = globalThis.browser) == null ? void 0 : _a.runtime) == null ? void 0 : _b.id) ? globalThis.browser : globalThis.chrome; function print(method, ...args) { return; } @@ -347,9 +340,6 @@ describe('Output Directory Structure', () => { project.addFile('entrypoints/popup/main.ts', `logHello('popup')`); await project.build({ - // Simplify the build output for comparison - extensionApi: 'chrome', - vite: () => ({ build: { // Make output for snapshot readible @@ -381,11 +371,7 @@ describe('Output Directory Structure', () => { background; function initPlugins() { } - // @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 - ); + ((_b = (_a = globalThis.browser) == null ? void 0 : _a.runtime) == null ? void 0 : _b.id) ? globalThis.browser : globalThis.chrome; function print(method, ...args) { return; } diff --git a/packages/wxt/e2e/tests/user-config.test.ts b/packages/wxt/e2e/tests/user-config.test.ts index b120bf87..0ee4a969 100644 --- a/packages/wxt/e2e/tests/user-config.test.ts +++ b/packages/wxt/e2e/tests/user-config.test.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest'; import { TestProject } from '../utils'; -import { InlineConfig } from '../../src/types'; describe('User Config', () => { // Root directory is tested with all tests. @@ -88,24 +87,6 @@ describe('User Config', () => { `); }); - 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(); - projectWithPolyfill.addFile('entrypoints/background.ts', background); - await projectWithPolyfill.build(config); - return await projectWithPolyfill.serializeFile( - '.output/chrome-mv3/background.js', - ); - }; - - const withPolyfill = await buildBackground(); - const withoutPolyfill = await buildBackground({ - extensionApi: 'chrome', - }); - expect(withoutPolyfill).not.toBe(withPolyfill); - }); - it('should respect changing config files', async () => { const project = new TestProject(); project.addFile( diff --git a/packages/wxt/package.json b/packages/wxt/package.json index 39ca18ad..03583adb 100644 --- a/packages/wxt/package.json +++ b/packages/wxt/package.json @@ -47,12 +47,8 @@ "default": "./dist/sandbox/index.mjs" }, "./browser": { - "types": "./dist/browser/index.d.ts", - "default": "./dist/browser/index.mjs" - }, - "./browser/chrome": { - "types": "./dist/browser/chrome.d.ts", - "import": "./dist/browser/chrome.mjs" + "types": "./dist/browser.d.ts", + "default": "./dist/browser.mjs" }, "./testing": { "types": "./dist/testing/index.d.ts", @@ -84,11 +80,10 @@ "dependencies": { "@1natsu/wait-element": "catalog:", "@aklinker1/rollup-plugin-visualizer": "catalog:", - "@types/chrome": "catalog:", - "@types/webextension-polyfill": "catalog:", "@webext-core/fake-browser": "catalog:", "@webext-core/isolated-element": "catalog:", "@webext-core/match-patterns": "catalog:", + "@wxt-dev/browser": "workspace:*", "@wxt-dev/storage": "workspace:^1.0.0", "async-mutex": "catalog:", "c12": "catalog:", @@ -128,8 +123,7 @@ "unimport": "catalog:", "vite": "catalog:", "vite-node": "catalog:", - "web-ext-run": "catalog:", - "webextension-polyfill": "catalog:" + "web-ext-run": "catalog:" }, "devDependencies": { "@aklinker1/check": "catalog:", @@ -149,9 +143,5 @@ "vitest": "catalog:", "vitest-plugin-random-seed": "catalog:" }, - "peerDependenciesMeta": { - "@types/chrome": { - "optional": true - } - } + "peerDependenciesMeta": {} } diff --git a/packages/wxt/src/browser.ts b/packages/wxt/src/browser.ts new file mode 100644 index 00000000..9f0b96fd --- /dev/null +++ b/packages/wxt/src/browser.ts @@ -0,0 +1,25 @@ +/** + * @module wxt/browser + */ +import { browser as _browser, type Browser } from '@wxt-dev/browser'; + +/** + * This interface is empty because it is generated per-project when running `wxt prepare`. See: + * - `.wxt/types/paths.d.ts` + */ +export interface WxtRuntime {} + +/** + * This interface is empty because it is generated per-project when running `wxt prepare`. See: + * - `.wxt/types/i18n.d.ts` + */ +export interface WxtI18n {} + +export type WxtBrowser = Omit & { + runtime: WxtRuntime & Omit<(typeof _browser)['runtime'], 'getURL'>; + i18n: WxtI18n & Omit<(typeof _browser)['i18n'], 'getMessage'>; +}; + +export const browser: WxtBrowser = _browser; + +export { Browser }; diff --git a/packages/wxt/src/browser/chrome.ts b/packages/wxt/src/browser/chrome.ts deleted file mode 100644 index d1dad85d..00000000 --- a/packages/wxt/src/browser/chrome.ts +++ /dev/null @@ -1,23 +0,0 @@ -/// -/** - * EXPERIMENTAL - * - * Includes the `chrome` API and types when using `extensionApi: 'chrome'`. - * - * @module wxt/browser/chrome - */ -import type { WxtRuntime, WxtI18n } from './index'; - -export type WxtBrowser = Omit & { - runtime: WxtRuntime & Omit<(typeof chrome)['runtime'], 'getURL'>; - i18n: WxtI18n & Omit<(typeof chrome)['i18n'], 'getMessage'>; -}; - -// #region snippet -export const browser: WxtBrowser = - // @ts-expect-error - globalThis.browser?.runtime?.id == null - ? globalThis.chrome - : // @ts-expect-error - globalThis.browser; -// #endregion snippet diff --git a/packages/wxt/src/browser/index.ts b/packages/wxt/src/browser/index.ts deleted file mode 100644 index 8e21e1fb..00000000 --- a/packages/wxt/src/browser/index.ts +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Includes the `browser` API and types when using `extensionApi: 'webextension-polyfill'` (the default). - * - * @module wxt/browser - */ - -import originalBrowser, { Browser } from 'webextension-polyfill'; - -export type AugmentedBrowser = Omit & { - runtime: WxtRuntime & Omit; - i18n: WxtI18n & Omit; -}; - -/** - * This interface is empty because it is generated per-project when running `wxt prepare`. See: - * - `.wxt/types/paths.d.ts` - */ -export interface WxtRuntime {} - -/** - * This interface is empty because it is generated per-project when running `wxt prepare`. See: - * - `.wxt/types/i18n.d.ts` - */ -export interface WxtI18n {} - -export const browser: AugmentedBrowser = originalBrowser; - -// re-export all the types from webextension-polyfill -// Because webextension-polyfill uses a weird namespace with "import export", there isn't a good way -// to get these types without re-listing them. -/** @ignore */ -export type { - ActivityLog, - Alarms, - Bookmarks, - Action, - BrowserAction, - BrowserSettings, - BrowsingData, - CaptivePortal, - Clipboard, - Commands, - ContentScripts, - ContextualIdentities, - Cookies, - DeclarativeNetRequest, - Devtools, - Dns, - Downloads, - Events, - Experiments, - Extension, - ExtensionTypes, - Find, - GeckoProfiler, - History, - I18n, - Identity, - Idle, - Management, - Manifest, // TODO: Export custom manifest types that are valid for both Chrome and Firefox. - ContextMenus, - Menus, - NetworkStatus, - NormandyAddonStudy, - Notifications, - Omnibox, - PageAction, - Permissions, - Pkcs11, - Privacy, - Proxy, - Runtime, - Scripting, - Search, - Sessions, - SidebarAction, - Storage, - Tabs, - Theme, - TopSites, - Types, - UserScripts, - WebNavigation, - WebRequest, - Windows, -} from 'webextension-polyfill'; diff --git a/packages/wxt/src/client/content-scripts/__tests__/content-script-context.test.ts b/packages/wxt/src/client/content-scripts/__tests__/content-script-context.test.ts index 23ff12e8..548beb3d 100644 --- a/packages/wxt/src/client/content-scripts/__tests__/content-script-context.test.ts +++ b/packages/wxt/src/client/content-scripts/__tests__/content-script-context.test.ts @@ -24,7 +24,7 @@ describe('Content Script Context', () => { const onInvalidated = vi.fn(); ctx.onInvalidated(onInvalidated); - // @ts-expect-error + // @ts-ignore delete fakeBrowser.runtime.id; const isValid = ctx.isValid; diff --git a/packages/wxt/src/core/builders/vite/index.ts b/packages/wxt/src/core/builders/vite/index.ts index 545c6339..24bbe5d9 100644 --- a/packages/wxt/src/core/builders/vite/index.ts +++ b/packages/wxt/src/core/builders/vite/index.ts @@ -83,7 +83,6 @@ export async function createViteBuilder( wxtPlugins.tsconfigPaths(wxtConfig), wxtPlugins.noopBackground(), wxtPlugins.globals(wxtConfig), - wxtPlugins.resolveExtensionApi(wxtConfig), wxtPlugins.defineImportMeta(), wxtPlugins.wxtPluginLoader(wxtConfig), wxtPlugins.resolveAppConfig(wxtConfig), diff --git a/packages/wxt/src/core/builders/vite/plugins/extensionApiMock.ts b/packages/wxt/src/core/builders/vite/plugins/extensionApiMock.ts index 7724219e..0e2b18f3 100644 --- a/packages/wxt/src/core/builders/vite/plugins/extensionApiMock.ts +++ b/packages/wxt/src/core/builders/vite/plugins/extensionApiMock.ts @@ -3,12 +3,7 @@ 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. + * Mock `wxt/browser` and stub the global `browser`/`chrome` types with a fake version of the extension APIs */ export function extensionApiMock(config: ResolvedConfig): vite.PluginOption { const virtualSetupModule = 'virtual:wxt-setup'; @@ -27,14 +22,12 @@ export function extensionApiMock(config: ResolvedConfig): vite.PluginOption { }, resolve: { alias: [ - { find: 'webextension-polyfill', replacement }, // wxt/browser, wxt/browser/... - { find: /^wxt\/browser.*/, replacement }, + { find: 'wxt/browser', replacement }, ], }, ssr: { - // Inline all WXT modules so vite processes them so the aliases can - // be resolved + // Inline all WXT modules subdependencies can be mocked noExternal: ['wxt'], }, }; diff --git a/packages/wxt/src/core/builders/vite/plugins/index.ts b/packages/wxt/src/core/builders/vite/plugins/index.ts index f70dde24..5ed13ff8 100644 --- a/packages/wxt/src/core/builders/vite/plugins/index.ts +++ b/packages/wxt/src/core/builders/vite/plugins/index.ts @@ -9,7 +9,6 @@ export * from './cssEntrypoints'; export * from './bundleAnalysis'; export * from './globals'; export * from './extensionApiMock'; -export * from './resolveExtensionApi'; export * from './entrypointGroupGlobals'; export * from './defineImportMeta'; export * from './removeEntrypointMainFunction'; diff --git a/packages/wxt/src/core/builders/vite/plugins/resolveExtensionApi.ts b/packages/wxt/src/core/builders/vite/plugins/resolveExtensionApi.ts deleted file mode 100644 index 17ec0206..00000000 --- a/packages/wxt/src/core/builders/vite/plugins/resolveExtensionApi.ts +++ /dev/null @@ -1,27 +0,0 @@ -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' }, - ], - }, - }; - }, - }; -} diff --git a/packages/wxt/src/core/generate-wxt-dir.ts b/packages/wxt/src/core/generate-wxt-dir.ts index e7d35949..3e58d778 100644 --- a/packages/wxt/src/core/generate-wxt-dir.ts +++ b/packages/wxt/src/core/generate-wxt-dir.ts @@ -37,11 +37,6 @@ export async function generateWxtDir(entrypoints: Entrypoint[]): Promise { // import.meta.env.* entries.push(await getGlobalsDeclarationEntry()); - // @types/chrome - if (wxt.config.extensionApi === 'chrome') { - entries.push({ module: '@types/chrome' }); - } - // tsconfig.json entries.push(await getTsConfigEntry()); diff --git a/packages/wxt/src/core/resolve-config.ts b/packages/wxt/src/core/resolve-config.ts index 01c38ca2..d5a9b15a 100644 --- a/packages/wxt/src/core/resolve-config.ts +++ b/packages/wxt/src/core/resolve-config.ts @@ -171,8 +171,6 @@ export async function resolveConfig( {}, ); - const extensionApi = mergedConfig.extensionApi ?? 'webextension-polyfill'; - return { browser, command, @@ -182,13 +180,7 @@ export async function resolveConfig( filterEntrypoints, env, fsCache: createFsCache(wxtDir), - imports: await getUnimportOptions( - wxtDir, - srcDir, - logger, - extensionApi, - mergedConfig, - ), + imports: await getUnimportOptions(wxtDir, srcDir, logger, mergedConfig), logger, manifest: await resolveManifestConfig(env, mergedConfig.manifest), manifestVersion, @@ -207,7 +199,6 @@ export async function resolveConfig( analysis: resolveAnalysisConfig(root, mergedConfig), userConfigMetadata: userConfigMetadata ?? {}, alias, - extensionApi, entrypointLoader: mergedConfig.entrypointLoader ?? 'vite-node', experimental: defu(mergedConfig.experimental, {}), dev: { @@ -342,7 +333,6 @@ async function getUnimportOptions( wxtDir: string, srcDir: string, logger: Logger, - extensionApi: ResolvedConfig['extensionApi'], config: InlineConfig, ): Promise { if (config.imports === false) return false; @@ -361,10 +351,7 @@ async function getUnimportOptions( // ignored. ignore: ['options'], }, - { - package: - extensionApi === 'chrome' ? 'wxt/browser/chrome' : 'wxt/browser', - }, + { package: 'wxt/browser' }, { package: 'wxt/sandbox' }, { package: 'wxt/storage' }, ], diff --git a/packages/wxt/src/core/utils/__tests__/manifest.test.ts b/packages/wxt/src/core/utils/__tests__/manifest.test.ts index 230f1470..1a767d10 100644 --- a/packages/wxt/src/core/utils/__tests__/manifest.test.ts +++ b/packages/wxt/src/core/utils/__tests__/manifest.test.ts @@ -13,7 +13,6 @@ import { fakeWxtDevServer, setFakeWxt, } from '../testing/fake-objects'; -import { Manifest } from 'webextension-polyfill'; import { BuildOutput, ContentScriptEntrypoint, @@ -22,6 +21,7 @@ import { } from '../../../types'; import { wxt } from '../../wxt'; import { mock } from 'vitest-mock-extended'; +import type { Browser } from '@wxt-dev/browser'; const outDir = '/output'; const contentScriptOutDir = '/output/content-scripts'; @@ -58,7 +58,7 @@ describe('Manifest Utils', () => { outDir, }, }); - const expected: Partial = { + const expected: Partial = { action: { default_icon: popup.options.defaultIcon, default_title: popup.options.defaultTitle, diff --git a/packages/wxt/src/core/utils/building/rebuild.ts b/packages/wxt/src/core/utils/building/rebuild.ts index 7a17e3ff..b0902f5c 100644 --- a/packages/wxt/src/core/utils/building/rebuild.ts +++ b/packages/wxt/src/core/utils/building/rebuild.ts @@ -1,9 +1,9 @@ -import type { Manifest } from 'wxt/browser'; import { BuildOutput, Entrypoint, EntrypointGroup } from '../../../types'; import { generateWxtDir } from '../../generate-wxt-dir'; import { buildEntrypoints } from './build-entrypoints'; import { generateManifest, writeManifest } from '../../utils/manifest'; import { wxt } from '../../wxt'; +import type { Browser } from '@wxt-dev/browser'; /** * Given a configuration, list of entrypoints, and an existing, partial output, build the @@ -30,7 +30,7 @@ export async function rebuild( }, ): Promise<{ output: BuildOutput; - manifest: Manifest.WebExtensionManifest; + manifest: Browser.runtime.Manifest; warnings: any[][]; }> { const { default: ora } = await import('ora'); diff --git a/packages/wxt/src/core/utils/content-scripts.ts b/packages/wxt/src/core/utils/content-scripts.ts index 3ba1eb18..93f00d8a 100644 --- a/packages/wxt/src/core/utils/content-scripts.ts +++ b/packages/wxt/src/core/utils/content-scripts.ts @@ -1,6 +1,7 @@ -import type { Manifest, Scripting } from 'wxt/browser'; +import type { Browser } from '@wxt-dev/browser'; import { ContentScriptEntrypoint, ResolvedConfig } from '../../types'; import { getEntrypointBundlePath } from './entrypoints'; +import { ManifestContentScript } from './types'; /** * Returns a unique and consistent string hash based on a content scripts options. @@ -22,13 +23,14 @@ export function hashContentScriptOptions( if (simplifiedOptions[key] == null) delete simplifiedOptions[key]; }); - const withDefaults: Manifest.ContentScript = { + const withDefaults: ManifestContentScript = { exclude_globs: [], exclude_matches: [], include_globs: [], match_about_blank: false, run_at: 'document_idle', all_frames: false, + // @ts-expect-error: Untyped match_origin_as_fallback: false, world: 'ISOLATED', ...simplifiedOptions, @@ -49,7 +51,7 @@ export function mapWxtOptionsToContentScript( options: ContentScriptEntrypoint['options'], js: string[] | undefined, css: string[] | undefined, -): Manifest.ContentScript { +): ManifestContentScript { return { matches: options.matches ?? [], all_frames: options.allFrames, @@ -61,6 +63,7 @@ export function mapWxtOptionsToContentScript( css, js, + // @ts-expect-error: Untyped match_origin_as_fallback: options.matchOriginAsFallback, world: options.world, }; @@ -70,7 +73,7 @@ export function mapWxtOptionsToRegisteredContentScript( options: ContentScriptEntrypoint['options'], js: string[] | undefined, css: string[] | undefined, -): Omit { +): Omit { return { allFrames: options.allFrames, excludeMatches: options.excludeMatches, diff --git a/packages/wxt/src/core/utils/manifest.ts b/packages/wxt/src/core/utils/manifest.ts index 364f749f..7b0d3388 100644 --- a/packages/wxt/src/core/utils/manifest.ts +++ b/packages/wxt/src/core/utils/manifest.ts @@ -1,4 +1,3 @@ -import type { Manifest } from 'wxt/browser'; import { Entrypoint, BackgroundEntrypoint, @@ -21,12 +20,14 @@ import { normalizePath } from './paths'; import { writeFileIfDifferent } from './fs'; import defu from 'defu'; import { wxt } from '../wxt'; +import { ManifestV3WebAccessibleResource } from './types'; +import type { Browser } from '@wxt-dev/browser'; /** * Writes the manifest to the output directory and the build output. */ export async function writeManifest( - manifest: Manifest.WebExtensionManifest, + manifest: Browser.runtime.Manifest, output: BuildOutput, ): Promise { const str = @@ -49,7 +50,7 @@ export async function writeManifest( export async function generateManifest( allEntrypoints: Entrypoint[], buildOutput: Omit, -): Promise<{ manifest: Manifest.WebExtensionManifest; warnings: any[][] }> { +): Promise<{ manifest: Browser.runtime.Manifest; warnings: any[][] }> { const entrypoints = allEntrypoints.filter((entry) => !entry.skipped); const warnings: any[][] = []; @@ -67,7 +68,7 @@ export async function generateManifest( } const version = wxt.config.manifest.version ?? simplifyVersion(versionName); - const baseManifest: Manifest.WebExtensionManifest = { + const baseManifest: Browser.runtime.Manifest = { manifest_version: wxt.config.manifestVersion, name: pkg?.name, description: pkg?.description, @@ -83,10 +84,7 @@ export async function generateManifest( ); } - let manifest = defu( - userManifest, - baseManifest, - ) as Manifest.WebExtensionManifest; + let manifest = defu(userManifest, baseManifest) as Browser.runtime.Manifest; // Add reload command in dev mode if (wxt.config.command === 'serve' && wxt.config.dev.reloadCommand) { @@ -177,7 +175,7 @@ function simplifyVersion(versionName: string): string { } function addEntrypoints( - manifest: Manifest.WebExtensionManifest, + manifest: Browser.runtime.Manifest, entrypoints: Entrypoint[], buildOutput: Omit, ): void { @@ -239,7 +237,6 @@ function addEntrypoints( ); } else { manifest.chrome_url_overrides ??= {}; - // @ts-expect-error: bookmarks is untyped in webextension-polyfill, but supported by chrome manifest.chrome_url_overrides.bookmarks = getEntrypointBundlePath( bookmarks, wxt.config.outDir, @@ -255,7 +252,6 @@ function addEntrypoints( ); } else { manifest.chrome_url_overrides ??= {}; - // @ts-expect-error: history is untyped in webextension-polyfill, but supported by chrome manifest.chrome_url_overrides.history = getEntrypointBundlePath( history, wxt.config.outDir, @@ -279,12 +275,13 @@ function addEntrypoints( wxt.config.outDir, '.html', ); - const options: Manifest.ActionManifest = {}; + const options: Browser.runtime.ManifestAction = {}; if (popup.options.defaultIcon) options.default_icon = popup.options.defaultIcon; if (popup.options.defaultTitle) options.default_title = popup.options.defaultTitle; if (popup.options.browserStyle) + // @ts-expect-error: Not typed by @wxt-dev/browser, but supported by Firefox options.browser_style = popup.options.browserStyle; if (manifest.manifest_version === 3) { manifest.action = { @@ -314,6 +311,7 @@ function addEntrypoints( const page = getEntrypointBundlePath(options, wxt.config.outDir, '.html'); manifest.options_ui = { open_in_tab: options.options.openInTab, + // @ts-expect-error: Not typed by @wxt-dev/browser, but supported by Firefox browser_style: wxt.config.browser === 'firefox' ? options.options.browserStyle @@ -332,7 +330,6 @@ function addEntrypoints( 'Sandboxed pages not supported by Firefox. sandbox.pages was not added to the manifest', ); } else { - // @ts-expect-error: sandbox not typed manifest.sandbox = { pages: sandboxes.map((entry) => getEntrypointBundlePath(entry, wxt.config.outDir, '.html'), @@ -359,7 +356,6 @@ function addEntrypoints( open_at_install: defaultSidepanel.options.openAtInstall, }; } else if (wxt.config.manifestVersion === 3) { - // @ts-expect-error: Untyped manifest.side_panel = { default_path: page, }; @@ -432,7 +428,7 @@ function addEntrypoints( function discoverIcons( buildOutput: Omit, -): Manifest.WebExtensionManifest['icons'] { +): Browser.runtime.Manifest['icons'] { const icons: [string, string][] = []; // prettier-ignore // #region snippet @@ -464,7 +460,7 @@ function discoverIcons( return icons.length > 0 ? Object.fromEntries(icons) : undefined; } -function addDevModeCsp(manifest: Manifest.WebExtensionManifest): void { +function addDevModeCsp(manifest: Browser.runtime.Manifest): void { const permission = `http://${wxt.server?.hostname ?? ''}/*`; const allowedCsp = wxt.server?.origin ?? 'http://localhost:*'; @@ -499,7 +495,7 @@ function addDevModeCsp(manifest: Manifest.WebExtensionManifest): void { manifest.content_security_policy.sandbox = sandboxCsp.toString(); } -function addDevModePermissions(manifest: Manifest.WebExtensionManifest) { +function addDevModePermissions(manifest: Browser.runtime.Manifest) { // For reloading the page addPermission(manifest, 'tabs'); @@ -543,8 +539,7 @@ export function getContentScriptCssWebAccessibleResources( contentScripts: ContentScriptEntrypoint[], contentScriptCssMap: Record, ): any[] { - const resources: Manifest.WebExtensionManifestWebAccessibleResourcesC2ItemType[] = - []; + const resources: ManifestV3WebAccessibleResource[] = []; contentScripts.forEach((script) => { if (script.options.cssInjectionMode !== 'ui') return; @@ -554,9 +549,10 @@ export function getContentScriptCssWebAccessibleResources( resources.push({ resources: [cssFile], - matches: script.options.matches?.map((matchPattern) => - stripPathFromMatchPattern(matchPattern), - ), + matches: + script.options.matches?.map((matchPattern) => + stripPathFromMatchPattern(matchPattern), + ) ?? [], }); }); @@ -583,16 +579,18 @@ export function getContentScriptsCssMap( } function addPermission( - manifest: Manifest.WebExtensionManifest, + manifest: Browser.runtime.Manifest, permission: string, ): void { manifest.permissions ??= []; + // @ts-expect-error: Allow using strings for permissions for MV2 support if (manifest.permissions.includes(permission)) return; + // @ts-expect-error: Allow using strings for permissions for MV2 support manifest.permissions.push(permission); } function addHostPermission( - manifest: Manifest.WebExtensionManifest, + manifest: Browser.runtime.Manifest, hostPermission: string, ): void { manifest.host_permissions ??= []; @@ -618,7 +616,7 @@ export function stripPathFromMatchPattern(pattern: string) { * targeting MV2, automatically convert their definitions down to the basic MV2 array. */ export function convertWebAccessibleResourcesToMv2( - manifest: Manifest.WebExtensionManifest, + manifest: Browser.runtime.Manifest, ): void { if (manifest.web_accessible_resources == null) return; @@ -633,17 +631,17 @@ export function convertWebAccessibleResourcesToMv2( } function moveHostPermissionsToPermissions( - manifest: Manifest.WebExtensionManifest, + manifest: Browser.runtime.Manifest, ): void { if (!manifest.host_permissions?.length) return; - manifest.host_permissions.forEach((permission) => + manifest.host_permissions.forEach((permission: string) => addPermission(manifest, permission), ); delete manifest.host_permissions; } -function convertActionToMv2(manifest: Manifest.WebExtensionManifest): void { +function convertActionToMv2(manifest: Browser.runtime.Manifest): void { if ( manifest.action == null || manifest.browser_action != null || @@ -654,7 +652,7 @@ function convertActionToMv2(manifest: Manifest.WebExtensionManifest): void { manifest.browser_action = manifest.action; } -function convertCspToMv2(manifest: Manifest.WebExtensionManifest): void { +function convertCspToMv2(manifest: Browser.runtime.Manifest): void { if ( typeof manifest.content_security_policy === 'string' || manifest.content_security_policy?.extension_pages == null @@ -668,8 +666,8 @@ function convertCspToMv2(manifest: Manifest.WebExtensionManifest): void { /** * Make sure all resources are in MV3 format. If not, add a wanring */ -export function validateMv3WebAccessibleResources( - manifest: Manifest.WebExtensionManifest, +function validateMv3WebAccessibleResources( + manifest: Browser.runtime.Manifest, ): void { if (manifest.web_accessible_resources == null) return; @@ -688,7 +686,7 @@ export function validateMv3WebAccessibleResources( /** * Remove keys from the manifest based on the build target. */ -function stripKeys(manifest: Manifest.WebExtensionManifest): void { +function stripKeys(manifest: Browser.runtime.Manifest): void { let keysToRemove: string[] = []; if (wxt.config.manifestVersion === 2) { keysToRemove.push(...mv3OnlyKeys); @@ -699,7 +697,7 @@ function stripKeys(manifest: Manifest.WebExtensionManifest): void { } keysToRemove.forEach((key) => { - delete manifest[key as keyof Manifest.WebExtensionManifest]; + delete manifest[key as keyof Browser.runtime.Manifest]; }); } diff --git a/packages/wxt/src/core/utils/testing/fake-objects.ts b/packages/wxt/src/core/utils/testing/fake-objects.ts index 0586d7fb..eeef953b 100644 --- a/packages/wxt/src/core/utils/testing/fake-objects.ts +++ b/packages/wxt/src/core/utils/testing/fake-objects.ts @@ -4,7 +4,6 @@ import { resolve } from 'path'; import { faker } from '@faker-js/faker'; import merge from 'lodash.merge'; -import type { Manifest } from 'wxt/browser'; import { FsCache, ResolvedConfig, @@ -27,6 +26,7 @@ import { import { mock } from 'vitest-mock-extended'; import { vi } from 'vitest'; import { setWxtForTesting } from '../../../core/wxt'; +import type { Browser } from '@wxt-dev/browser'; faker.seed(import.meta.test.SEED); @@ -208,13 +208,11 @@ export function fakeOutputFile(): OutputFile { return faker.helpers.arrayElement([fakeOutputAsset(), fakeOutputChunk()]); } -export const fakeManifest = fakeObjectCreator( - () => ({ - manifest_version: faker.helpers.arrayElement([2, 3]), - name: faker.string.alphanumeric(), - version: `${faker.number.int()}.${faker.number.int()}.${faker.number.int()}`, - }), -); +export const fakeManifest = fakeObjectCreator(() => ({ + manifest_version: faker.helpers.arrayElement([2, 3]), + name: faker.string.alphanumeric(), + version: `${faker.number.int()}.${faker.number.int()}.${faker.number.int()}`, +})); export const fakeUserManifest = fakeObjectCreator(() => ({ name: faker.string.alphanumeric(), @@ -299,7 +297,6 @@ export const fakeResolvedConfig = fakeObjectCreator(() => { transformManifest: () => {}, userConfigMetadata: {}, alias: {}, - extensionApi: 'webextension-polyfill', entrypointLoader: 'vite-node', experimental: {}, dev: { @@ -356,8 +353,8 @@ export const fakeBuildStepOutput = fakeObjectCreator(() => ({ entrypoints: fakeArray(fakeEntrypoint), })); -export const fakeManifestCommand = - fakeObjectCreator(() => ({ +export const fakeManifestCommand = fakeObjectCreator( + () => ({ description: faker.string.sample(), suggested_key: { default: `${faker.helpers.arrayElement(['ctrl', 'alt'])}+${faker.number.int( @@ -367,7 +364,8 @@ export const fakeManifestCommand = }, )}`, }, - })); + }), +); export const fakeDevServer = fakeObjectCreator(() => ({ hostname: 'localhost', diff --git a/packages/wxt/src/core/utils/transform.ts b/packages/wxt/src/core/utils/transform.ts index f6951c61..857fdcff 100644 --- a/packages/wxt/src/core/utils/transform.ts +++ b/packages/wxt/src/core/utils/transform.ts @@ -5,7 +5,7 @@ import { ProxifiedModule, parseModule } from 'magicast'; * 1. Removes or clears out `main` function from returned object * 2. Removes any unused functions/variables outside the definition that aren't being called/used * 3. Removes unused imports - * 3. Removes value-less, side-effect only imports (like `import "./styles.css"` or `import "webextension-polyfill"`) + * 3. Removes value-less, side-effect only imports (like `import "./styles.css"` or `import "polyfill"`) */ export function removeMainFunctionCode(code: string): { code: string; diff --git a/packages/wxt/src/core/utils/types.ts b/packages/wxt/src/core/utils/types.ts index ed6ff200..9755088a 100644 --- a/packages/wxt/src/core/utils/types.ts +++ b/packages/wxt/src/core/utils/types.ts @@ -1,3 +1,5 @@ +import type { Browser } from '@wxt-dev/browser'; + /** * Remove optional from key, but keep undefined if present * @@ -6,3 +8,11 @@ * // type Test = {a: string | undefined, b: number} */ export type NullablyRequired = { [K in keyof Required]: T[K] }; + +export type ManifestContentScript = NonNullable< + Browser.runtime.Manifest['content_scripts'] +>[number]; + +export type ManifestV3WebAccessibleResource = NonNullable< + Browser.runtime.ManifestV3['web_accessible_resources'] +>[number]; diff --git a/packages/wxt/src/types.ts b/packages/wxt/src/types.ts index 187ecb1f..1d6f29bf 100644 --- a/packages/wxt/src/types.ts +++ b/packages/wxt/src/types.ts @@ -1,5 +1,4 @@ import type * as vite from 'vite'; -import type { Manifest, Scripting } from 'wxt/browser'; import { UnimportOptions, Import } from 'unimport'; import { LogLevel } from 'consola'; import type { ContentScriptContext } from './client/content-scripts/content-script-context'; @@ -7,6 +6,8 @@ import type { PluginVisualizerOptions } from '@aklinker1/rollup-plugin-visualize import { ResolvedConfig as C12ResolvedConfig } from 'c12'; import { Hookable, NestedHooks } from 'hookable'; import type * as Nypm from 'nypm'; +import { ManifestContentScript } from './core/utils/types'; +import type { Browser } from '@wxt-dev/browser'; export interface InlineConfig { /** @@ -267,7 +268,7 @@ export interface InlineConfig { * } * }) */ - transformManifest?: (manifest: Manifest.WebExtensionManifest) => void; + transformManifest?: (manifest: Browser.runtime.Manifest) => void; analysis?: { /** * Explicitly include bundle analysis when running `wxt build`. This can be overridden by the @@ -325,16 +326,6 @@ export interface InlineConfig { * } */ alias?: Record; - /** - * Which extension API to use. - * - * - `"webextension-polyfill"`: Use `browser` and types from [`webextension-polyfill`](https://www.npmjs.com/package/webextension-polyfill). - * - `"chrome"`: Use the regular `chrome` (or `browser` for Firefox/Safari) globals provided by the browser. Types provided by [`@types/chrome`](https://www.npmjs.com/package/@types/chrome). - * - * @default "webextension-polyfill" - * @since 0.19.0 - */ - extensionApi?: 'webextension-polyfill' | 'chrome'; /** * @deprecated Will be removed in v0.20.0, please migrate to using `vite-node`, the new default. * @@ -444,7 +435,7 @@ export interface WxtHooks { } export interface BuildOutput { - manifest: Manifest.WebExtensionManifest; + manifest: Browser.runtime.Manifest; publicAssets: OutputAsset[]; steps: BuildStepOutput[]; } @@ -537,7 +528,7 @@ export interface WxtDevServer export interface ReloadContentScriptPayload { registration?: BaseContentScriptEntrypointOptions['registration']; - contentScript: Omit; + contentScript: Omit; } export type TargetBrowser = string; @@ -588,39 +579,39 @@ export interface BackgroundEntrypointOptions extends BaseEntrypointOptions { export interface BaseContentScriptEntrypointOptions extends BaseEntrypointOptions { - matches?: PerBrowserOption; + matches?: PerBrowserOption>; /** * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/ * @default "documentIdle" */ - runAt?: PerBrowserOption; + runAt?: PerBrowserOption; /** * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/ * @default false */ matchAboutBlank?: PerBrowserOption< - Manifest.ContentScript['match_about_blank'] + ManifestContentScript['match_about_blank'] >; /** * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/ * @default [] */ - excludeMatches?: PerBrowserOption; + excludeMatches?: PerBrowserOption; /** * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/ * @default [] */ - includeGlobs?: PerBrowserOption; + includeGlobs?: PerBrowserOption; /** * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/ * @default [] */ - excludeGlobs?: PerBrowserOption; + excludeGlobs?: PerBrowserOption; /** * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/ * @default false */ - allFrames?: PerBrowserOption; + allFrames?: PerBrowserOption; /** * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/ * @default false @@ -868,7 +859,7 @@ export type ResolvedPerBrowserOptions = { * here, they are configured inline. */ export type UserManifest = { - [key in keyof chrome.runtime.ManifestV3 as key extends + [key in keyof Browser.runtime.ManifestV3 as key extends | 'action' | 'background' | 'chrome_url_overrides' @@ -880,16 +871,16 @@ export type UserManifest = { | 'sandbox' | 'web_accessible_resources' ? never - : key]?: chrome.runtime.ManifestV3[key]; + : key]?: Browser.runtime.ManifestV3[key]; } & { // Add any Browser-specific or MV2 properties that WXT supports here - action?: chrome.runtime.ManifestV3['action'] & { + action?: Browser.runtime.ManifestV3['action'] & { browser_style?: boolean; }; - browser_action?: chrome.runtime.ManifestV2['browser_action'] & { + browser_action?: Browser.runtime.ManifestV2['browser_action'] & { browser_style?: boolean; }; - page_action?: chrome.runtime.ManifestV2['page_action'] & { + page_action?: Browser.runtime.ManifestV2['page_action'] & { browser_style?: boolean; }; browser_specific_settings?: { @@ -909,12 +900,12 @@ export type UserManifest = { }; }; permissions?: ( - | chrome.runtime.ManifestPermissions + | Browser.runtime.ManifestPermissions | (string & Record) )[]; web_accessible_resources?: | string[] - | chrome.runtime.ManifestV3['web_accessible_resources']; + | Browser.runtime.ManifestV3['web_accessible_resources']; }; export type UserManifestFn = ( @@ -1187,7 +1178,7 @@ export interface WxtHooks { */ 'build:manifestGenerated': ( wxt: Wxt, - manifest: Manifest.WebExtensionManifest, + manifest: Browser.runtime.Manifest, ) => HookResult; /** * Called once the names and paths of all entrypoints have been resolved. @@ -1359,7 +1350,7 @@ export interface ResolvedConfig { /** * @deprecated Use `build:manifestGenerated` hook instead. */ - transformManifest?: (manifest: Manifest.WebExtensionManifest) => void; + transformManifest?: (manifest: Browser.runtime.Manifest) => void; analysis: { enabled: boolean; open: boolean; @@ -1377,7 +1368,6 @@ export interface ResolvedConfig { * Import aliases to absolute paths. */ alias: Record; - extensionApi: 'webextension-polyfill' | 'chrome'; entrypointLoader: 'vite-node' | 'jiti'; experimental: {}; dev: { diff --git a/packages/wxt/src/virtual/utils/reload-content-scripts.ts b/packages/wxt/src/virtual/utils/reload-content-scripts.ts index 11b5e0c8..3b82417a 100644 --- a/packages/wxt/src/virtual/utils/reload-content-scripts.ts +++ b/packages/wxt/src/virtual/utils/reload-content-scripts.ts @@ -84,7 +84,7 @@ async function reloadTabsForContentScript(contentScript: ContentScript) { await Promise.all( matchingTabs.map(async (tab) => { try { - await browser.tabs.reload(tab.id); + await browser.tabs.reload(tab.id!); } catch (err) { logger.warn('Failed to reload tab:', err); } diff --git a/packages/wxt/src/virtual/virtual-module-globals.d.ts b/packages/wxt/src/virtual/virtual-module-globals.d.ts index 5199a83a..0b70bcf1 100644 --- a/packages/wxt/src/virtual/virtual-module-globals.d.ts +++ b/packages/wxt/src/virtual/virtual-module-globals.d.ts @@ -21,7 +21,7 @@ declare module 'virtual:user-unlisted-script-entrypoint' { } declare module 'wxt/browser' { - export const browser: import('webextension-polyfill').Browser; + export { browser, Browser } from '@wxt-dev/browser'; } declare module 'virtual:wxt-plugins' { diff --git a/packages/wxt/typedoc.json b/packages/wxt/typedoc.json index d9edaddf..fa919313 100644 --- a/packages/wxt/typedoc.json +++ b/packages/wxt/typedoc.json @@ -3,8 +3,7 @@ "src/client/index.ts", "src/testing/index.ts", "src/sandbox/index.ts", - "src/browser/index.ts", - "src/browser/chrome.ts", + "src/browser.ts", "src/index.ts", "src/modules.ts", "src/storage.ts" diff --git a/packages/wxt/vitest.config.ts b/packages/wxt/vitest.config.ts index 8bb1d0da..0c25b962 100644 --- a/packages/wxt/vitest.config.ts +++ b/packages/wxt/vitest.config.ts @@ -11,6 +11,7 @@ export default defineConfig({ include: ['src/**'], exclude: ['**/dist', '**/__tests__', 'src/utils/testing'], }, + setupFiles: ['./vitest.setup.ts'], globalSetup: ['./vitest.globalSetup.ts'], }, server: { @@ -22,7 +23,6 @@ export default defineConfig({ resolve: { alias: { 'wxt/testing': path.resolve('src/testing'), - 'webextension-polyfill': path.resolve('src/virtual/mock-browser'), }, }, }); diff --git a/packages/wxt/vitest.setup.ts b/packages/wxt/vitest.setup.ts new file mode 100644 index 00000000..a828762f --- /dev/null +++ b/packages/wxt/vitest.setup.ts @@ -0,0 +1,5 @@ +import { fakeBrowser } from '@webext-core/fake-browser'; +import { vi } from 'vitest'; + +vi.stubGlobal('chrome', fakeBrowser); +vi.stubGlobal('browser', fakeBrowser); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d461ccb5..ce82ef83 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,9 +57,6 @@ catalogs: '@types/ua-parser-js': specifier: ^0.7.39 version: 0.7.39 - '@types/webextension-polyfill': - specifier: ^0.12.1 - version: 0.12.1 '@vitejs/plugin-react': specifier: ^4.3.4 version: 4.3.4 @@ -297,9 +294,6 @@ catalogs: web-ext-run: specifier: ^0.2.1 version: 0.2.1 - webextension-polyfill: - specifier: ^0.12.0 - version: 0.12.0 patchedDependencies: markdown-it-footnote: @@ -698,12 +692,6 @@ importers: '@aklinker1/rollup-plugin-visualizer': specifier: 'catalog:' version: 5.12.0(rollup@4.34.9) - '@types/chrome': - specifier: 'catalog:' - version: 0.0.280 - '@types/webextension-polyfill': - specifier: 'catalog:' - version: 0.12.1 '@webext-core/fake-browser': specifier: 'catalog:' version: 1.3.1 @@ -713,6 +701,9 @@ importers: '@webext-core/match-patterns': specifier: 'catalog:' version: 1.0.3 + '@wxt-dev/browser': + specifier: workspace:* + version: link:../browser '@wxt-dev/storage': specifier: workspace:^1.0.0 version: link:../storage @@ -833,9 +824,6 @@ importers: web-ext-run: specifier: 'catalog:' version: 0.2.1 - webextension-polyfill: - specifier: 'catalog:' - version: 0.12.0 devDependencies: '@aklinker1/check': specifier: 'catalog:' @@ -2324,9 +2312,6 @@ packages: '@types/web-bluetooth@0.0.20': resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} - '@types/webextension-polyfill@0.12.1': - resolution: {integrity: sha512-xPTFWwQ8BxPevPF2IKsf4hpZNss4LxaOLZXypQH4E63BDLmcwX/RMGdI4tB4VO4Nb6xDBH3F/p4gz4wvof1o9w==} - '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} @@ -5365,9 +5350,6 @@ packages: resolution: {integrity: sha512-5D11VcjdGkA1/xax5UWL0YeAbDySKHzWFe6EpsoPNUMw5Uk9tKk9p6GUOfcaI5N7sINKfBMZYNsTBiu5dzJB9A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} - webextension-polyfill@0.12.0: - resolution: {integrity: sha512-97TBmpoWJEE+3nFBQ4VocyCdLKfw54rFaJ6EVQYLBCXqCIpLSZkwGgASpv4oPt9gdKCJ80RJlcmNzNn008Ag6Q==} - webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} @@ -6664,8 +6646,6 @@ snapshots: '@types/web-bluetooth@0.0.20': {} - '@types/webextension-polyfill@0.12.1': {} - '@types/yauzl@2.10.3': dependencies: '@types/node': 20.17.6 @@ -10092,8 +10072,6 @@ snapshots: - supports-color - utf-8-validate - webextension-polyfill@0.12.0: {} - webidl-conversions@7.0.0: {} webpack-sources@3.2.3: diff --git a/templates/react/wxt.config.ts b/templates/react/wxt.config.ts index d1e35387..429f2b90 100644 --- a/templates/react/wxt.config.ts +++ b/templates/react/wxt.config.ts @@ -2,6 +2,5 @@ import { defineConfig } from 'wxt'; // See https://wxt.dev/api/config.html export default defineConfig({ - extensionApi: 'chrome', modules: ['@wxt-dev/module-react'], }); diff --git a/templates/solid/wxt.config.ts b/templates/solid/wxt.config.ts index 0a5a994f..1cc7596d 100644 --- a/templates/solid/wxt.config.ts +++ b/templates/solid/wxt.config.ts @@ -2,6 +2,5 @@ import { defineConfig } from 'wxt'; // See https://wxt.dev/api/config.html export default defineConfig({ - extensionApi: 'chrome', modules: ['@wxt-dev/module-solid'], }); diff --git a/templates/svelte/wxt.config.ts b/templates/svelte/wxt.config.ts index f0e4f9aa..5749b4e6 100644 --- a/templates/svelte/wxt.config.ts +++ b/templates/svelte/wxt.config.ts @@ -3,6 +3,5 @@ import { defineConfig } from 'wxt'; // See https://wxt.dev/api/config.html export default defineConfig({ srcDir: 'src', - extensionApi: 'chrome', modules: ['@wxt-dev/module-svelte'], }); diff --git a/templates/vanilla/wxt.config.ts b/templates/vanilla/wxt.config.ts index 35c7ade7..1e2f53d3 100644 --- a/templates/vanilla/wxt.config.ts +++ b/templates/vanilla/wxt.config.ts @@ -1,6 +1,4 @@ import { defineConfig } from 'wxt'; // See https://wxt.dev/api/config.html -export default defineConfig({ - extensionApi: 'chrome', -}); +export default defineConfig({}); diff --git a/templates/vue/wxt.config.ts b/templates/vue/wxt.config.ts index 2ab714b1..55fbc4af 100644 --- a/templates/vue/wxt.config.ts +++ b/templates/vue/wxt.config.ts @@ -2,6 +2,5 @@ import { defineConfig } from 'wxt'; // See https://wxt.dev/api/config.html export default defineConfig({ - extensionApi: 'chrome', modules: ['@wxt-dev/module-vue'], });