fix!: Move browser constants to import.meta.env (#380)

BREAKING CHANGE: Renamed undocumented constants:

- `__BROWSER__` → `import.meta.env.BROWSER`
- `__COMMAND__` → `import.meta.env.COMMAND`
- `__MANIFEST_VERSION__` → `import.meta.env.MANIFEST_VERSION`
- `__IS_CHROME__` → `import.meta.env.CHROME`
- `__IS_FIREFOX__` → `import.meta.env.FIREFOX`
- `__IS_SAFARI__` → `import.meta.env.SAFARI`
- `__IS_EDGE__` → `import.meta.env.EDGE`
- `__IS_OPERA__` → `import.meta.env.OPERA`
This commit is contained in:
Aaron
2024-01-29 11:14:18 -06:00
committed by GitHub
parent 2dcdae91eb
commit 927aca612e
17 changed files with 68 additions and 62 deletions
+4 -4
View File
@@ -4,10 +4,10 @@ export default defineBackground(() => {
console.log(browser.runtime.id);
logId();
console.log({
browser: __BROWSER__,
chrome: __IS_CHROME__,
firefox: __IS_FIREFOX__,
manifestVersion: __MANIFEST_VERSION__,
browser: import.meta.env.BROWSER,
chrome: import.meta.env.CHROME,
firefox: import.meta.env.FIREFOX,
manifestVersion: import.meta.env.MANIFEST_VERSION,
messages,
});
+9 -9
View File
@@ -115,19 +115,19 @@ Only `defineBackground` and `defineContentScript` support per-browser options ri
To determine the browser or manifest version at runtime, you can use any of the below variables:
- `__BROWSER__`: A string, the target browser, usually equal to the `--browser` flag
- `__MANIFEST_VERSION__`: A number, either `2` or `3`, depending on the manifest version targetted
- `__IS_CHROME__`: A boolean equivalent to `__BROWSER__ === "chrome"`
- `__IS_FIREFOX__`: A boolean equivalent to `__BROWSER__ === "firefox"`
- `__IS_EDGE__`: A boolean equivalent to `__BROWSER__ === "edge"`
- `__IS_SAFARI__`: A boolean equivalent to `__BROWSER__ === "safari"`
- `__IS_OPERA__`: A boolean equivalent to `__BROWSER__ === "opera"`
- `__COMMAND__`: A string, `"serve"` when running `wxt` for development or `"build"` in all other cases.
- `import.meta.env.BROWSER`: A string, the target browser, usually equal to the `--browser` flag
- `import.meta.env.MANIFEST_VERSION`: A number, either `2` or `3`, depending on the manifest version targetted
- `import.meta.env.CHROME`: A boolean equivalent to `import.meta.env.BROWSER === "chrome"`
- `import.meta.env.FIREFOX`: A boolean equivalent to `import.meta.env.BROWSER === "firefox"`
- `import.meta.env.EDGE`: A boolean equivalent to `import.meta.env.BROWSER === "edge"`
- `import.meta.env.SAFARI`: A boolean equivalent to `import.meta.env.BROWSER === "safari"`
- `import.meta.env.OPERA`: A boolean equivalent to `import.meta.env.BROWSER === "opera"`
- `import.meta.env.COMMAND`: A string, `"serve"` when running `wxt` for development or `"build"` in all other cases.
:::info
These variables are constants defined at build time based on the build target. They do not actually detect which browser the code is running in.
For example, if you build for `--browser chrome` and publish it on Edge, `__BROWSER__` will be `"chrome"`, not `"edge"`. You have to build a separate ZIP for `--browser edge` before `__BROWSER__` will be `"edge"`.
For example, if you build for `--browser chrome` and publish it on Edge, `import.meta.env.BROWSER` will be `"chrome"`, not `"edge"`. You have to build a separate ZIP for `--browser edge` before `import.meta.env.BROWSER` will be `"edge"`.
If you need to know the actual browser your code is being ran on, you should use a [user agent parser](https://www.npmjs.com/package/ua-parser-js).
:::
+1 -1
View File
@@ -19,7 +19,7 @@ If you want to try to use a different framework for unit tests, you will need to
- **Auto-imports**: Add `unimport` to your test environment or disable them by setting `imports: false` in your `wxt.config.ts` file
- **`browser` mock**: Mock the `webextension-polyfill` module globally with `wxt/dist/virtual/mock-browser.js`
- **[Remote Code Bundling](/guide/remote-code)**: If you use it, configure your environment to handle the `url:` module prefix
- **Global Variables**: If you consume them, manually define globals provided by WXT (like `__BROWSER__`) by adding them to the global scope before accessing them (`globalThis.__BROWSER__ = "chrome"`)
- **Global Variables**: If you consume them, manually define globals provided by WXT (like `import.meta.env.BROWSER`) by adding them to the global scope before accessing them (`import.meta.env.BROWSER = "chrome"`)
- **Import paths**: If you use the `@/` or `~/` path aliases, add them to your test environment
[Here's how Vitest is configured](https://github.com/wxt-dev/wxt/blob/main/src/testing/wxt-vitest-plugin.ts) for reference.
+14 -11
View File
@@ -14,16 +14,19 @@ describe('TypeScript Project', () => {
----------------------------------------
// Generated by wxt
export {}
declare global {
const __MANIFEST_VERSION__: 2 | 3;
const __BROWSER__: string;
const __IS_CHROME__: boolean;
const __IS_FIREFOX__: boolean;
const __IS_SAFARI__: boolean;
const __IS_EDGE__: boolean;
const __IS_OPERA__: boolean;
const __COMMAND__: "build" | "serve";
const __ENTRYPOINT__: string;
interface ImportMetaEnv {
readonly MANIFEST_VERSION: 2 | 3;
readonly BROWSER: string;
readonly CHROME: boolean;
readonly FIREFOX: boolean;
readonly SAFARI: boolean;
readonly EDGE: boolean;
readonly OPERA: boolean;
readonly COMMAND: "build" | "serve";
readonly ENTRYPOINT: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
"
`);
@@ -133,7 +136,7 @@ describe('TypeScript Project', () => {
options?: GetMessageOptions,
): string;
/**
*
* No message description.
*
* "<browser.i18n.getUiLocale()>"
*/
+5 -3
View File
@@ -15,10 +15,12 @@ export class WxtLocationChangeEvent extends Event {
* Returns an event name unique to the extension and content script that's running.
*/
export function getUniqueEventName(eventName: string): string {
// During the build process, __ENTRYPOINT__ is not defined when importing entrypoints to get their
// metadata.
// During the build process, import.meta.env is not defined when importing
// entrypoints to get their metadata.
const entrypointName =
typeof __ENTRYPOINT__ === 'undefined' ? 'build' : __ENTRYPOINT__;
typeof import.meta.env === 'undefined'
? 'build'
: import.meta.env.ENTRYPOINT;
return `${browser.runtime.id}:${entrypointName}:${eventName}`;
}
+3 -1
View File
@@ -236,7 +236,9 @@ function mountUi(
* Load the CSS for the current entrypoint.
*/
async function loadCss(): Promise<string> {
const url = browser.runtime.getURL(`/content-scripts/${__ENTRYPOINT__}.css`);
const url = browser.runtime.getURL(
`/content-scripts/${import.meta.env.ENTRYPOINT}.css`,
);
try {
const res = await fetch(url);
return await res.text();
@@ -14,7 +14,7 @@ export function entrypointGroupGlobals(
const define: vite.InlineConfig['define'] = {};
let name = Array.isArray(entrypointGroup) ? 'html' : entrypointGroup.name;
for (const global of getEntrypointGlobals(name)) {
define[global.name] = JSON.stringify(global.value);
define[`import.meta.env.${global.name}`] = JSON.stringify(global.value);
}
return {
define,
+1 -1
View File
@@ -10,7 +10,7 @@ export function globals(
config() {
const define: vite.InlineConfig['define'] = {};
for (const global of getGlobals(config)) {
define[global.name] = JSON.stringify(global.value);
define[`import.meta.env.${global.name}`] = JSON.stringify(global.value);
}
return {
define,
+6 -3
View File
@@ -136,7 +136,7 @@ declare module "wxt/browser" {
const overrides = messages.map((message) => {
return ` /**
* ${message.description ?? 'No message description.'}
* ${message.description || 'No message description.'}
*
* "${message.message}"
*/
@@ -164,8 +164,11 @@ async function writeGlobalsDeclarationFile(
[
'// Generated by wxt',
'export {}',
'declare global {',
...globals.map((global) => ` const ${global.name}: ${global.type};`),
'interface ImportMetaEnv {',
...globals.map((global) => ` readonly ${global.name}: ${global.type};`),
'}',
'interface ImportMeta {',
' readonly env: ImportMetaEnv',
'}',
].join('\n') + '\n',
);
@@ -98,6 +98,7 @@ export async function importEntrypointFile<T>(
{ cause: err },
);
} else {
config.logger.error(err);
throw Error(`Failed to load entrypoint: ${filePath}`, { cause: err });
}
}
+9 -17
View File
@@ -5,42 +5,42 @@ export function getGlobals(
): Array<{ name: string; value: any; type: string }> {
return [
{
name: surroundInUnderscore('MANIFEST_VERSION'),
name: 'MANIFEST_VERSION',
value: config.manifestVersion,
type: `2 | 3`,
},
{
name: surroundInUnderscore('BROWSER'),
name: 'BROWSER',
value: config.browser,
type: `string`,
},
{
name: surroundInUnderscore('IS_CHROME'),
name: 'CHROME',
value: config.browser === 'chrome',
type: `boolean`,
},
{
name: surroundInUnderscore('IS_FIREFOX'),
name: 'FIREFOX',
value: config.browser === 'firefox',
type: `boolean`,
},
{
name: surroundInUnderscore('IS_SAFARI'),
name: 'SAFARI',
value: config.browser === 'safari',
type: `boolean`,
},
{
name: surroundInUnderscore('IS_EDGE'),
name: 'EDGE',
value: config.browser === 'edge',
type: `boolean`,
},
{
name: surroundInUnderscore('IS_OPERA'),
name: 'OPERA',
value: config.browser === 'opera',
type: `boolean`,
},
{
name: surroundInUnderscore('COMMAND'),
name: 'COMMAND',
value: config.command,
type: `"build" | "serve"`,
},
@@ -50,17 +50,9 @@ export function getGlobals(
export function getEntrypointGlobals(entrypointName: string) {
return [
{
name: surroundInUnderscore('ENTRYPOINT'),
name: 'ENTRYPOINT',
value: entrypointName,
type: `string`,
},
];
}
/**
* Don't hardcode the complete name so that the string litterals in this file aren't replaced during
* tests (which causes syntax errors), only during builds.
*/
function surroundInUnderscore(name: string): string {
return `__${name}__`;
}
+7 -4
View File
@@ -1,7 +1,10 @@
// Globals defined by the vite-plugins/devServerGlobals.ts and utils/globals.ts
declare const __COMMAND__: 'build' | 'serve';
declare const __DEV_SERVER_PROTOCOL__: string;
declare const __DEV_SERVER_HOSTNAME__: string;
declare const __DEV_SERVER_PORT__: string;
declare const __MANIFEST_VERSION__: 2 | 3;
declare const __ENTRYPOINT__: string;
// Globals defined by the vite-plugins/devServerGlobals.ts and utils/globals.ts
interface ImportMetaEnv {
readonly COMMAND: 'build' | 'serve';
readonly MANIFEST_VERSION: 2 | 3;
readonly ENTRYPOINT: string;
}
+2 -2
View File
@@ -5,7 +5,7 @@ import { browser } from 'wxt/browser';
import { keepServiceWorkerAlive } from './utils/keep-service-worker-alive';
import { reloadContentScript } from './utils/reload-content-scripts';
if (__COMMAND__ === 'serve') {
if (import.meta.env.COMMAND === 'serve') {
try {
const ws = setupWebSocket((message) => {
if (message.event === 'wxt:reload-extension') browser.runtime.reload();
@@ -13,7 +13,7 @@ if (__COMMAND__ === 'serve') {
reloadContentScript(message.data);
});
if (__MANIFEST_VERSION__ === 3) {
if (import.meta.env.MANIFEST_VERSION === 3) {
// Tell the server the background script is loaded and ready to go
ws.addEventListener('open', () => {
const msg = { type: 'custom', event: 'wxt:background-initialized' };
@@ -5,12 +5,12 @@ import { ContentScriptContext } from 'wxt/client';
(async () => {
try {
const { main, ...options } = definition;
const ctx = new ContentScriptContext(__ENTRYPOINT__, options);
const ctx = new ContentScriptContext(import.meta.env.ENTRYPOINT, options);
await main(ctx);
} catch (err) {
logger.error(
`The content script "${__ENTRYPOINT__}" crashed on startup!`,
`The content script "${import.meta.env.ENTRYPOINT}" crashed on startup!`,
err,
);
}
@@ -7,7 +7,7 @@ import { logger } from '../sandbox/utils/logger';
await main();
} catch (err) {
logger.error(
`The content script "${__ENTRYPOINT__}" crashed on startup!`,
`The content script "${import.meta.env.ENTRYPOINT}" crashed on startup!`,
err,
);
}
+1 -1
View File
@@ -1,7 +1,7 @@
import { logger } from '../sandbox/utils/logger';
import { setupWebSocket } from './utils/setup-web-socket';
if (__COMMAND__ === 'serve') {
if (import.meta.env.COMMAND === 'serve') {
try {
setupWebSocket((message) => {
if (message.event === 'wxt:reload-page') {
+1 -1
View File
@@ -6,7 +6,7 @@ import { logger } from '../sandbox/utils/logger';
await definition.main();
} catch (err) {
logger.error(
`The unlisted script "${__ENTRYPOINT__}" crashed on startup!`,
`The unlisted script "${import.meta.env.ENTRYPOINT}" crashed on startup!`,
err,
);
}