From ff1720a4c65a97305ffd74cd45305c29b1bab399 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Dec 2024 09:35:20 -0600 Subject: [PATCH] feat: Add `@wxt-dev/webextension-polyfill` module (#1310) --- .github/workflows/release.yml | 1 + .github/workflows/sync-releases.yml | 1 + docs/guide/essentials/extension-apis.md | 6 ++ docs/guide/resources/upgrading.md | 24 ++++++-- packages/webextension-polyfill/README.md | 18 ++++++ .../webextension-polyfill/build.config.ts | 15 +++++ .../entrypoints/content/index.ts | 6 ++ .../entrypoints/popup/index.html | 12 ++++ .../entrypoints/popup/main.ts | 3 + .../modules/webextension-polyfill/browser.ts | 1 + .../modules/webextension-polyfill/index.ts | 18 ++++++ packages/webextension-polyfill/package.json | 56 +++++++++++++++++++ packages/webextension-polyfill/public/.keep | 0 packages/webextension-polyfill/tsconfig.json | 4 ++ pnpm-lock.yaml | 40 +++++++++++++ 15 files changed, 200 insertions(+), 5 deletions(-) create mode 100644 packages/webextension-polyfill/README.md create mode 100644 packages/webextension-polyfill/build.config.ts create mode 100644 packages/webextension-polyfill/entrypoints/content/index.ts create mode 100644 packages/webextension-polyfill/entrypoints/popup/index.html create mode 100644 packages/webextension-polyfill/entrypoints/popup/main.ts create mode 100644 packages/webextension-polyfill/modules/webextension-polyfill/browser.ts create mode 100644 packages/webextension-polyfill/modules/webextension-polyfill/index.ts create mode 100644 packages/webextension-polyfill/package.json create mode 100644 packages/webextension-polyfill/public/.keep create mode 100644 packages/webextension-polyfill/tsconfig.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2e971e4f..c4fb5680 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,6 +16,7 @@ on: - module-vue - storage - unocss + - webextension-polyfill - wxt permissions: diff --git a/.github/workflows/sync-releases.yml b/.github/workflows/sync-releases.yml index 3d0663fa..7e6ddca0 100644 --- a/.github/workflows/sync-releases.yml +++ b/.github/workflows/sync-releases.yml @@ -15,6 +15,7 @@ on: - module-svelte - module-vue - storage + - webextension-polyfill - wxt permissions: diff --git a/docs/guide/essentials/extension-apis.md b/docs/guide/essentials/extension-apis.md index 5d0187b9..89b58115 100644 --- a/docs/guide/essentials/extension-apis.md +++ b/docs/guide/essentials/extension-apis.md @@ -36,6 +36,12 @@ function handleMessage(message: any, sender: Browser.runtime.MessageSender) { } ``` +## Using `webextension-polyfill` + +If you want to use the `webextension-polyfill` when importing `browser`, you can do so by installing the `@wxt-dev/webextension-polyfill` package. + +See it's [Installation Guide](https://github.com/wxt-dev/wxt/blob/main/packages/webextension-polyfill/README.md) to get started. + ## Feature Detection 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`. diff --git a/docs/guide/resources/upgrading.md b/docs/guide/resources/upgrading.md index e7ed8d1d..44b40d55 100644 --- a/docs/guide/resources/upgrading.md +++ b/docs/guide/resources/upgrading.md @@ -31,12 +31,11 @@ WXT no longer uses the `webextension-polyfill` internally and `wxt/browser` uses To upgrade, you have two options: 1. **Stop using the polyfill** - - No changes required, this is the default behavior of v0.20. Your extension will likely continue to work, but do some manual testing to confirm. + - Replace any manual imports from `wxt/browser/chrome` with `wxt/browser` 2. **Continue using the polyfill** - - Install the polyfill, types (if you use typescript), and WXT's [new polyfill module](https://www.npmjs.com/package/@wxt-dev/webextension-polyfill): + - Install the polyfill and WXT's [new polyfill module](https://www.npmjs.com/package/@wxt-dev/webextension-polyfill): ```sh - pnpm i webextension-polyfill - pnpm i -D @types/webextension-polyfill @wxt-dev/webextension-polyfill + pnpm i webextension-polyfill @wxt-dev/webextension-polyfill ``` - Add the WXT module to your config: ```ts @@ -46,7 +45,7 @@ To upgrade, you have two options: }); ``` -Additionally, the `extensionApi` config has been removed. Remove it from your `wxt.config.ts` file if present: +Regardless of your choice, the `extensionApi` config has been removed. Remove it from your `wxt.config.ts` file if present: ```ts // wxt.config.ts @@ -55,6 +54,21 @@ export default defineConfig({ }); ``` +Additionally, extension API types have changed. `wxt/browser` now uses types from `@types/chrome` instead of `@types/webextension-polyfill`. You will have to migrate any type imports to use `@types/chrome`'s namespace approach: + + +```ts +import type { Runtime } from 'wxt/browser'; // [!code --] +import { browser } from 'wxt/browser'; // [!code ++] + +function getMessageSenderUrl(sender: Runtime.MessageSender): string { // [!code --] +function getMessageSenderUrl(sender: browser.runtime.MessageSender): string { // [!code ++] + // ... +} +``` + +`@types/chrome` are more up-to-date, contain less bugs, and don't have any auto-generated names. So even if you continue to use the polyfill, you will need to update your types to use these types. + ### `public/` and `modules/` Directories Moved The default location for the `public/` and `modules/` directories have changed to better align with standards set by other frameworks (Nuxt, Next, Astro, etc). Now, each path is relative to the project's root directory. diff --git a/packages/webextension-polyfill/README.md b/packages/webextension-polyfill/README.md new file mode 100644 index 00000000..8dffa772 --- /dev/null +++ b/packages/webextension-polyfill/README.md @@ -0,0 +1,18 @@ +# `@wxt-dev/webextension-polyfill` + +Configures `wxt/browser` to import `browser` from [`webextension-polyfill`](https://github.com/mozilla/webextension-polyfill) instead of using the regular `chrome`/`browser` globals WXT normally provides. + +## Usage + +```sh +pnpm i @wxt-dev/webextension-polyfill webextension-polyfill +``` + +Then add the module to your config: + +```ts +// wxt.config.ts +export default defineConfig({ + modules: ['@wxt-dev/webextension-polyfill'], +}); +``` diff --git a/packages/webextension-polyfill/build.config.ts b/packages/webextension-polyfill/build.config.ts new file mode 100644 index 00000000..64a6c1bf --- /dev/null +++ b/packages/webextension-polyfill/build.config.ts @@ -0,0 +1,15 @@ +import { defineBuildConfig } from 'unbuild'; +import { resolve } from 'node:path'; + +export default defineBuildConfig({ + rootDir: resolve(__dirname, 'modules/webextension-polyfill'), + outDir: resolve(__dirname, 'dist'), + entries: [ + { input: 'index.ts', name: 'index' }, + { input: 'browser.ts', name: 'browser' }, + ], + replace: { + 'process.env.NPM': 'true', + }, + declaration: true, +}); diff --git a/packages/webextension-polyfill/entrypoints/content/index.ts b/packages/webextension-polyfill/entrypoints/content/index.ts new file mode 100644 index 00000000..87ad9f39 --- /dev/null +++ b/packages/webextension-polyfill/entrypoints/content/index.ts @@ -0,0 +1,6 @@ +export default defineContentScript({ + matches: ['*://*/*'], + async main() { + console.log(browser.runtime.id); + }, +}); diff --git a/packages/webextension-polyfill/entrypoints/popup/index.html b/packages/webextension-polyfill/entrypoints/popup/index.html new file mode 100644 index 00000000..a6d6644f --- /dev/null +++ b/packages/webextension-polyfill/entrypoints/popup/index.html @@ -0,0 +1,12 @@ + + + + + + Document + + +
+ + + diff --git a/packages/webextension-polyfill/entrypoints/popup/main.ts b/packages/webextension-polyfill/entrypoints/popup/main.ts new file mode 100644 index 00000000..3677c7ed --- /dev/null +++ b/packages/webextension-polyfill/entrypoints/popup/main.ts @@ -0,0 +1,3 @@ +const root = document.getElementById('app')!; + +root.textContent = browser.runtime.id; diff --git a/packages/webextension-polyfill/modules/webextension-polyfill/browser.ts b/packages/webextension-polyfill/modules/webextension-polyfill/browser.ts new file mode 100644 index 00000000..c86e9ce3 --- /dev/null +++ b/packages/webextension-polyfill/modules/webextension-polyfill/browser.ts @@ -0,0 +1 @@ +export { default as browser } from 'webextension-polyfill'; diff --git a/packages/webextension-polyfill/modules/webextension-polyfill/index.ts b/packages/webextension-polyfill/modules/webextension-polyfill/index.ts new file mode 100644 index 00000000..6114cad1 --- /dev/null +++ b/packages/webextension-polyfill/modules/webextension-polyfill/index.ts @@ -0,0 +1,18 @@ +import 'wxt'; +import { addViteConfig, defineWxtModule } from 'wxt/modules'; +import { resolve } from 'node:path'; + +export default defineWxtModule({ + name: '@wxt-dev/webextension-polyfill', + setup(wxt) { + addViteConfig(wxt, () => ({ + resolve: { + alias: { + 'wxt/browser': process.env.NPM + ? '@wxt-dev/webextension-polyfill/browser' + : resolve(__dirname, 'browser.ts'), + }, + }, + })); + }, +}); diff --git a/packages/webextension-polyfill/package.json b/packages/webextension-polyfill/package.json new file mode 100644 index 00000000..fb7c8d5a --- /dev/null +++ b/packages/webextension-polyfill/package.json @@ -0,0 +1,56 @@ +{ + "name": "@wxt-dev/webextension-polyfill", + "description": "Use webextension-polyfill with WXT", + "repository": { + "type": "git", + "url": "git+https://github.com/wxt-dev/wxt.git", + "directory": "packages/webextension-polyfill" + }, + "homepage": "https://github.com/wxt-dev/wxt/blob/main/packages/webextension-polyfill/README.md", + "keywords": [ + "wxt", + "module", + "webextension-polyfill" + ], + "author": { + "name": "Aaron Klinker", + "email": "aaronklinker1+wxt@gmail.com" + }, + "license": "MIT", + "version": "1.0.0", + "type": "module", + "main": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + }, + "./browser": { + "types": "./dist/browser.d.mts", + "default": "./dist/browser.mjs" + } + }, + "files": [ + "dist" + ], + "scripts": { + "dev": "wxt", + "check": "pnpm build && check", + "build": "buildc -- unbuild", + "prepare": "buildc --deps-only -- wxt prepare" + }, + "peerDependencies": { + "webextension-polyfill": "*", + "wxt": ">=0.20.0" + }, + "devDependencies": { + "@aklinker1/check": "catalog:", + "@types/webextension-polyfill": "catalog:", + "publint": "catalog:", + "typescript": "catalog:", + "unbuild": "catalog:", + "webextension-polyfill": "catalog:", + "wxt": "workspace:*" + } +} diff --git a/packages/webextension-polyfill/public/.keep b/packages/webextension-polyfill/public/.keep new file mode 100644 index 00000000..e69de29b diff --git a/packages/webextension-polyfill/tsconfig.json b/packages/webextension-polyfill/tsconfig.json new file mode 100644 index 00000000..cde6e0a8 --- /dev/null +++ b/packages/webextension-polyfill/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": ["../../tsconfig.base.json", "./.wxt/tsconfig.json"], + "exclude": ["node_modules/**", "dist/**"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9dcf32f0..dbbc7c73 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,6 +57,9 @@ catalogs: '@types/ua-parser-js': specifier: ^0.7.39 version: 0.7.39 + '@types/webextension-polyfill': + specifier: ^0.12.1 + version: 0.12.3 '@vitejs/plugin-react': specifier: ^4.3.4 version: 4.3.4 @@ -294,6 +297,9 @@ 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: @@ -687,6 +693,30 @@ importers: specifier: workspace:* version: link:../wxt + packages/webextension-polyfill: + devDependencies: + '@aklinker1/check': + specifier: 'catalog:' + version: 1.4.5(typescript@5.6.3) + '@types/webextension-polyfill': + specifier: 'catalog:' + version: 0.12.3 + publint: + specifier: 'catalog:' + version: 0.2.12 + typescript: + specifier: 'catalog:' + version: 5.6.3 + unbuild: + specifier: 'catalog:' + version: 3.5.0(sass@1.80.7)(typescript@5.6.3)(vue@3.5.13(typescript@5.6.3)) + webextension-polyfill: + specifier: 'catalog:' + version: 0.12.0 + wxt: + specifier: workspace:* + version: link:../wxt + packages/wxt: dependencies: '@1natsu/wait-element': @@ -2312,6 +2342,9 @@ packages: '@types/web-bluetooth@0.0.20': resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + '@types/webextension-polyfill@0.12.3': + resolution: {integrity: sha512-F58aDVSeN/MjUGazXo/cPsmR76EvqQhQ1v4x23hFjUX0cfAJYE+JBWwiOGW36/VJGGxoH74sVlRIF3z7SJCKyg==} + '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} @@ -5354,6 +5387,9 @@ 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'} @@ -6654,6 +6690,8 @@ snapshots: '@types/web-bluetooth@0.0.20': {} + '@types/webextension-polyfill@0.12.3': {} + '@types/yauzl@2.10.3': dependencies: '@types/node': 20.17.6 @@ -10084,6 +10122,8 @@ snapshots: - supports-color - utf-8-validate + webextension-polyfill@0.12.0: {} + webidl-conversions@7.0.0: {} webpack-sources@3.2.3: