diff --git a/docs/guide/essentials/extension-apis.md b/docs/guide/essentials/extension-apis.md index 529558d83..d014f98fd 100644 --- a/docs/guide/essentials/extension-apis.md +++ b/docs/guide/essentials/extension-apis.md @@ -4,52 +4,29 @@ 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`. - -## 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. +:::tip +With auto-imports enabled, you don't even need to import this variable from `wxt/browser`! +::: -You can disable it with a single line: +The `browser` variable WXT provides is a simple export of the `browser` or `chrome` globals provided by the browser at runtime: -```ts -// wxt.config.ts -export default defineConfig({ - extensionApi: 'chrome', -}); -``` +<<< @/../packages/wxt/src/browser.ts#snippet -This will change `wxt/browser` to simply export the `browser` or `chrome` globals based on browser at runtime: +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). -<<< @/../packages/wxt/src/browser/chrome.ts#snippet +## Accessing Types -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: +All types can be accessed via WXT's `browser` object: ```ts function handleMessage(message: any, sender: browser.runtime.Sender) { @@ -59,7 +36,7 @@ function handleMessage(message: any, sender: browser.runtime.Sender) { ## 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/wxt-demo/src/entrypoints/__tests__/background.test.ts b/packages/wxt-demo/src/entrypoints/__tests__/background.test.ts index 62f79bed1..0383bac5a 100644 --- a/packages/wxt-demo/src/entrypoints/__tests__/background.test.ts +++ b/packages/wxt-demo/src/entrypoints/__tests__/background.test.ts @@ -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 57f8d5204..f92b5ae63 100644 --- a/packages/wxt-demo/wxt.config.ts +++ b/packages/wxt-demo/wxt.config.ts @@ -2,7 +2,6 @@ import { defineConfig } from 'wxt'; export default defineConfig({ srcDir: 'src', - extensionApi: 'chrome', manifest: { permissions: ['storage'], default_locale: 'en', diff --git a/packages/wxt/e2e/tests/auto-imports.test.ts b/packages/wxt/e2e/tests/auto-imports.test.ts index 167b33a44..118c52e2b 100644 --- a/packages/wxt/e2e/tests/auto-imports.test.ts +++ b/packages/wxt/e2e/tests/auto-imports.test.ts @@ -54,6 +54,7 @@ describe('Auto Imports', () => { /// /// /// + /// /// " `); @@ -93,6 +94,7 @@ describe('Auto Imports', () => { /// /// /// + /// " `, ); diff --git a/packages/wxt/e2e/tests/modules.test.ts b/packages/wxt/e2e/tests/modules.test.ts index 367099b52..1108ddbe6 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 260157ae7..f882b8595 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 @@ -347,9 +344,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 diff --git a/packages/wxt/e2e/tests/typescript-project.test.ts b/packages/wxt/e2e/tests/typescript-project.test.ts index 34c372af6..20e8e8db0 100644 --- a/packages/wxt/e2e/tests/typescript-project.test.ts +++ b/packages/wxt/e2e/tests/typescript-project.test.ts @@ -238,6 +238,7 @@ describe('TypeScript Project', () => { /// /// /// + /// /// " `); diff --git a/packages/wxt/e2e/tests/user-config.test.ts b/packages/wxt/e2e/tests/user-config.test.ts index c0b497508..b444b07b8 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 eb44a03c3..ab9b4f5c0 100644 --- a/packages/wxt/package.json +++ b/packages/wxt/package.json @@ -46,12 +46,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", @@ -83,7 +79,6 @@ "dependencies": { "@aklinker1/rollup-plugin-visualizer": "5.12.0", "@types/chrome": "^0.0.269", - "@types/webextension-polyfill": "^0.10.7", "@webext-core/fake-browser": "^1.3.1", "@webext-core/isolated-element": "^1.1.2", "@webext-core/match-patterns": "^1.0.3", @@ -124,8 +119,7 @@ "unimport": "^3.13.1", "vite": "^5.4.8", "vite-node": "^2.1.2", - "web-ext-run": "^0.2.1", - "webextension-polyfill": "^0.12.0" + "web-ext-run": "^0.2.1" }, "devDependencies": { "@aklinker1/check": "^1.4.5", diff --git a/packages/wxt/src/browser/chrome.ts b/packages/wxt/src/browser.ts similarity index 56% rename from packages/wxt/src/browser/chrome.ts rename to packages/wxt/src/browser.ts index d1dad85db..10cd6e8b9 100644 --- a/packages/wxt/src/browser/chrome.ts +++ b/packages/wxt/src/browser.ts @@ -1,12 +1,19 @@ /// /** - * EXPERIMENTAL - * - * Includes the `chrome` API and types when using `extensionApi: 'chrome'`. - * - * @module wxt/browser/chrome + * @module wxt/browser */ -import type { WxtRuntime, WxtI18n } from './index'; + +/** + * 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 chrome)['runtime'], 'getURL'>; diff --git a/packages/wxt/src/browser/index.ts b/packages/wxt/src/browser/index.ts deleted file mode 100644 index 3eb44e110..000000000 --- a/packages/wxt/src/browser/index.ts +++ /dev/null @@ -1,88 +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, - Urlbar, - 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 6f7d14c18..099c9453f 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 @@ -16,7 +16,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 6ab15ab4a..5fa87581c 100644 --- a/packages/wxt/src/core/builders/vite/index.ts +++ b/packages/wxt/src/core/builders/vite/index.ts @@ -74,7 +74,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 7724219ec..0e2b18f3a 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 f70dde240..5ed13ff81 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 17ec02064..000000000 --- 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 cf9980c7f..dfa3149b9 100644 --- a/packages/wxt/src/core/generate-wxt-dir.ts +++ b/packages/wxt/src/core/generate-wxt-dir.ts @@ -37,10 +37,8 @@ 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' }); - } + // wxt/browser types + 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 e99dbb10b..4209cb823 100644 --- a/packages/wxt/src/core/resolve-config.ts +++ b/packages/wxt/src/core/resolve-config.ts @@ -162,8 +162,6 @@ export async function resolveConfig( {}, ); - const extensionApi = mergedConfig.extensionApi ?? 'webextension-polyfill'; - return { browser, command, @@ -173,13 +171,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, @@ -198,7 +190,6 @@ export async function resolveConfig( analysis: resolveAnalysisConfig(root, mergedConfig), userConfigMetadata: userConfigMetadata ?? {}, alias, - extensionApi, entrypointLoader: mergedConfig.entrypointLoader ?? 'vite-node', experimental: defu(mergedConfig.experimental, {}), dev: { @@ -333,7 +324,6 @@ async function getUnimportOptions( wxtDir: string, srcDir: string, logger: Logger, - extensionApi: ResolvedConfig['extensionApi'], config: InlineConfig, ): Promise { if (config.imports === false) return false; @@ -352,10 +342,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 1af508dc5..56fdd1efe 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, @@ -56,7 +55,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 7a17e3ff1..4e7a6c7a5 100644 --- a/packages/wxt/src/core/utils/building/rebuild.ts +++ b/packages/wxt/src/core/utils/building/rebuild.ts @@ -1,4 +1,3 @@ -import type { Manifest } from 'wxt/browser'; import { BuildOutput, Entrypoint, EntrypointGroup } from '../../../types'; import { generateWxtDir } from '../../generate-wxt-dir'; import { buildEntrypoints } from './build-entrypoints'; @@ -30,7 +29,7 @@ export async function rebuild( }, ): Promise<{ output: BuildOutput; - manifest: Manifest.WebExtensionManifest; + manifest: chrome.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 d9b1425dd..cfb6db3e6 100644 --- a/packages/wxt/src/core/utils/content-scripts.ts +++ b/packages/wxt/src/core/utils/content-scripts.ts @@ -1,6 +1,6 @@ -import type { Manifest, Scripting } from 'wxt/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,7 +22,7 @@ export function hashContentScriptOptions( if (simplifiedOptions[key] == null) delete simplifiedOptions[key]; }); - const withDefaults: Manifest.ContentScript = { + const withDefaults: ManifestContentScript = { exclude_globs: [], exclude_matches: [], include_globs: [], @@ -50,7 +50,7 @@ export function mapWxtOptionsToContentScript( options: ContentScriptEntrypoint['options'], js: string[] | undefined, css: string[] | undefined, -): Manifest.ContentScript { +): ManifestContentScript { return { matches: options.matches, all_frames: options.allFrames, @@ -72,7 +72,7 @@ export function mapWxtOptionsToRegisteredContentScript( options: ContentScriptEntrypoint['options'], js: string[] | undefined, css: string[] | undefined, -): Omit { +): Omit { return { allFrames: options.allFrames, excludeMatches: options.excludeMatches, @@ -80,7 +80,6 @@ export function mapWxtOptionsToRegisteredContentScript( runAt: options.runAt, js, css, - // @ts-expect-error: Chrome accepts this, not typed in webextension-polyfill (https://developer.chrome.com/docs/extensions/reference/scripting/#type-RegisteredContentScript) world: options.world, }; } diff --git a/packages/wxt/src/core/utils/manifest.ts b/packages/wxt/src/core/utils/manifest.ts index 17a9feb1f..e04efedd3 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,13 @@ import { normalizePath } from './paths'; import { writeFileIfDifferent } from './fs'; import defu from 'defu'; import { wxt } from '../wxt'; +import { ManifestV3WebAccessibleResource } from './types'; /** * Writes the manifest to the output directory and the build output. */ export async function writeManifest( - manifest: Manifest.WebExtensionManifest, + manifest: chrome.runtime.Manifest, output: BuildOutput, ): Promise { const str = @@ -49,7 +49,7 @@ export async function writeManifest( export async function generateManifest( entrypoints: Entrypoint[], buildOutput: Omit, -): Promise<{ manifest: Manifest.WebExtensionManifest; warnings: any[][] }> { +): Promise<{ manifest: chrome.runtime.Manifest; warnings: any[][] }> { const warnings: any[][] = []; const pkg = await getPackageJson(); @@ -65,7 +65,7 @@ export async function generateManifest( } const version = wxt.config.manifest.version ?? simplifyVersion(versionName); - const baseManifest: Manifest.WebExtensionManifest = { + const baseManifest: chrome.runtime.Manifest = { manifest_version: wxt.config.manifestVersion, name: pkg?.name, description: pkg?.description, @@ -75,10 +75,7 @@ export async function generateManifest( }; const userManifest = wxt.config.manifest; - let manifest = defu( - userManifest, - baseManifest, - ) as Manifest.WebExtensionManifest; + let manifest = defu(userManifest, baseManifest) as chrome.runtime.Manifest; // Add reload command in dev mode if (wxt.config.command === 'serve' && wxt.config.dev.reloadCommand) { @@ -121,7 +118,7 @@ export async function generateManifest( } if (wxt.config.manifestVersion === 3) { - validateMv3WebAccessbileResources(manifest); + validateMv3WebAccessibleResources(manifest); } stripKeys(manifest); @@ -143,7 +140,7 @@ export async function generateManifest( } /** - * Removes suffixes from the version, like X.Y.Z-alpha1 (which brosers don't allow), so it's a + * Removes suffixes from the version, like X.Y.Z-alpha1 (which browsers don't allow), so it's a * simple version number, like X or X.Y or X.Y.Z, which browsers allow. */ function simplifyVersion(versionName: string): string { @@ -161,7 +158,7 @@ function simplifyVersion(versionName: string): string { } function addEntrypoints( - manifest: Manifest.WebExtensionManifest, + manifest: chrome.runtime.Manifest, entrypoints: Entrypoint[], buildOutput: Omit, ): void { @@ -223,7 +220,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, @@ -239,7 +235,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, @@ -263,12 +258,13 @@ function addEntrypoints( wxt.config.outDir, '.html', ); - const options: Manifest.ActionManifest = {}; + const options: chrome.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 @types/chrome, but supported by Firefox options.browser_style = popup.options.browserStyle; if (manifest.manifest_version === 3) { manifest.action = { @@ -298,6 +294,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 @types/chrome, but supported by Firefox browser_style: wxt.config.browser === 'firefox' ? options.options.browserStyle @@ -316,7 +313,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'), @@ -343,7 +339,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, }; @@ -424,7 +419,7 @@ function addEntrypoints( function discoverIcons( buildOutput: Omit, -): Manifest.WebExtensionManifest['icons'] { +): chrome.runtime.Manifest['icons'] { const icons: [string, string][] = []; // prettier-ignore // #region snippet @@ -456,7 +451,7 @@ function discoverIcons( return icons.length > 0 ? Object.fromEntries(icons) : undefined; } -function addDevModeCsp(manifest: Manifest.WebExtensionManifest): void { +function addDevModeCsp(manifest: chrome.runtime.Manifest): void { const permission = `http://${wxt.server?.hostname ?? ''}/*`; const allowedCsp = wxt.server?.origin ?? 'http://localhost:*'; @@ -468,8 +463,7 @@ function addDevModeCsp(manifest: Manifest.WebExtensionManifest): void { const extensionPagesCsp = new ContentSecurityPolicy( manifest.manifest_version === 3 - ? // @ts-expect-error: extension_pages is not typed - (manifest.content_security_policy?.extension_pages ?? + ? (manifest.content_security_policy?.extension_pages ?? "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';") // default extension_pages CSP for MV3 : (manifest.content_security_policy ?? "script-src 'self'; object-src 'self';"), // default CSP for MV2 @@ -487,17 +481,15 @@ function addDevModeCsp(manifest: Manifest.WebExtensionManifest): void { if (manifest.manifest_version === 3) { manifest.content_security_policy ??= {}; - // @ts-expect-error: extension_pages is not typed manifest.content_security_policy.extension_pages = extensionPagesCsp.toString(); - // @ts-expect-error: sandbox is not typed manifest.content_security_policy.sandbox = sandboxCsp.toString(); } else { manifest.content_security_policy = extensionPagesCsp.toString(); } } -function addDevModePermissions(manifest: Manifest.WebExtensionManifest) { +function addDevModePermissions(manifest: chrome.runtime.Manifest) { // For reloading the page addPermission(manifest, 'tabs'); @@ -541,8 +533,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; @@ -581,16 +572,18 @@ export function getContentScriptsCssMap( } function addPermission( - manifest: Manifest.WebExtensionManifest, + manifest: chrome.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: chrome.runtime.Manifest, hostPermission: string, ): void { manifest.host_permissions ??= []; @@ -613,10 +606,10 @@ export function stripPathFromMatchPattern(pattern: string) { /** * Converts all MV3 web accessible resources to their MV2 forms. MV3 web accessible resources are * generated in this file, and may be defined by the user in their manifest. In both cases, when - * targetting MV2, automatically convert their definitions down to the basic MV2 array. + * targeting MV2, automatically convert their definitions down to the basic MV2 array. */ export function convertWebAccessibleResourcesToMv2( - manifest: Manifest.WebExtensionManifest, + manifest: chrome.runtime.Manifest, ): void { if (manifest.web_accessible_resources == null) return; @@ -631,17 +624,17 @@ export function convertWebAccessibleResourcesToMv2( } function moveHostPermissionsToPermissions( - manifest: Manifest.WebExtensionManifest, + manifest: chrome.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: chrome.runtime.Manifest): void { if ( manifest.action == null || manifest.browser_action != null || @@ -655,8 +648,8 @@ function convertActionToMv2(manifest: Manifest.WebExtensionManifest): void { /** * Make sure all resources are in MV3 format. If not, add a wanring */ -export function validateMv3WebAccessbileResources( - manifest: Manifest.WebExtensionManifest, +function validateMv3WebAccessibleResources( + manifest: chrome.runtime.Manifest, ): void { if (manifest.web_accessible_resources == null) return; @@ -675,7 +668,7 @@ export function validateMv3WebAccessbileResources( /** * Remove keys from the manifest based on the build target. */ -function stripKeys(manifest: Manifest.WebExtensionManifest): void { +function stripKeys(manifest: chrome.runtime.Manifest): void { let keysToRemove: string[] = []; if (wxt.config.manifestVersion === 2) { keysToRemove.push(...mv3OnlyKeys); @@ -686,7 +679,7 @@ function stripKeys(manifest: Manifest.WebExtensionManifest): void { } keysToRemove.forEach((key) => { - delete manifest[key as keyof Manifest.WebExtensionManifest]; + delete manifest[key as keyof chrome.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 c097aeab7..db48364d2 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 { Commands, type Manifest } from 'wxt/browser'; import { FsCache, ResolvedConfig, @@ -207,13 +206,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(), @@ -298,7 +295,6 @@ export const fakeResolvedConfig = fakeObjectCreator(() => { transformManifest: () => {}, userConfigMetadata: {}, alias: {}, - extensionApi: 'webextension-polyfill', entrypointLoader: 'vite-node', experimental: {}, dev: { @@ -355,13 +351,17 @@ export const fakeBuildStepOutput = fakeObjectCreator(() => ({ entrypoints: fakeArray(fakeEntrypoint), })); -export const fakeManifestCommand = fakeObjectCreator(() => ({ - description: faker.string.sample(), - shortcut: `${faker.helpers.arrayElement(['ctrl', 'alt'])}+${faker.number.int({ - min: 0, - max: 9, - })}`, -})); +export const fakeManifestCommand = fakeObjectCreator( + () => ({ + description: faker.string.sample(), + shortcut: `${faker.helpers.arrayElement(['ctrl', 'alt'])}+${faker.number.int( + { + min: 0, + max: 9, + }, + )}`, + }), +); 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 f6951c614..857fdcff6 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 ed6ff2000..45d68dda9 100644 --- a/packages/wxt/src/core/utils/types.ts +++ b/packages/wxt/src/core/utils/types.ts @@ -6,3 +6,11 @@ * // type Test = {a: string | undefined, b: number} */ export type NullablyRequired = { [K in keyof Required]: T[K] }; + +export type ManifestContentScript = NonNullable< + chrome.runtime.Manifest['content_scripts'] +>[number]; + +export type ManifestV3WebAccessibleResource = NonNullable< + chrome.runtime.ManifestV3['web_accessible_resources'] +>[number]; diff --git a/packages/wxt/src/storage.ts b/packages/wxt/src/storage.ts index 55795d4a7..94c774b21 100644 --- a/packages/wxt/src/storage.ts +++ b/packages/wxt/src/storage.ts @@ -5,7 +5,7 @@ * * @module wxt/storage */ -import { Storage, browser } from 'wxt/browser'; +import { browser } from 'wxt/browser'; import { dequal } from 'dequal/lite'; import { logger } from './sandbox/utils/logger'; import { toArray } from './core/utils/arrays'; @@ -391,7 +391,7 @@ function createDriver(storageArea: StorageArea): WxtStorageDriver { return area; }; const watchListeners = new Set< - (changes: Storage.StorageAreaOnChangedChangesType) => void + (changes: Record) => void >(); return { getItem: async (key) => { @@ -432,7 +432,9 @@ function createDriver(storageArea: StorageArea): WxtStorageDriver { await getStorageArea().set(data); }, watch(key, cb) { - const listener = (changes: Storage.StorageAreaOnChangedChangesType) => { + const listener = ( + changes: Record, + ) => { const change = changes[key]; if (change == null) return; if (dequal(change.newValue, change.oldValue)) return; @@ -646,7 +648,7 @@ export interface WxtStorageItem< migrate(): Promise; } -export type StorageArea = 'local' | 'session' | 'sync' | 'managed'; +export type StorageArea = chrome.storage.AreaName; export type StorageItemKey = `${StorageArea}:${string}`; export interface GetItemOptions { diff --git a/packages/wxt/src/types.ts b/packages/wxt/src/types.ts index 3ad48acfe..8a258f0f5 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'; @@ -8,6 +7,7 @@ import type { FSWatcher } from 'chokidar'; import { ResolvedConfig as C12ResolvedConfig } from 'c12'; import { Hookable, NestedHooks } from 'hookable'; import type * as Nypm from 'nypm'; +import { ManifestContentScript } from './core/utils/types'; export interface InlineConfig { /** @@ -267,7 +267,7 @@ export interface InlineConfig { * } * }) */ - transformManifest?: (manifest: Manifest.WebExtensionManifest) => void; + transformManifest?: (manifest: chrome.runtime.Manifest) => void; analysis?: { /** * Explicitly include bundle analysis when running `wxt build`. This can be overridden by the @@ -325,16 +325,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 +434,7 @@ export interface WxtHooks { } export interface BuildOutput { - manifest: Manifest.WebExtensionManifest; + manifest: chrome.runtime.Manifest; publicAssets: OutputAsset[]; steps: BuildStepOutput[]; } @@ -537,7 +527,7 @@ export interface WxtDevServer export interface ReloadContentScriptPayload { registration?: BaseContentScriptEntrypointOptions['registration']; - contentScript: Omit; + contentScript: Omit; } export type TargetBrowser = string; @@ -588,39 +578,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 @@ -1163,7 +1153,7 @@ export interface WxtHooks { */ 'build:manifestGenerated': ( wxt: Wxt, - manifest: Manifest.WebExtensionManifest, + manifest: chrome.runtime.Manifest, ) => HookResult; /** * Called once all entrypoints have been loaded from the `entrypointsDir`. @@ -1316,7 +1306,7 @@ export interface ResolvedConfig { /** * @deprecated Use `build:manifestGenerated` hook instead. */ - transformManifest?: (manifest: Manifest.WebExtensionManifest) => void; + transformManifest?: (manifest: chrome.runtime.Manifest) => void; analysis: { enabled: boolean; open: boolean; @@ -1334,7 +1324,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/tsconfig.json b/packages/wxt/src/virtual/tsconfig.json index 6f74c3f88..0820153ad 100644 --- a/packages/wxt/src/virtual/tsconfig.json +++ b/packages/wxt/src/virtual/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../../../../tsconfig.base.json", "compilerOptions": { - "types": ["vite/client", "../@types/globals.d.ts"] + "types": ["vite/client", "../@types/globals.d.ts", "chrome"] }, "include": ["./*"] } diff --git a/packages/wxt/src/virtual/utils/reload-content-scripts.ts b/packages/wxt/src/virtual/utils/reload-content-scripts.ts index 11b5e0c87..3b82417ae 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 5199a83a9..fa95ef866 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 { chrome as browser }; } declare module 'virtual:wxt-plugins' { diff --git a/packages/wxt/typedoc.json b/packages/wxt/typedoc.json index 312472814..b5472db17 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/storage.ts", "src/modules.ts" diff --git a/packages/wxt/vitest.config.ts b/packages/wxt/vitest.config.ts index 8bb1d0dab..0c25b9629 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 000000000..a828762f2 --- /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 d94a395f8..a6d891145 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -257,9 +257,6 @@ importers: '@types/chrome': specifier: ^0.0.269 version: 0.0.269 - '@types/webextension-polyfill': - specifier: ^0.10.7 - version: 0.10.7 '@webext-core/fake-browser': specifier: ^1.3.1 version: 1.3.1 @@ -383,9 +380,6 @@ importers: web-ext-run: specifier: ^0.2.1 version: 0.2.1 - webextension-polyfill: - specifier: ^0.12.0 - version: 0.12.0 devDependencies: '@aklinker1/check': specifier: ^1.4.5 @@ -1731,9 +1725,6 @@ packages: '@types/web-bluetooth@0.0.20': resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} - '@types/webextension-polyfill@0.10.7': - resolution: {integrity: sha512-10ql7A0qzBmFB+F+qAke/nP1PIonS0TXZAOMVOxEUsm+lGSW6uwVcISFNa0I4Oyj0884TZVWGGMIWeXOVSNFHw==} - '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} @@ -4541,9 +4532,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'} @@ -5780,8 +5768,6 @@ snapshots: '@types/web-bluetooth@0.0.20': {} - '@types/webextension-polyfill@0.10.7': {} - '@types/yauzl@2.10.3': dependencies: '@types/node': 20.16.10 @@ -8879,8 +8865,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 d1e353878..429f2b90d 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 0a5a994ff..1cc7596d8 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 f0e4f9aa1..5749b4e62 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 35c7ade7f..1e2f53d37 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 2ab714b1c..55fbc4af6 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'], });