fix: Use @wxt-dev/browser instead of @types/chrome (#1645)

This commit is contained in:
Aaron
2025-05-02 08:41:02 -05:00
committed by GitHub
parent 6f970efda5
commit 6a52bb22a3
13 changed files with 54 additions and 58 deletions
@@ -9,11 +9,12 @@ import type {
AnalyticsEventMetadata,
AnalyticsProvider,
} from './types';
import { browser } from '@wxt-dev/browser';
const ANALYTICS_PORT = '@wxt-dev/analytics';
export function createAnalytics(config?: AnalyticsConfig): Analytics {
if (typeof chrome === 'undefined' || !chrome?.runtime?.id)
if (!browser?.runtime?.id)
throw Error(
'Cannot use WXT analytics in contexts without access to the browser.runtime APIs',
);
@@ -51,13 +52,13 @@ function createBackgroundAnalytics(
defineStorageItem<boolean>('local:wxt-analytics:enabled', false);
// Cached values
const platformInfo = chrome.runtime.getPlatformInfo();
const platformInfo = browser.runtime.getPlatformInfo();
const userAgent = UAParser();
let userId = Promise.resolve(userIdStorage.getValue()).then(
(id) => id ?? globalThis.crypto.randomUUID(),
);
let userProperties = userPropertiesStorage.getValue();
const manifest = chrome.runtime.getManifest();
const manifest = browser.runtime.getManifest();
const getBackgroundMeta = () => ({
timestamp: Date.now(),
@@ -178,7 +179,7 @@ function createBackgroundAnalytics(
config?.providers?.map((provider) => provider(analytics, config)) ?? [];
// Listen for messages from the rest of the extension
chrome.runtime.onConnect.addListener((port) => {
browser.runtime.onConnect.addListener((port) => {
if (port.name === ANALYTICS_PORT) {
port.onMessage.addListener(({ fn, args }) => {
// @ts-expect-error: Untyped fn key
@@ -194,7 +195,7 @@ function createBackgroundAnalytics(
* Creates an analytics client for non-background contexts.
*/
function createFrontendAnalytics(): Analytics {
const port = chrome.runtime.connect({ name: ANALYTICS_PORT });
const port = browser.runtime.connect({ name: ANALYTICS_PORT });
const sessionId = Date.now();
const getFrontendMetadata = (): AnalyticsEventMetadata => ({
sessionId,
@@ -252,8 +253,8 @@ function defineStorageItem<T>(
): AnalyticsStorageItem<T> {
return {
getValue: async () =>
(await chrome.storage.local.get(key))[key] ?? defaultValue,
setValue: (newValue) => chrome.storage.local.set({ [key]: newValue }),
(await browser.storage.local.get(key))[key] ?? defaultValue,
setValue: (newValue) => browser.storage.local.set({ [key]: newValue }),
};
}
+1 -1
View File
@@ -52,7 +52,6 @@
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"@types/chrome": "^0.0.313",
"@types/ua-parser-js": "^0.7.39",
"publint": "^0.3.12",
"typescript": "^5.8.3",
@@ -60,6 +59,7 @@
"wxt": "workspace:*"
},
"dependencies": {
"@wxt-dev/browser": "workspace:*",
"ua-parser-js": "^1.0.40"
}
}
+1 -2
View File
@@ -3,8 +3,7 @@
"compilerOptions": {
"paths": {
"#analytics": ["./.wxt/analytics/index.ts"]
},
"types": ["chrome"]
}
},
"exclude": ["node_modules", "dist"]
}
+1 -1
View File
@@ -26,6 +26,7 @@
"test": "buildc --deps-only -- vitest"
},
"dependencies": {
"@wxt-dev/browser": "workspace:*",
"chokidar": "^4.0.3",
"confbox": "^0.1.8 || ^0.2.2",
"fast-glob": "^3.3.3"
@@ -40,7 +41,6 @@
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"@types/chrome": "^0.0.313",
"@types/node": "^20.17.6",
"oxlint": "^0.16.8",
"publint": "^0.3.12",
+11 -6
View File
@@ -1,13 +1,18 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { createI18n } from '../index';
import { browser } from '@wxt-dev/browser';
const getMessageMock = vi.fn();
vi.stubGlobal('chrome', {
i18n: {
getMessage: getMessageMock,
},
vi.mock('@wxt-dev/browser', async () => {
const { vi } = await import('vitest');
return {
browser: {
i18n: {
getMessage: vi.fn(),
},
},
};
});
const getMessageMock = vi.mocked(browser.i18n.getMessage);
describe('createI18n', () => {
beforeEach(() => {
+11 -6
View File
@@ -1,13 +1,18 @@
import { beforeEach, describe, it, vi } from 'vitest';
import { createI18n } from '..';
import { browser } from '@wxt-dev/browser';
const getMessageMock = vi.fn();
vi.stubGlobal('chrome', {
i18n: {
getMessage: getMessageMock,
},
vi.mock('@wxt-dev/browser', async () => {
const { vi } = await import('vitest');
return {
browser: {
i18n: {
getMessage: vi.fn(),
},
},
};
});
const getMessageMock = vi.mocked(browser.i18n.getMessage);
const n: number = 1;
+3 -2
View File
@@ -7,6 +7,7 @@ import {
I18n,
Substitution,
} from './types';
import { browser } from '@wxt-dev/browser';
export function createI18n<
T extends I18nStructure = DefaultI18nStructure,
@@ -39,9 +40,9 @@ export function createI18n<
if (sub?.length) {
// Convert all substitutions to strings
const stringSubs = sub?.map((sub) => String(sub));
message = chrome.i18n.getMessage(key.replaceAll('.', '_'), stringSubs);
message = browser.i18n.getMessage(key.replaceAll('.', '_'), stringSubs);
} else {
message = chrome.i18n.getMessage(key.replaceAll('.', '_'));
message = browser.i18n.getMessage(key.replaceAll('.', '_'));
}
if (!message) {
console.warn(`[i18n] Message not found: "${key}"`);
+1 -1
View File
@@ -1,7 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["chrome", "node"]
"types": ["node"]
},
"exclude": ["node_modules/**", "dist/**"]
}
+1 -1
View File
@@ -30,12 +30,12 @@
"test": "buildc --deps-only -- vitest"
},
"dependencies": {
"@wxt-dev/browser": "workspace:*",
"async-mutex": "^0.5.0",
"dequal": "^2.0.3"
},
"devDependencies": {
"@aklinker1/check": "2.0.0",
"@types/chrome": "^0.0.313",
"@webext-core/fake-browser": "^1.3.2",
"oxlint": "^0.16.8",
"publint": "^0.3.12",
+4 -3
View File
@@ -1,6 +1,7 @@
import { fakeBrowser } from '@webext-core/fake-browser';
import { describe, it, expect, beforeEach, vi, expectTypeOf } from 'vitest';
import { MigrationError, type WxtStorageItem, storage } from '../index';
import { browser } from '@wxt-dev/browser';
/**
* This works because fakeBrowser is synchronous, and is will finish any number of chained
@@ -222,7 +223,7 @@ describe('Storage Utils', () => {
describe('setMeta', () => {
it('should set metadata at key+$', async () => {
const existing = { v: 1 };
await chrome.storage[storageArea].set({ count$: existing });
await browser.storage[storageArea].set({ count$: existing });
const newValues = {
date: Date.now(),
};
@@ -238,7 +239,7 @@ describe('Storage Utils', () => {
'should remove any properties set to %s',
async (version) => {
const existing = { v: 1 };
await chrome.storage[storageArea].set({ count$: existing });
await browser.storage[storageArea].set({ count$: existing });
const expected = {};
await storage.setMeta(`${storageArea}:count`, { v: version });
@@ -1265,7 +1266,7 @@ describe('Storage Utils', () => {
await item.removeValue();
// Make sure it's actually blank before running the test
expect(await chrome.storage.local.get()).toEqual({});
expect(await browser.storage.local.get()).toEqual({});
init.mockClear();
const [value1, value2] = await Promise.all([
+2 -9
View File
@@ -1,4 +1,3 @@
/// <reference types="chrome" />
/**
* Simplified storage APIs with support for versioned fields, snapshots, metadata, and item definitions.
*
@@ -7,13 +6,7 @@
*/
import { dequal } from 'dequal/lite';
import { Mutex } from 'async-mutex';
const browser: typeof chrome =
// @ts-expect-error
globalThis.browser?.runtime?.id == null
? globalThis.chrome
: // @ts-expect-error
globalThis.browser;
import { browser, type Browser } from '@wxt-dev/browser';
export const storage = createStorage();
@@ -897,7 +890,7 @@ export interface WxtStorageItemOptions<T> {
}
export type StorageAreaChanges = {
[key: string]: chrome.storage.StorageChange;
[key: string]: Browser.storage.StorageChange;
};
/**
+1 -2
View File
@@ -1,8 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"verbatimModuleSyntax": true,
"types": ["chrome"]
"verbatimModuleSyntax": true
},
"exclude": ["node_modules/**", "dist/**"]
}
+9 -17
View File
@@ -100,6 +100,9 @@ importers:
packages/analytics:
dependencies:
'@wxt-dev/browser':
specifier: workspace:*
version: link:../browser
ua-parser-js:
specifier: ^1.0.40
version: 1.0.40
@@ -107,9 +110,6 @@ importers:
'@aklinker1/check':
specifier: 2.0.0
version: 2.0.0
'@types/chrome':
specifier: ^0.0.313
version: 0.0.313
'@types/ua-parser-js':
specifier: ^0.7.39
version: 0.7.39
@@ -187,6 +187,9 @@ importers:
packages/i18n:
dependencies:
'@wxt-dev/browser':
specifier: workspace:*
version: link:../browser
chokidar:
specifier: ^4.0.3
version: 4.0.3
@@ -200,9 +203,6 @@ importers:
'@aklinker1/check':
specifier: 2.0.0
version: 2.0.0
'@types/chrome':
specifier: ^0.0.313
version: 0.0.313
'@types/node':
specifier: ^20.17.6
version: 20.17.30
@@ -336,6 +336,9 @@ importers:
packages/storage:
dependencies:
'@wxt-dev/browser':
specifier: workspace:*
version: link:../browser
async-mutex:
specifier: ^0.5.0
version: 0.5.0
@@ -346,9 +349,6 @@ importers:
'@aklinker1/check':
specifier: 2.0.0
version: 2.0.0
'@types/chrome':
specifier: ^0.0.313
version: 0.0.313
'@webext-core/fake-browser':
specifier: ^1.3.2
version: 1.3.2
@@ -1866,9 +1866,6 @@ packages:
'@types/babel__traverse@7.20.6':
resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==}
'@types/chrome@0.0.313':
resolution: {integrity: sha512-9R5T7gTaYZhkxlu+Ho4wk9FL+y/werWQY2yjGWSqCuiTsqS7nL/BE5UMTP6rU7J+oIG2FRKqrEycHhJATeltVA==}
'@types/chrome@0.0.318':
resolution: {integrity: sha512-rrtyYQ1t+g7EyG0FejE+UXQBjSGUHGh0RIdXwUT/laPo9T724NOIgXA94ns6ewmNauwijYa5ck3+dBxWnHcynQ==}
@@ -5917,11 +5914,6 @@ snapshots:
dependencies:
'@babel/types': 7.27.0
'@types/chrome@0.0.313':
dependencies:
'@types/filesystem': 0.0.36
'@types/har-format': 1.2.15
'@types/chrome@0.0.318':
dependencies:
'@types/filesystem': 0.0.36