Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2e9ab75e2b | |||
| 0c2d795800 | |||
| 97aa173f7e | |||
| 9eb64d94d6 | |||
| a0971cab52 | |||
| 127562e9d0 | |||
| 038e7450e0 | |||
| 6c00763187 | |||
| 2da0f3d686 |
@@ -12,6 +12,7 @@ on:
|
||||
- module-vue
|
||||
- module-svelte
|
||||
- module-solid
|
||||
- auto-icons
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
|
||||
@@ -142,7 +142,7 @@ export default defineConfig({
|
||||
menuItem('Custom Events', 'custom-events'),
|
||||
menuItem('Reusable Modules', 'reusable-modules'),
|
||||
menuItem('Remote Code', 'remote-code'),
|
||||
menuItem('Entrypoint Side Effects', 'entrypoint-side-effects'),
|
||||
menuItem('Entrypoint Loaders', 'entrypoint-loaders'),
|
||||
menuItem('How WXT Works', 'how-wxt-works'),
|
||||
]),
|
||||
menuGroup('Upgrade Guide', '/guide/upgrade-guide/', [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Entrypoint Loaders
|
||||
|
||||
Because entrypoint options, like content script matches, are listed in the entrypoint's JS file, WXT has to import them during the build process to use those options when generating the manifest.
|
||||
Because entrypoint options, like content script `matches`, are listed in the entrypoint's JS file, WXT has to import them during the build process to use those options when generating the manifest.
|
||||
|
||||
There are two options for loading your entrypoints:
|
||||
|
||||
@@ -11,7 +11,50 @@ There are two options for loading your entrypoints:
|
||||
|
||||
Since 0.19.0, WXT uses `vite-node`, the same tool that powers Vitest and Nuxt, to import your entrypoint files.
|
||||
|
||||
There isn't really anything to add here... By default, it should "just work".
|
||||
If you use any runtime packages that depend on `webextension-polyfill`, you need to add them to [Vite's `ssr.noExternal` option](https://vitejs.dev/config/ssr-options#ssr-noexternal):
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
vite: () => ({
|
||||
ssr: {
|
||||
noExternal: ['@webext-core/messaging', '@webext-core/proxy-service'],
|
||||
},
|
||||
}),
|
||||
});
|
||||
```
|
||||
|
||||
:::details Why?
|
||||
This tells Vite it needs process these module's, letting WXT properly disable the polyfill in the NodeJS environment so it doesn't cause any build errors like this:
|
||||
|
||||
```
|
||||
ERROR This script should only be loaded in a browser extension
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
To get a list of installed packages that use on `webextension-polyfill`, run your package manager's `list` command. Here's an example with PNPM:
|
||||
|
||||
```sh
|
||||
$ pnpm why webextension-polyfill
|
||||
|
||||
dependencies:
|
||||
@webext-core/messaging 1.4.0
|
||||
└── webextension-polyfill 0.10.0
|
||||
@webext-core/proxy-service 1.2.0
|
||||
├─┬ @webext-core/messaging 1.4.0 peer
|
||||
│ └── webextension-polyfill 0.10.0
|
||||
└── webextension-polyfill 0.12.0 peer
|
||||
|
||||
devDependencies:
|
||||
@wxt-dev/module-vue 1.0.0
|
||||
└─┬ wxt 0.19.0-alpha1 peer
|
||||
└── webextension-polyfill 0.12.0
|
||||
webextension-polyfill 0.12.0
|
||||
wxt 0.19.0-alpha1
|
||||
└── webextension-polyfill 0.12.0
|
||||
```
|
||||
|
||||
Ignoring WXT itself (it's added automatically for you), there are three packages that depend on the polyfill: `@wxt-dev/module-vue`, `@webext-core/messaging`, and `@webext-core/proxy-service`. Since the vue module is a build dependency, with no runtime code, you don't have to add it. That means for this case, you need to add `@webext-core/messaging`, and `@webext-core/proxy-service`, as shown in the original code snippet.
|
||||
|
||||
## jiti
|
||||
|
||||
|
||||
@@ -14,37 +14,56 @@ If there was a major version change, follow the steps below to fix breaking chan
|
||||
|
||||
### `vite-node` Entrypoint Loader
|
||||
|
||||
The default entrypoint loader has changed to `vite-node`. This change enables:
|
||||
The default entrypoint loader has changed to `vite-node`. If you use any NPM packages that depend on the `webextension-polyfill`, you need to add them to Vite's `ssr.noExternal` option:
|
||||
|
||||
- Importing variables and using them in the entrypoint options.
|
||||
<!-- prettier-ignore -->
|
||||
```ts
|
||||
export default defineConfig({
|
||||
vite: () => ({ // [!code ++]
|
||||
ssr: { // [!code ++]
|
||||
noExternal: ['@webext-core/messaging', '@webext-core/proxy-service'], // [!code ++]
|
||||
}, // [!code ++]
|
||||
}), // [!code ++]
|
||||
});
|
||||
```
|
||||
|
||||
```ts
|
||||
// entrypoints/content.ts
|
||||
import { GOOGLE_MATCHES } from '~/utils/constants'
|
||||
> [Read the full docs](/guide/go-further/entrypoint-loaders#vite-node) for more information.
|
||||
|
||||
export default defineContentScript({
|
||||
matches: [GOOGLE_MATCHES],
|
||||
main: () => ...,
|
||||
})
|
||||
```
|
||||
:::details This change enables:
|
||||
|
||||
- Use Vite-specific APIs like `import.meta.glob` to define entrypoint options.
|
||||
Importing variables and using them in the entrypoint options:
|
||||
|
||||
```ts
|
||||
// entrypoints/content.ts
|
||||
const providers: Record<string, any> = import.meta.glob('../providers/*', {
|
||||
eager: true,
|
||||
});
|
||||
```ts
|
||||
// entrypoints/content.ts
|
||||
import { GOOGLE_MATCHES } from '~/utils/constants'
|
||||
|
||||
export default defineContentScript({
|
||||
matches: Object.values(providers).flatMap(
|
||||
(provider) => provider.default.paths,
|
||||
),
|
||||
async main() {
|
||||
console.log('Hello content.');
|
||||
},
|
||||
});
|
||||
```
|
||||
export default defineContentScript({
|
||||
matches: [GOOGLE_MATCHES],
|
||||
main: () => ...,
|
||||
})
|
||||
```
|
||||
|
||||
Using Vite-specific APIs like `import.meta.glob` to define entrypoint options:
|
||||
|
||||
```ts
|
||||
// entrypoints/content.ts
|
||||
const providers: Record<string, any> = import.meta.glob('../providers/*', {
|
||||
eager: true,
|
||||
});
|
||||
|
||||
export default defineContentScript({
|
||||
matches: Object.values(providers).flatMap(
|
||||
(provider) => provider.default.paths,
|
||||
),
|
||||
async main() {
|
||||
console.log('Hello content.');
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Basically, you can now import and do things outside the `main` function of the entrypoint - you could not do that before. Still though, be careful. It is recommended to avoid running code outside the `main` function to keep your builds fast.
|
||||
|
||||
:::
|
||||
|
||||
To continue using the old approach, add the following to your `wxt.config.ts` file:
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# WXT Auto Icons
|
||||
|
||||
## Features
|
||||
|
||||
- Generate extension icons with the correct sizes
|
||||
- Make the icon greyscale during development
|
||||
|
||||
## Usage
|
||||
|
||||
Install the package:
|
||||
|
||||
```sh
|
||||
npm i --save-dev @wxt-dev/auto-icons
|
||||
pnpm i -D @wxt-dev/auto-icons
|
||||
yarn add --dev @wxt-dev/auto-icons
|
||||
bun i -D @wxt-dev/auto-icons
|
||||
```
|
||||
|
||||
Add the module to `wxt.config.ts`:
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
modules: ['@wxt-dev/auto-icons'],
|
||||
});
|
||||
```
|
||||
|
||||
And finally, save the base icon to `<srcDir>/assets/icon.png`.
|
||||
|
||||
## Configuration
|
||||
|
||||
The module can be configured via the `autoIcons` config:
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
module: ['@wxt-dev/auto-icons'],
|
||||
autoIcons: {
|
||||
// ...
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Options have JSDocs available in your editor, or you can read them in the source code: [`AutoIconsOptions`](./src/index.ts).
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "@wxt-dev/auto-icons",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "buildc -- unbuild",
|
||||
"check": "buildc --deps-only -- check"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"wxt": ">=0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "^1.3.1",
|
||||
"publint": "^0.2.9",
|
||||
"typescript": "^5.5.3",
|
||||
"unbuild": "^2.0.0",
|
||||
"wxt": "workspace:*"
|
||||
},
|
||||
"dependencies": {
|
||||
"defu": "^6.1.4",
|
||||
"fs-extra": "^11.2.0",
|
||||
"sharp": "^0.33.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import 'wxt';
|
||||
import { defineWxtModule } from 'wxt/modules';
|
||||
import { resolve, relative } from 'node:path';
|
||||
import defu from 'defu';
|
||||
import sharp from 'sharp';
|
||||
import { ensureDir, exists } from 'fs-extra';
|
||||
|
||||
export default defineWxtModule<AutoIconsOptions>({
|
||||
name: '@wxt-dev/auto-icons',
|
||||
configKey: 'autoIcons',
|
||||
async setup(wxt, options) {
|
||||
const parsedOptions = defu(options, {
|
||||
enabled: true,
|
||||
baseIconsPath: resolve(wxt.config.srcDir, 'assets/icon.png'),
|
||||
grayscaleOnDevelopment: true,
|
||||
sizes: [128, 48, 32, 16],
|
||||
});
|
||||
|
||||
if (!parsedOptions.enabled)
|
||||
return wxt.logger.warn(`\`[auto-icons]\` ${this.name} disabled`);
|
||||
|
||||
if (!(await exists(parsedOptions.baseIconsPath))) {
|
||||
const relativePath = relative(process.cwd(), parsedOptions.baseIconsPath);
|
||||
return wxt.logger.warn(
|
||||
`\`[auto-icons]\` Skipping icon generation, no base icon found at ${relativePath}`,
|
||||
);
|
||||
}
|
||||
|
||||
wxt.hooks.hook('build:manifestGenerated', async (wxt, manifest) => {
|
||||
if (manifest.icons)
|
||||
return wxt.logger.warn(
|
||||
'`[auto-icons]` icons property found in manifest, overwriting with auto-generated icons',
|
||||
);
|
||||
|
||||
manifest.icons = Object.fromEntries(
|
||||
parsedOptions.sizes.map((size) => [size, `icons/${size}.png`]),
|
||||
);
|
||||
});
|
||||
|
||||
wxt.hooks.hook('build:done', async (wxt, output) => {
|
||||
const image = sharp(parsedOptions.baseIconsPath).png();
|
||||
|
||||
if (
|
||||
wxt.config.mode === 'development' &&
|
||||
parsedOptions.grayscaleOnDevelopment
|
||||
) {
|
||||
image.grayscale();
|
||||
}
|
||||
|
||||
const outputFolder = wxt.config.outDir;
|
||||
|
||||
for (const size of parsedOptions.sizes) {
|
||||
const resized = image.resize(size);
|
||||
ensureDir(resolve(outputFolder, 'icons'));
|
||||
await resized.toFile(resolve(outputFolder, `icons/${size}.png`));
|
||||
|
||||
output.publicAssets.push({
|
||||
type: 'asset',
|
||||
fileName: `icons/${size}.png`,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
wxt.hooks.hook('prepare:publicPaths', (wxt, paths) => {
|
||||
for (const size of parsedOptions.sizes) {
|
||||
paths.push(`icons/${size}.png`);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Options for the auto-icons module
|
||||
*/
|
||||
export interface AutoIconsOptions {
|
||||
/**
|
||||
* Enable auto-icons generation
|
||||
* @default true
|
||||
*/
|
||||
enabled?: boolean;
|
||||
/**
|
||||
* Path to the image to use.
|
||||
* @default "<srcDir>/assets/icon.png"
|
||||
*/
|
||||
baseIconPath?: string;
|
||||
/**
|
||||
* Grayscale the image when in development mode to indicate development
|
||||
* @default true
|
||||
*/
|
||||
grayscaleOnDevelopment?: boolean;
|
||||
/**
|
||||
* Sizes to generate icons for
|
||||
* @default [128, 48, 32, 16]
|
||||
*/
|
||||
sizes?: number[];
|
||||
}
|
||||
|
||||
declare module 'wxt' {
|
||||
export interface InlineConfig {
|
||||
autoIcons?: AutoIconsOptions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"exclude": ["node_modules/**", "dist/**"]
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
"@types/chrome": "^0.0.268",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@wxt-dev/auto-icons": "workspace:*",
|
||||
"sass": "^1.77.8",
|
||||
"typescript": "^5.5.3",
|
||||
"vitest": "^2.0.3",
|
||||
|
||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
@@ -20,7 +20,7 @@ export default defineBackground({
|
||||
// @ts-expect-error: should only accept entrypoints or public assets
|
||||
browser.runtime.getURL('/');
|
||||
browser.runtime.getURL('/background.js');
|
||||
browser.runtime.getURL('/icon/128.png');
|
||||
browser.runtime.getURL('/icons/128.png');
|
||||
browser.runtime.getURL('/example.html#hash');
|
||||
browser.runtime.getURL('/example.html?query=param');
|
||||
// @ts-expect-error: should only allow hashes/query params on HTML files
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import autoIcons from '@wxt-dev/auto-icons';
|
||||
|
||||
export default autoIcons;
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 504 B |
Binary file not shown.
|
Before Width: | Height: | Size: 936 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 KiB |
@@ -1,8 +1,24 @@
|
||||
# Changelog
|
||||
|
||||
## v0.19.1
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.19.0...wxt-v0.19.1)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- Auto Icons Module ([#851](https://github.com/wxt-dev/wxt/pull/851))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Define web globals when importing entrypoints ([#865](https://github.com/wxt-dev/wxt/pull/865))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Florian Metz ([@Timeraa](http://github.com/Timeraa))
|
||||
|
||||
## v0.19.0
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.18.15...wxt-v0.19.0)
|
||||
[⚠️ breaking changes](https://wxt.dev/guide/upgrade-guide/wxt) • [compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.18.15...wxt-v0.19.0)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
@@ -36,11 +52,6 @@
|
||||
- **deps:** Upgrade `minimatch` from 9 to 10 ([#840](https://github.com/wxt-dev/wxt/pull/840))
|
||||
- **dev-deps:** Upgrade `happy-dom` from 13 to 14 ([#843](https://github.com/wxt-dev/wxt/pull/843))
|
||||
|
||||
#### ⚠️ Breaking Changes
|
||||
|
||||
- ⚠️ Use `vite-node` to load entrypoints by default ([#859](https://github.com/wxt-dev/wxt/pull/859))
|
||||
- **size:** ⚠️ Switch from `tsup` to `unbuild` for building WXT ([#848](https://github.com/wxt-dev/wxt/pull/848))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Florian Metz ([@Timeraa](http://github.com/Timeraa))
|
||||
|
||||
@@ -280,7 +280,7 @@ describe('Output Directory Structure', () => {
|
||||
var _a, _b;
|
||||
import { l as logHello, i as initPlugins } from "./chunks/_virtual_wxt-plugins-OjKtWpmY.js";
|
||||
function defineBackground(arg) {
|
||||
if (typeof arg === "function") return { main: arg };
|
||||
if (arg == null || typeof arg === "function") return { main: arg };
|
||||
return arg;
|
||||
}
|
||||
const definition = defineBackground({
|
||||
@@ -366,7 +366,7 @@ describe('Output Directory Structure', () => {
|
||||
"use strict";
|
||||
var _a, _b;
|
||||
function defineBackground(arg) {
|
||||
if (typeof arg === "function") return { main: arg };
|
||||
if (arg == null || typeof arg === "function") return { main: arg };
|
||||
return arg;
|
||||
}
|
||||
function logHello(name) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { TestProject } from '../utils';
|
||||
|
||||
describe('Remote Code', () => {
|
||||
it('should download "url:*" modules and include them in the final bundle', async () => {
|
||||
const url = 'https://code.jquery.com/jquery-3.7.1.slim.min.js';
|
||||
const url = 'https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js';
|
||||
const project = new TestProject();
|
||||
project.addFile(
|
||||
'entrypoints/popup.ts',
|
||||
@@ -16,7 +16,7 @@ describe('Remote Code', () => {
|
||||
const output = await project.serializeFile('.output/chrome-mv3/popup.js');
|
||||
expect(output).toContain(
|
||||
// Some text that will hopefully be in future versions of this script
|
||||
'jQuery v3.7.1',
|
||||
'lodash.com',
|
||||
);
|
||||
expect(output).not.toContain(url);
|
||||
expect(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "wxt",
|
||||
"type": "module",
|
||||
"version": "0.19.0",
|
||||
"version": "0.19.1",
|
||||
"description": "Next gen framework for developing web extensions",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -230,10 +230,7 @@ export async function createViteBuilder(
|
||||
baseConfig.optimizeDeps.noDiscovery = true;
|
||||
baseConfig.optimizeDeps.include = [];
|
||||
const envConfig: vite.InlineConfig = {
|
||||
plugins: [
|
||||
wxtPlugins.extensionApiMock(wxtConfig),
|
||||
wxtPlugins.removeEntrypointMainFunction(wxtConfig, path),
|
||||
],
|
||||
plugins: [wxtPlugins.removeEntrypointMainFunction(wxtConfig, path)],
|
||||
};
|
||||
const config = vite.mergeConfig(baseConfig, envConfig);
|
||||
const server = await vite.createServer(config);
|
||||
|
||||
@@ -14,8 +14,17 @@ export function removeEntrypointMainFunction(
|
||||
const absPath = normalizePath(resolve(config.root, path));
|
||||
return {
|
||||
name: 'wxt:remove-entrypoint-main-function',
|
||||
transform(code, id) {
|
||||
if (id === absPath) return removeMainFunctionCode(code);
|
||||
transform: {
|
||||
order: 'pre',
|
||||
handler(code, id) {
|
||||
if (id === absPath) {
|
||||
const newCode = removeMainFunctionCode(code);
|
||||
config.logger.debug('vite-node transformed entrypoint', path);
|
||||
config.logger.debug(`Original:\n---\n${code}\n---`);
|
||||
config.logger.debug(`Transformed:\n---\n${newCode.code}\n---`);
|
||||
return newCode;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,23 +6,28 @@ describe('Transform Utils', () => {
|
||||
it.each(['defineBackground', 'defineUnlistedScript'])(
|
||||
'should remove the first arrow function argument for %s',
|
||||
(def) => {
|
||||
const input = `export default ${def}(() => {
|
||||
const input = `
|
||||
export default ${def}(() => {
|
||||
console.log();
|
||||
})`;
|
||||
const expected = `export default ${def}(() => {})`;
|
||||
})
|
||||
`;
|
||||
const expected = `export default ${def}();`;
|
||||
|
||||
const actual = removeMainFunctionCode(input).code;
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
},
|
||||
);
|
||||
|
||||
it.each(['defineBackground', 'defineUnlistedScript'])(
|
||||
'should remove the first function argument for %s',
|
||||
(def) => {
|
||||
const input = `export default ${def}(function () {
|
||||
const input = `
|
||||
export default ${def}(function () {
|
||||
console.log();
|
||||
})`;
|
||||
const expected = `export default ${def}(function () {})`;
|
||||
})
|
||||
`;
|
||||
const expected = `export default ${def}();`;
|
||||
|
||||
const actual = removeMainFunctionCode(input).code;
|
||||
|
||||
@@ -35,10 +40,12 @@ describe('Transform Utils', () => {
|
||||
'defineContentScript',
|
||||
'defineUnlistedScript',
|
||||
])('should remove the main field from %s', (def) => {
|
||||
const input = `export default ${def}({
|
||||
asdf: "asdf",
|
||||
main: () => {},
|
||||
})`;
|
||||
const input = `
|
||||
export default ${def}({
|
||||
asdf: "asdf",
|
||||
main: () => {},
|
||||
})
|
||||
`;
|
||||
const expected = `export default ${def}({
|
||||
asdf: "asdf"
|
||||
})`;
|
||||
@@ -47,5 +54,39 @@ describe('Transform Utils', () => {
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should remove unused imports', () => {
|
||||
const input = `
|
||||
import { defineBackground } from "wxt/sandbox"
|
||||
import { test1 } from "somewhere1"
|
||||
import test2 from "somewhere2"
|
||||
|
||||
export default defineBackground(() => {})
|
||||
`;
|
||||
const expected = `import { defineBackground } from "wxt/sandbox"
|
||||
|
||||
export default defineBackground();`;
|
||||
|
||||
const actual = removeMainFunctionCode(input).code;
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should remove explict side-effect imports', () => {
|
||||
const input = `
|
||||
import { defineBackground } from "wxt/sandbox"
|
||||
import "my-polyfill"
|
||||
import "./style.css"
|
||||
|
||||
export default defineBackground(() => {})
|
||||
`;
|
||||
const expected = `import { defineBackground } from "wxt/sandbox"
|
||||
|
||||
export default defineBackground();`;
|
||||
|
||||
const actual = removeMainFunctionCode(input).code;
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,6 +28,7 @@ import { VIRTUAL_NOOP_BACKGROUND_MODULE_ID } from '../../utils/constants';
|
||||
import { CSS_EXTENSIONS_PATTERN } from '../../utils/paths';
|
||||
import pc from 'picocolors';
|
||||
import { wxt } from '../../wxt';
|
||||
import { createExtensionEnvironment } from '../environments';
|
||||
|
||||
/**
|
||||
* Return entrypoints and their configuration by looking through the project's files.
|
||||
@@ -72,47 +73,50 @@ export async function findEntrypoints(): Promise<Entrypoint[]> {
|
||||
|
||||
// Import entrypoints to get their config
|
||||
let hasBackground = false;
|
||||
const entrypoints: Entrypoint[] = await Promise.all(
|
||||
entrypointInfos.map(async (info): Promise<Entrypoint> => {
|
||||
const { type } = info;
|
||||
switch (type) {
|
||||
case 'popup':
|
||||
return await getPopupEntrypoint(info);
|
||||
case 'sidepanel':
|
||||
return await getSidepanelEntrypoint(info);
|
||||
case 'options':
|
||||
return await getOptionsEntrypoint(info);
|
||||
case 'background':
|
||||
hasBackground = true;
|
||||
return await getBackgroundEntrypoint(info);
|
||||
case 'content-script':
|
||||
return await getContentScriptEntrypoint(info);
|
||||
case 'unlisted-page':
|
||||
return await getUnlistedPageEntrypoint(info);
|
||||
case 'unlisted-script':
|
||||
return await getUnlistedScriptEntrypoint(info);
|
||||
case 'content-script-style':
|
||||
return {
|
||||
...info,
|
||||
type,
|
||||
outputDir: resolve(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
|
||||
options: {
|
||||
include: undefined,
|
||||
exclude: undefined,
|
||||
},
|
||||
};
|
||||
default:
|
||||
return {
|
||||
...info,
|
||||
type,
|
||||
outputDir: wxt.config.outDir,
|
||||
options: {
|
||||
include: undefined,
|
||||
exclude: undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
}),
|
||||
const env = createExtensionEnvironment();
|
||||
const entrypoints: Entrypoint[] = await env.run(() =>
|
||||
Promise.all(
|
||||
entrypointInfos.map(async (info): Promise<Entrypoint> => {
|
||||
const { type } = info;
|
||||
switch (type) {
|
||||
case 'popup':
|
||||
return await getPopupEntrypoint(info);
|
||||
case 'sidepanel':
|
||||
return await getSidepanelEntrypoint(info);
|
||||
case 'options':
|
||||
return await getOptionsEntrypoint(info);
|
||||
case 'background':
|
||||
hasBackground = true;
|
||||
return await getBackgroundEntrypoint(info);
|
||||
case 'content-script':
|
||||
return await getContentScriptEntrypoint(info);
|
||||
case 'unlisted-page':
|
||||
return await getUnlistedPageEntrypoint(info);
|
||||
case 'unlisted-script':
|
||||
return await getUnlistedScriptEntrypoint(info);
|
||||
case 'content-script-style':
|
||||
return {
|
||||
...info,
|
||||
type,
|
||||
outputDir: resolve(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
|
||||
options: {
|
||||
include: undefined,
|
||||
exclude: undefined,
|
||||
},
|
||||
};
|
||||
default:
|
||||
return {
|
||||
...info,
|
||||
type,
|
||||
outputDir: wxt.config.outDir,
|
||||
options: {
|
||||
include: undefined,
|
||||
exclude: undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
if (wxt.config.command === 'serve' && !hasBackground) {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { parseHTML } from 'linkedom';
|
||||
import { createEnvironment, Environment, EnvGlobals } from './environment';
|
||||
|
||||
export function createBrowserEnvironment(): Environment {
|
||||
return createEnvironment(getBrowserEnvironmentGlobals);
|
||||
}
|
||||
|
||||
export function getBrowserEnvironmentGlobals(): EnvGlobals {
|
||||
const { window, document, global } = parseHTML(`
|
||||
<html>
|
||||
<head></head>
|
||||
<body></body>
|
||||
</html>
|
||||
`);
|
||||
return {
|
||||
...global,
|
||||
window,
|
||||
document,
|
||||
self: global,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
export interface Environment {
|
||||
setup: () => () => void;
|
||||
run: <T>(fn: () => Promise<T>) => Promise<T>;
|
||||
}
|
||||
|
||||
export function createEnvironment(getGlobals: () => EnvGlobals): Environment {
|
||||
const setup = () => {
|
||||
const envGlobals = getGlobals();
|
||||
const ogGlobals = getOgGlobals(envGlobals);
|
||||
applyGlobals(envGlobals);
|
||||
|
||||
return () => {
|
||||
applyGlobals(ogGlobals);
|
||||
};
|
||||
};
|
||||
const run = async (fn: () => any) => {
|
||||
const teardown = setup();
|
||||
try {
|
||||
return await fn();
|
||||
} finally {
|
||||
teardown();
|
||||
}
|
||||
};
|
||||
return {
|
||||
setup,
|
||||
run,
|
||||
};
|
||||
}
|
||||
|
||||
export type EnvGlobals = Record<string, any>;
|
||||
|
||||
export function getOgGlobals(envGlobals: EnvGlobals): EnvGlobals {
|
||||
return Object.keys(envGlobals).reduce<typeof envGlobals>((acc, key) => {
|
||||
// @ts-expect-error: Untyped key on globalThis
|
||||
acc[key] = globalThis[key];
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
export function applyGlobals(globals: EnvGlobals): void {
|
||||
Object.entries(globals).forEach(([key, envValue]) => {
|
||||
try {
|
||||
// @ts-expect-error: Untyped key on globalThis
|
||||
globalThis[key] = envValue;
|
||||
} catch (err) {
|
||||
// ignore any globals that can't be set
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { fakeBrowser } from '@webext-core/fake-browser';
|
||||
import { getBrowserEnvironmentGlobals } from './browser-environment';
|
||||
import { createEnvironment, Environment } from './environment';
|
||||
|
||||
export function createExtensionEnvironment(): Environment {
|
||||
return createEnvironment(getExtensionEnvironmentGlobals);
|
||||
}
|
||||
|
||||
export function getExtensionEnvironmentGlobals() {
|
||||
return {
|
||||
...getBrowserEnvironmentGlobals(),
|
||||
chrome: fakeBrowser,
|
||||
browser: fakeBrowser,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './browser-environment';
|
||||
export * from './extension-environment';
|
||||
@@ -2,8 +2,9 @@ import { ProxifiedModule, parseModule } from 'magicast';
|
||||
|
||||
/**
|
||||
* Removes any code used at runtime related to an entrypoint's main function.
|
||||
* - Removes or clears out `main` function from returned object
|
||||
* - TODO: Removes unused imports after main function has been removed to prevent importing runtime modules
|
||||
* 1. Removes or clears out `main` function from returned object
|
||||
* 2. Removes unused imports
|
||||
* 3. Removes value-less, side-effect only imports (like `import "./styles.css"` or `import "webextension-polyfill"`)
|
||||
*/
|
||||
export function removeMainFunctionCode(code: string): {
|
||||
code: string;
|
||||
@@ -11,16 +12,18 @@ export function removeMainFunctionCode(code: string): {
|
||||
} {
|
||||
const mod = parseModule(code);
|
||||
emptyMainFunction(mod);
|
||||
removeUnusedImports(mod);
|
||||
removeSideEffectImports(mod);
|
||||
return mod.generate();
|
||||
}
|
||||
|
||||
function emptyMainFunction(mod: ProxifiedModule) {
|
||||
function emptyMainFunction(mod: ProxifiedModule): void {
|
||||
if (mod.exports?.default?.$type === 'function-call') {
|
||||
if (mod.exports.default.$ast?.arguments?.[0]?.body) {
|
||||
// Remove body from function
|
||||
// ex: "fn(() => { ... })" to "fn(() => {})"
|
||||
// ex: "fn(function () { ... })" to "fn(function () {})"
|
||||
mod.exports.default.$ast.arguments[0].body.body = [];
|
||||
// ex: "fn(() => { ... })" to "fn()"
|
||||
// ex: "fn(function () { ... })" to "fn()"
|
||||
delete mod.exports.default.$ast.arguments[0];
|
||||
} else if (mod.exports.default.$ast?.arguments?.[0]?.properties) {
|
||||
// Remove main field from object
|
||||
// ex: "fn({ ..., main: () => {} })" to "fn({ ... })"
|
||||
@@ -31,3 +34,71 @@ function emptyMainFunction(mod: ProxifiedModule) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Do a more complex declaration analysis where shadowed variables are detected and ignored.
|
||||
// Right now, this code assumes there are no shadowed variables.
|
||||
function removeUnusedImports(mod: ProxifiedModule): void {
|
||||
const importSymbols = Object.keys(mod.imports);
|
||||
const usedMap = new Map(importSymbols.map((sym) => [sym, false]));
|
||||
|
||||
const queue: any[] = [getSimpleAstJson(mod.$ast)];
|
||||
for (const item of queue) {
|
||||
if (!item) {
|
||||
continue;
|
||||
} else if (Array.isArray(item)) {
|
||||
queue.push(...item);
|
||||
} else if (item.type === 'ImportDeclaration') {
|
||||
// Exclude looking for identifiers in import statements
|
||||
continue;
|
||||
} else if (item.type === 'Identifier') {
|
||||
// Only track import usages
|
||||
if (usedMap.has(item.name)) usedMap.set(item.name, true);
|
||||
} else if (typeof item === 'object') {
|
||||
queue.push(Object.values(item));
|
||||
}
|
||||
}
|
||||
|
||||
for (const [name, used] of usedMap.entries()) {
|
||||
if (!used) delete mod.imports[name];
|
||||
}
|
||||
}
|
||||
|
||||
function deleteImportAst(
|
||||
mod: ProxifiedModule,
|
||||
shouldDelete: (node: any) => boolean,
|
||||
): void {
|
||||
const importIndexesToDelete: number[] = [];
|
||||
(mod.$ast as any).body.forEach((node: any, index: number) => {
|
||||
if (node.type === 'ImportDeclaration' && shouldDelete(node)) {
|
||||
importIndexesToDelete.push(index);
|
||||
}
|
||||
});
|
||||
importIndexesToDelete.reverse().forEach((i) => {
|
||||
delete (mod.$ast as any).body[i];
|
||||
});
|
||||
}
|
||||
|
||||
function removeSideEffectImports(mod: ProxifiedModule): void {
|
||||
deleteImportAst(mod, (node) => node.specifiers.length === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Util to get the AST as a simple JSON object, stripping out large objects and file locations to keep it readible
|
||||
*/
|
||||
function getSimpleAstJson(ast: any): any {
|
||||
if (!ast) {
|
||||
return ast;
|
||||
} else if (Array.isArray(ast)) {
|
||||
return ast.map(getSimpleAstJson);
|
||||
} else if (typeof ast === 'object') {
|
||||
return Object.fromEntries(
|
||||
Object.entries(ast)
|
||||
.filter(
|
||||
([key, value]) => key !== 'loc' && key !== 'start' && key !== 'end',
|
||||
)
|
||||
.map(([key, value]) => [key, getSimpleAstJson(value)]),
|
||||
);
|
||||
} else {
|
||||
return ast;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@ export function defineBackground(
|
||||
export function defineBackground(
|
||||
arg: (() => void) | BackgroundDefinition,
|
||||
): BackgroundDefinition {
|
||||
if (typeof arg === 'function') return { main: arg };
|
||||
if (arg == null || typeof arg === 'function') return { main: arg };
|
||||
return arg;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@ export function defineUnlistedScript(
|
||||
export function defineUnlistedScript(
|
||||
arg: (() => void) | UnlistedScriptDefinition,
|
||||
): UnlistedScriptDefinition {
|
||||
if (typeof arg === 'function') return { main: arg };
|
||||
if (arg == null || typeof arg === 'function') return { main: arg };
|
||||
return arg;
|
||||
}
|
||||
|
||||
@@ -18,10 +18,7 @@ export default defineConfig({
|
||||
ignored: '**/dist/**',
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
// @ts-expect-error: Vite version mismatch
|
||||
RandomSeed(),
|
||||
],
|
||||
plugins: [RandomSeed()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'wxt/testing': path.resolve('src/testing'),
|
||||
|
||||
Generated
+291
-4
@@ -84,6 +84,34 @@ importers:
|
||||
specifier: ^2.4.5
|
||||
version: 2.4.5
|
||||
|
||||
packages/auto-icons:
|
||||
dependencies:
|
||||
defu:
|
||||
specifier: ^6.1.4
|
||||
version: 6.1.4
|
||||
fs-extra:
|
||||
specifier: ^11.2.0
|
||||
version: 11.2.0
|
||||
sharp:
|
||||
specifier: ^0.33.4
|
||||
version: 0.33.4
|
||||
devDependencies:
|
||||
'@aklinker1/check':
|
||||
specifier: ^1.3.1
|
||||
version: 1.3.1(typescript@5.5.3)
|
||||
publint:
|
||||
specifier: ^0.2.9
|
||||
version: 0.2.9
|
||||
typescript:
|
||||
specifier: ^5.5.3
|
||||
version: 5.5.3
|
||||
unbuild:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0(typescript@5.5.3)
|
||||
wxt:
|
||||
specifier: workspace:*
|
||||
version: link:../wxt
|
||||
|
||||
packages/module-react:
|
||||
dependencies:
|
||||
'@vitejs/plugin-react':
|
||||
@@ -389,6 +417,9 @@ importers:
|
||||
'@types/react-dom':
|
||||
specifier: ^18.3.0
|
||||
version: 18.3.0
|
||||
'@wxt-dev/auto-icons':
|
||||
specifier: workspace:*
|
||||
version: link:../auto-icons
|
||||
sass:
|
||||
specifier: ^1.77.8
|
||||
version: 1.77.8
|
||||
@@ -940,6 +971,14 @@ packages:
|
||||
- '@algolia/client-search'
|
||||
dev: true
|
||||
|
||||
/@emnapi/runtime@1.2.0:
|
||||
resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
tslib: 2.6.0
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/aix-ppc64@0.19.12:
|
||||
resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1528,6 +1567,194 @@ packages:
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13'}
|
||||
dev: true
|
||||
|
||||
/@img/sharp-darwin-arm64@0.33.4:
|
||||
resolution: {integrity: sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==}
|
||||
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.0.2
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-darwin-x64@0.33.4:
|
||||
resolution: {integrity: sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==}
|
||||
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-x64': 1.0.2
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-libvips-darwin-arm64@1.0.2:
|
||||
resolution: {integrity: sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==}
|
||||
engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-libvips-darwin-x64@1.0.2:
|
||||
resolution: {integrity: sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==}
|
||||
engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-libvips-linux-arm64@1.0.2:
|
||||
resolution: {integrity: sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==}
|
||||
engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-libvips-linux-arm@1.0.2:
|
||||
resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==}
|
||||
engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-libvips-linux-s390x@1.0.2:
|
||||
resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==}
|
||||
engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-libvips-linux-x64@1.0.2:
|
||||
resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==}
|
||||
engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-libvips-linuxmusl-arm64@1.0.2:
|
||||
resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==}
|
||||
engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-libvips-linuxmusl-x64@1.0.2:
|
||||
resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==}
|
||||
engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-linux-arm64@0.33.4:
|
||||
resolution: {integrity: sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==}
|
||||
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm64': 1.0.2
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-linux-arm@0.33.4:
|
||||
resolution: {integrity: sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==}
|
||||
engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm': 1.0.2
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-linux-s390x@0.33.4:
|
||||
resolution: {integrity: sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==}
|
||||
engines: {glibc: '>=2.31', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-s390x': 1.0.2
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-linux-x64@0.33.4:
|
||||
resolution: {integrity: sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==}
|
||||
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-x64': 1.0.2
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-linuxmusl-arm64@0.33.4:
|
||||
resolution: {integrity: sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==}
|
||||
engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.0.2
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-linuxmusl-x64@0.33.4:
|
||||
resolution: {integrity: sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==}
|
||||
engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.0.2
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-wasm32@0.33.4:
|
||||
resolution: {integrity: sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [wasm32]
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@emnapi/runtime': 1.2.0
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-win32-ia32@0.33.4:
|
||||
resolution: {integrity: sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@img/sharp-win32-x64@0.33.4:
|
||||
resolution: {integrity: sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@isaacs/cliui@8.0.2:
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -2345,12 +2572,12 @@ packages:
|
||||
resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/acorn@8.12.1:
|
||||
resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/adm-zip@0.5.10:
|
||||
resolution: {integrity: sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==}
|
||||
@@ -2921,6 +3148,21 @@ packages:
|
||||
/color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
/color-string@1.9.1:
|
||||
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
simple-swizzle: 0.2.2
|
||||
dev: false
|
||||
|
||||
/color@4.2.3:
|
||||
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
||||
engines: {node: '>=12.5.0'}
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
color-string: 1.9.1
|
||||
dev: false
|
||||
|
||||
/colord@2.9.3:
|
||||
resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
|
||||
dev: true
|
||||
@@ -3291,6 +3533,11 @@ packages:
|
||||
resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==}
|
||||
dev: false
|
||||
|
||||
/detect-libc@2.0.3:
|
||||
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/dir-glob@3.0.1:
|
||||
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -4188,6 +4435,10 @@ packages:
|
||||
/is-arrayish@0.2.1:
|
||||
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
|
||||
|
||||
/is-arrayish@0.3.2:
|
||||
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
|
||||
dev: false
|
||||
|
||||
/is-bigint@1.0.4:
|
||||
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
|
||||
dependencies:
|
||||
@@ -5004,9 +5255,9 @@ packages:
|
||||
/mlly@1.7.1:
|
||||
resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==}
|
||||
dependencies:
|
||||
acorn: 8.11.3
|
||||
acorn: 8.12.1
|
||||
pathe: 1.1.2
|
||||
pkg-types: 1.1.1
|
||||
pkg-types: 1.1.3
|
||||
ufo: 1.5.3
|
||||
|
||||
/moment@2.29.4:
|
||||
@@ -6241,6 +6492,36 @@ packages:
|
||||
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
|
||||
dev: false
|
||||
|
||||
/sharp@0.33.4:
|
||||
resolution: {integrity: sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==}
|
||||
engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
color: 4.2.3
|
||||
detect-libc: 2.0.3
|
||||
semver: 7.6.2
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.33.4
|
||||
'@img/sharp-darwin-x64': 0.33.4
|
||||
'@img/sharp-libvips-darwin-arm64': 1.0.2
|
||||
'@img/sharp-libvips-darwin-x64': 1.0.2
|
||||
'@img/sharp-libvips-linux-arm': 1.0.2
|
||||
'@img/sharp-libvips-linux-arm64': 1.0.2
|
||||
'@img/sharp-libvips-linux-s390x': 1.0.2
|
||||
'@img/sharp-libvips-linux-x64': 1.0.2
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.0.2
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.0.2
|
||||
'@img/sharp-linux-arm': 0.33.4
|
||||
'@img/sharp-linux-arm64': 0.33.4
|
||||
'@img/sharp-linux-s390x': 0.33.4
|
||||
'@img/sharp-linux-x64': 0.33.4
|
||||
'@img/sharp-linuxmusl-arm64': 0.33.4
|
||||
'@img/sharp-linuxmusl-x64': 0.33.4
|
||||
'@img/sharp-wasm32': 0.33.4
|
||||
'@img/sharp-win32-ia32': 0.33.4
|
||||
'@img/sharp-win32-x64': 0.33.4
|
||||
dev: false
|
||||
|
||||
/shebang-command@1.2.0:
|
||||
resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -6316,6 +6597,12 @@ packages:
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
|
||||
/simple-swizzle@0.2.2:
|
||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
||||
dependencies:
|
||||
is-arrayish: 0.3.2
|
||||
dev: false
|
||||
|
||||
/sisteransi@1.0.5:
|
||||
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
|
||||
dev: false
|
||||
@@ -7266,7 +7553,7 @@ packages:
|
||||
peerDependencies:
|
||||
vite: ^4.0.0 || ^5.0.0
|
||||
dependencies:
|
||||
vite: 5.3.4(sass@1.77.8)
|
||||
vite: 5.3.4(@types/node@20.14.11)
|
||||
dev: true
|
||||
|
||||
/vitest@2.0.3:
|
||||
|
||||
@@ -27,7 +27,8 @@ const rawCommits = await listCommitsInDir(pkgDir, prevTag);
|
||||
const commits = parseCommits(rawCommits, config);
|
||||
|
||||
// Bump version
|
||||
let bumpType = determineSemverChange(commits, config) ?? 'patch';
|
||||
const originalBumpType = determineSemverChange(commits, config) ?? 'patch';
|
||||
let bumpType = originalBumpType;
|
||||
if (currentVersion.startsWith('0.')) {
|
||||
if (bumpType === 'major') {
|
||||
bumpType = 'minor';
|
||||
@@ -54,7 +55,7 @@ let versionChangelogBody = versionChangelog
|
||||
.slice(1)
|
||||
.join('\n')
|
||||
.trim();
|
||||
if (bumpType === 'major') {
|
||||
if (originalBumpType === 'major') {
|
||||
versionChangelogBody = versionChangelogBody.replace(
|
||||
'[compare changes]',
|
||||
`[⚠️ breaking changes](https://wxt.dev/guide/upgrade-guide/wxt) • [compare changes]`,
|
||||
|
||||
Reference in New Issue
Block a user