Skip to content

Commit 14ea7cc

Browse files
committed
feat!: Remove webextension-polyfill (#1084)
1 parent 842c158 commit 14ea7cc

39 files changed

+134
-359
lines changed

docs/guide/essentials/extension-apis.md

+12-35
Original file line numberDiff line numberDiff line change
@@ -4,52 +4,29 @@
44

55
Different browsers provide different global variables for accessing the extension APIs (chrome provides `chrome`, firefox provides `browser`, etc).
66

7-
WXT simplifies this - always use `browser`:
7+
WXT merges these two into a unified API accessed through the `browser` variable.
88

99
```ts
10+
import { browser } from 'wxt/browser';
11+
1012
browser.action.onClicked.addListener(() => {
1113
// ...
1214
});
1315
```
1416

15-
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`.
16-
17-
## Webextension Polyfill
18-
19-
> Since `v0.1.0`
20-
21-
By default, WXT uses the [`webextension-polyfill` by Mozilla](https://www.npmjs.com/package/webextension-polyfill) to make the extension API consistent between browsers.
22-
23-
To access types, you should import the relevant namespace from `wxt/browser`:
24-
25-
```ts
26-
import { Runtime } from 'wxt/browser';
27-
28-
function handleMessage(message: any, sender: Runtime.Sender) {
29-
// ...
30-
}
31-
```
32-
33-
### Disabling the polyfill
34-
35-
> Since `v0.19.0`
36-
37-
After the release of MV3 and Chrome's official deprecation of MV2 in June 2024, the polyfill isn't really doing anything useful anymore.
17+
:::tip
18+
With auto-imports enabled, you don't even need to import this variable from `wxt/browser`!
19+
:::
3820

39-
You can disable it with a single line:
21+
The `browser` variable WXT provides is a simple export of the `browser` or `chrome` globals provided by the browser at runtime:
4022

41-
```ts
42-
// wxt.config.ts
43-
export default defineConfig({
44-
extensionApi: 'chrome',
45-
});
46-
```
23+
<<< @/../packages/wxt/src/browser.ts#snippet
4724

48-
This will change `wxt/browser` to simply export the `browser` or `chrome` globals based on browser at runtime:
25+
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).
4926

50-
<<< @/../packages/wxt/src/browser/chrome.ts#snippet
27+
## Accessing Types
5128

52-
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:
29+
All types can be accessed via WXT's `browser` object:
5330

5431
```ts
5532
function handleMessage(message: any, sender: browser.runtime.Sender) {
@@ -59,7 +36,7 @@ function handleMessage(message: any, sender: browser.runtime.Sender) {
5936

6037
## Feature Detection
6138

62-
Depending on the manifest version and browser, some APIs are not available at runtime. If an API is not available, it will be `undefined`.
39+
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`.
6340

6441
:::warning
6542
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.

packages/wxt-demo/src/entrypoints/__tests__/background.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ describe('Background Entrypoint', () => {
1111
fakeBrowser.reset();
1212
});
1313

14-
it("should log the extenion's runtime ID", () => {
14+
it("should log the extension's runtime ID", () => {
1515
const id = 'some-id';
1616
fakeBrowser.runtime.id = id;
1717

packages/wxt-demo/wxt.config.ts

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { defineConfig } from 'wxt';
22

33
export default defineConfig({
44
srcDir: 'src',
5-
extensionApi: 'chrome',
65
manifest: {
76
permissions: ['storage'],
87
default_locale: 'en',

packages/wxt/e2e/tests/auto-imports.test.ts

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ describe('Auto Imports', () => {
5454
/// <reference types="./types/paths.d.ts" />
5555
/// <reference types="./types/i18n.d.ts" />
5656
/// <reference types="./types/globals.d.ts" />
57+
/// <reference types="@types/chrome" />
5758
/// <reference types="./types/imports.d.ts" />
5859
"
5960
`);
@@ -93,6 +94,7 @@ describe('Auto Imports', () => {
9394
/// <reference types="./types/paths.d.ts" />
9495
/// <reference types="./types/i18n.d.ts" />
9596
/// <reference types="./types/globals.d.ts" />
97+
/// <reference types="@types/chrome" />
9698
"
9799
`,
98100
);

packages/wxt/e2e/tests/modules.test.ts

+4-16
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,7 @@ describe('Module Helpers', () => {
191191
);
192192
const expectedText = addPluginModule(project);
193193

194-
await project.build({
195-
// reduce build output when comparing test failures
196-
extensionApi: 'chrome',
197-
});
194+
await project.build();
198195

199196
await expect(project.serializeOutput()).resolves.toContain(expectedText);
200197
});
@@ -211,10 +208,7 @@ describe('Module Helpers', () => {
211208
);
212209
const expectedText = addPluginModule(project);
213210

214-
await project.build({
215-
// reduce build output when comparing test failures
216-
extensionApi: 'chrome',
217-
});
211+
await project.build();
218212

219213
await expect(project.serializeOutput()).resolves.toContain(expectedText);
220214
});
@@ -232,10 +226,7 @@ describe('Module Helpers', () => {
232226
);
233227
const expectedText = addPluginModule(project);
234228

235-
await project.build({
236-
// reduce build output when comparing test failures
237-
extensionApi: 'chrome',
238-
});
229+
await project.build();
239230

240231
await expect(project.serializeOutput()).resolves.toContain(expectedText);
241232
});
@@ -248,10 +239,7 @@ describe('Module Helpers', () => {
248239
);
249240
const expectedText = addPluginModule(project);
250241

251-
await project.build({
252-
// reduce build output when comparing test failures
253-
extensionApi: 'chrome',
254-
});
242+
await project.build();
255243

256244
await expect(project.serializeOutput()).resolves.toContain(expectedText);
257245
});

packages/wxt/e2e/tests/output-structure.test.ts

-6
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,6 @@ describe('Output Directory Structure', () => {
262262
project.addFile('entrypoints/popup/main.ts', `logHello('popup')`);
263263

264264
await project.build({
265-
// Simplify the build output for comparison
266-
extensionApi: 'chrome',
267-
268265
vite: () => ({
269266
build: {
270267
// Make output for snapshot readible
@@ -347,9 +344,6 @@ describe('Output Directory Structure', () => {
347344
project.addFile('entrypoints/popup/main.ts', `logHello('popup')`);
348345

349346
await project.build({
350-
// Simplify the build output for comparison
351-
extensionApi: 'chrome',
352-
353347
vite: () => ({
354348
build: {
355349
// Make output for snapshot readible

packages/wxt/e2e/tests/typescript-project.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ describe('TypeScript Project', () => {
238238
/// <reference types="./types/paths.d.ts" />
239239
/// <reference types="./types/i18n.d.ts" />
240240
/// <reference types="./types/globals.d.ts" />
241+
/// <reference types="@types/chrome" />
241242
/// <reference types="./types/imports.d.ts" />
242243
"
243244
`);

packages/wxt/e2e/tests/user-config.test.ts

-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { describe, it, expect } from 'vitest';
22
import { TestProject } from '../utils';
3-
import { InlineConfig } from '../../src/types';
43

54
describe('User Config', () => {
65
// Root directory is tested with all tests.
@@ -88,24 +87,6 @@ describe('User Config', () => {
8887
`);
8988
});
9089

91-
it('should exclude the polyfill when extensionApi="chrome"', async () => {
92-
const buildBackground = async (config?: InlineConfig) => {
93-
const background = `export default defineBackground(() => console.log(browser.runtime.id));`;
94-
const projectWithPolyfill = new TestProject();
95-
projectWithPolyfill.addFile('entrypoints/background.ts', background);
96-
await projectWithPolyfill.build(config);
97-
return await projectWithPolyfill.serializeFile(
98-
'.output/chrome-mv3/background.js',
99-
);
100-
};
101-
102-
const withPolyfill = await buildBackground();
103-
const withoutPolyfill = await buildBackground({
104-
extensionApi: 'chrome',
105-
});
106-
expect(withoutPolyfill).not.toBe(withPolyfill);
107-
});
108-
10990
it('should respect changing config files', async () => {
11091
const project = new TestProject();
11192
project.addFile(

packages/wxt/package.json

+3-9
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,8 @@
4646
"default": "./dist/sandbox/index.mjs"
4747
},
4848
"./browser": {
49-
"types": "./dist/browser/index.d.ts",
50-
"default": "./dist/browser/index.mjs"
51-
},
52-
"./browser/chrome": {
53-
"types": "./dist/browser/chrome.d.ts",
54-
"import": "./dist/browser/chrome.mjs"
49+
"types": "./dist/browser.d.ts",
50+
"default": "./dist/browser.mjs"
5551
},
5652
"./testing": {
5753
"types": "./dist/testing/index.d.ts",
@@ -83,7 +79,6 @@
8379
"dependencies": {
8480
"@aklinker1/rollup-plugin-visualizer": "5.12.0",
8581
"@types/chrome": "^0.0.269",
86-
"@types/webextension-polyfill": "^0.10.7",
8782
"@webext-core/fake-browser": "^1.3.1",
8883
"@webext-core/isolated-element": "^1.1.2",
8984
"@webext-core/match-patterns": "^1.0.3",
@@ -124,8 +119,7 @@
124119
"unimport": "^3.13.1",
125120
"vite": "^5.4.8",
126121
"vite-node": "^2.1.2",
127-
"web-ext-run": "^0.2.1",
128-
"webextension-polyfill": "^0.12.0"
122+
"web-ext-run": "^0.2.1"
129123
},
130124
"devDependencies": {
131125
"@aklinker1/check": "^1.4.5",

packages/wxt/src/browser/chrome.ts packages/wxt/src/browser.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
/// <reference types="chrome" />
22
/**
3-
* EXPERIMENTAL
4-
*
5-
* Includes the `chrome` API and types when using `extensionApi: 'chrome'`.
6-
*
7-
* @module wxt/browser/chrome
3+
* @module wxt/browser
84
*/
9-
import type { WxtRuntime, WxtI18n } from './index';
5+
6+
/**
7+
* This interface is empty because it is generated per-project when running `wxt prepare`. See:
8+
* - `.wxt/types/paths.d.ts`
9+
*/
10+
export interface WxtRuntime {}
11+
12+
/**
13+
* This interface is empty because it is generated per-project when running `wxt prepare`. See:
14+
* - `.wxt/types/i18n.d.ts`
15+
*/
16+
export interface WxtI18n {}
1017

1118
export type WxtBrowser = Omit<typeof chrome, 'runtime' | 'i18n'> & {
1219
runtime: WxtRuntime & Omit<(typeof chrome)['runtime'], 'getURL'>;

packages/wxt/src/browser/index.ts

-88
This file was deleted.

packages/wxt/src/client/content-scripts/__tests__/content-script-context.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe('Content Script Context', () => {
1616
const onInvalidated = vi.fn();
1717

1818
ctx.onInvalidated(onInvalidated);
19-
// @ts-expect-error
19+
// @ts-ignore
2020
delete fakeBrowser.runtime.id;
2121
const isValid = ctx.isValid;
2222

packages/wxt/src/core/builders/vite/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ export async function createViteBuilder(
7474
wxtPlugins.tsconfigPaths(wxtConfig),
7575
wxtPlugins.noopBackground(),
7676
wxtPlugins.globals(wxtConfig),
77-
wxtPlugins.resolveExtensionApi(wxtConfig),
7877
wxtPlugins.defineImportMeta(),
7978
wxtPlugins.wxtPluginLoader(wxtConfig),
8079
wxtPlugins.resolveAppConfig(wxtConfig),

0 commit comments

Comments
 (0)