Compare commits

..

7 Commits

Author SHA1 Message Date
GitHub Actions d14d76a0c8 chore(release): v0.16.4 2024-02-06 05:21:00 +00:00
Aaron Klinker d0f1c7065c chore: Fix fake path in test data generator 2024-02-05 23:17:14 -06:00
Aaron 3edb66d76d feat: Add option to customize the analysis output filename (#426) 2024-02-05 23:15:15 -06:00
Aaron bba8cdace1 fix: Exclude analysis files from the build summary (#425) 2024-02-05 23:09:30 -06:00
Aaron 22f82a67ee feat: Automatically convert MV3 web_accessible_resources to MV2 (#423) 2024-02-05 22:49:18 -06:00
Aaron b32c60ca73 fix: Don't use immer for transformManifest (#424) 2024-02-05 22:37:26 -06:00
Aaron Klinker c93620cba5 Update changelog 2024-02-04 17:48:26 -06:00
12 changed files with 165 additions and 38 deletions
+19 -1
View File
@@ -1,5 +1,23 @@
# Changelog
## v0.16.4
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.16.3...v0.16.4)
### 🚀 Enhancements
- Automatically convert MV3 `web_accessible_resources` to MV2 ([#423](https://github.com/wxt-dev/wxt/pull/423))
- Add option to customize the analysis output filename ([#426](https://github.com/wxt-dev/wxt/pull/426))
### 🩹 Fixes
- Don't use immer for `transformManifest` ([#424](https://github.com/wxt-dev/wxt/pull/424))
- Exclude analysis files from the build summary ([#425](https://github.com/wxt-dev/wxt/pull/425))
### 🏡 Chore
- Fix fake path in test data generator ([d0f1c70](https://github.com/wxt-dev/wxt/commit/d0f1c70))
## v0.16.3
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.16.2...v0.16.3)
@@ -26,7 +44,7 @@
### ❤️ Contributors
- Chen Hua <hcljsq@gmail.com>
- Chen Hua ([@hcljsq](https://github.com/hcljsq))
- Florian Metz ([@Timeraa](http://github.com/Timeraa))
## v0.16.2
+1 -2
View File
@@ -1,7 +1,7 @@
{
"name": "wxt",
"type": "module",
"version": "0.16.3",
"version": "0.16.4",
"description": "Next gen framework for developing web extensions",
"engines": {
"node": ">=18",
@@ -121,7 +121,6 @@
"get-port": "^7.0.0",
"giget": "^1.1.3",
"hookable": "^5.5.3",
"immer": "^10.0.3",
"is-wsl": "^3.0.0",
"jiti": "^1.21.0",
"json5": "^2.2.3",
-7
View File
@@ -62,9 +62,6 @@ importers:
hookable:
specifier: ^5.5.3
version: 5.5.3
immer:
specifier: ^10.0.3
version: 10.0.3
is-wsl:
specifier: ^3.0.0
version: 3.1.0
@@ -2930,10 +2927,6 @@ packages:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
dev: false
/immer@10.0.3:
resolution: {integrity: sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==}
dev: false
/immutable@4.3.4:
resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==}
+1 -1
View File
@@ -66,7 +66,7 @@ export async function createViteBuilder(
wxtPlugins.defineImportMeta(),
);
if (wxtConfig.analysis.enabled) {
config.plugins.push(wxtPlugins.bundleAnalysis());
config.plugins.push(wxtPlugins.bundleAnalysis(wxtConfig));
}
return config;
@@ -1,12 +1,15 @@
import type * as vite from 'vite';
import { visualizer } from 'rollup-plugin-visualizer';
import { ResolvedConfig } from '~/types';
import path from 'node:path';
let increment = 0;
export function bundleAnalysis(): vite.Plugin {
export function bundleAnalysis(
config: Omit<ResolvedConfig, 'builder'>,
): vite.Plugin {
return visualizer({
emitFile: true,
template: 'raw-data',
filename: `stats-${increment++}.json`,
filename: path.resolve(config.outDir, `stats-${increment++}.json`),
}) as vite.Plugin;
}
+49
View File
@@ -851,6 +851,55 @@ describe('Manifest Utils', () => {
'content-scripts/one.css',
]);
});
it('should convert mv3 items to mv2 strings automatically', async () => {
setFakeWxt({
config: {
outDir,
manifestVersion: 2,
manifest: {
web_accessible_resources: [
{
matches: ['*://*/*'],
resources: ['/icon-128.png'],
},
{
matches: ['https://google.com'],
resources: ['/icon-128.png', '/icon-32.png'],
},
],
},
},
});
const { manifest: actual } = await generateManifest(
[],
fakeBuildOutput(),
);
expect(actual.web_accessible_resources).toEqual([
'/icon-128.png',
'/icon-32.png',
]);
});
it('should convert mv2 strings to mv3 items with a warning automatically', async () => {
setFakeWxt({
config: {
outDir,
manifestVersion: 3,
manifest: {
web_accessible_resources: ['/icon.svg'],
},
},
});
await expect(() =>
generateManifest([], fakeBuildOutput()),
).rejects.toThrow(
'Non-MV3 web_accessible_resources detected: ["/icon.svg"]. When manually defining web_accessible_resources, define them as MV3 objects ({ matches: [...], resources: [...] }), and WXT will automatically convert them to MV2 when necessary.',
);
});
});
describe('transformManifest option', () => {
@@ -20,6 +20,7 @@ export async function buildEntrypoints(
try {
steps.push(await wxt.config.builder.build(group));
} catch (err) {
wxt.logger.error(err);
throw Error(`Failed to build ${groupNames.join(', ')}`, { cause: err });
}
}
+10 -2
View File
@@ -77,8 +77,9 @@ export async function internalBuild(): Promise<BuildOutput> {
if (wxt.config.analysis.enabled) {
await combineAnalysisStats();
const statsPath = relative(wxt.config.root, wxt.config.analysis.outputFile);
wxt.logger.info(
`Analysis complete:\n ${pc.gray('└─')} ${pc.yellow('stats.html')}`,
`Analysis complete:\n ${pc.gray('└─')} ${pc.yellow(statsPath)}`,
);
}
@@ -94,9 +95,16 @@ async function combineAnalysisStats(): Promise<void> {
await exec(
'rollup-plugin-visualizer',
[...absolutePaths, '--template', wxt.config.analysis.template],
[
...absolutePaths,
'--template',
wxt.config.analysis.template,
'--filename',
wxt.config.analysis.outputFile,
],
{ cwd: wxt.config.root, stdio: 'inherit' },
);
await Promise.all(absolutePaths.map((statsFile) => fs.remove(statsFile)));
}
function printValidationResults({
+6 -3
View File
@@ -129,6 +129,10 @@ export async function resolveConfig(
analysis: {
enabled: mergedConfig.analysis?.enabled ?? false,
template: mergedConfig.analysis?.template ?? 'treemap',
outputFile: path.resolve(
root,
mergedConfig.analysis?.outputFile ?? 'stats.html',
),
},
userConfigMetadata: userConfigMetadata ?? {},
alias,
@@ -216,9 +220,8 @@ function mergeInlineConfig(
outDir: inlineConfig.outDir ?? userConfig.outDir,
zip,
analysis: {
enabled: inlineConfig.analysis?.enabled ?? userConfig.analysis?.enabled,
template:
inlineConfig.analysis?.template ?? userConfig.analysis?.template,
...userConfig.analysis,
...inlineConfig.analysis,
},
alias: {
...userConfig.alias,
+63 -19
View File
@@ -21,7 +21,6 @@ import {
import { getPackageJson } from './package';
import { normalizePath } from './paths';
import { writeFileIfDifferent } from './fs';
import { produce } from 'immer';
import defu from 'defu';
import { wxt } from '../wxt';
@@ -78,7 +77,7 @@ export async function generateManifest(
};
const userManifest = wxt.config.manifest;
const manifest = defu(
let manifest = defu(
userManifest,
baseManifest,
) as Manifest.WebExtensionManifest;
@@ -113,21 +112,29 @@ export async function generateManifest(
if (wxt.config.command === 'serve') addDevModeCsp(manifest);
if (wxt.config.command === 'serve') addDevModePermissions(manifest);
const finalManifest = produce(manifest, wxt.config.transformManifest);
await wxt.hooks.callHook('build:manifestGenerated', wxt, finalManifest);
// TODO: Remove in v1
wxt.config.transformManifest(manifest);
await wxt.hooks.callHook('build:manifestGenerated', wxt, manifest);
if (finalManifest.name == null)
if (wxt.config.manifestVersion === 2)
convertWebAccessibleResourcesToMv2(manifest);
if (wxt.config.manifestVersion === 3) {
validateMv3WebAccessbileResources(manifest);
}
if (manifest.name == null)
throw Error(
"Manifest 'name' is missing. Either:\n1. Set the name in your <rootDir>/package.json\n2. Set a name via the manifest option in your wxt.config.ts",
);
if (finalManifest.version == null) {
if (manifest.version == null) {
throw Error(
"Manifest 'version' is missing. Either:\n1. Add a version in your <rootDir>/package.json\n2. Pass the version via the manifest option in your wxt.config.ts",
);
}
return {
manifest: finalManifest,
manifest,
warnings,
};
}
@@ -501,7 +508,8 @@ export function getContentScriptCssWebAccessibleResources(
contentScripts: ContentScriptEntrypoint[],
contentScriptCssMap: Record<string, string | undefined>,
): any[] {
const resources: any[] = [];
const resources: Manifest.WebExtensionManifestWebAccessibleResourcesC2ItemType[] =
[];
contentScripts.forEach((script) => {
if (script.options.cssInjectionMode !== 'ui') return;
@@ -509,17 +517,13 @@ export function getContentScriptCssWebAccessibleResources(
const cssFile = contentScriptCssMap[script.name];
if (cssFile == null) return;
if (wxt.config.manifestVersion === 2) {
resources.push(cssFile);
} else {
resources.push({
resources: [cssFile],
matches: resolvePerBrowserOption(
script.options.matches,
wxt.config.browser,
).map((matchPattern) => stripPathFromMatchPattern(matchPattern)),
});
}
resources.push({
resources: [cssFile],
matches: resolvePerBrowserOption(
script.options.matches,
wxt.config.browser,
).map((matchPattern) => stripPathFromMatchPattern(matchPattern)),
});
});
return resources;
@@ -573,3 +577,43 @@ export function stripPathFromMatchPattern(pattern: string) {
const startOfPath = pattern.indexOf('/', protocolSepIndex + 3);
return pattern.substring(0, startOfPath) + '/*';
}
/**
* Converts all MV3 web accessible resources to their MV2 forms. MV3 web accessible resources are
* generated in this file, and may be defined by the user in their manifest. In both cases, when
* targetting MV2, automatically convert their definitions down to the basic MV2 array.
*/
export function convertWebAccessibleResourcesToMv2(
manifest: Manifest.WebExtensionManifest,
): void {
if (manifest.web_accessible_resources == null) return;
manifest.web_accessible_resources = Array.from(
new Set(
manifest.web_accessible_resources.flatMap((item) => {
if (typeof item === 'string') return item;
return item.resources;
}),
),
);
}
/**
* Make sure all resources are in MV3 format. If not, add a wanring
*/
export function validateMv3WebAccessbileResources(
manifest: Manifest.WebExtensionManifest,
): void {
if (manifest.web_accessible_resources == null) return;
const stringResources = manifest.web_accessible_resources.filter(
(item) => typeof item === 'string',
);
if (stringResources.length > 0) {
throw Error(
`Non-MV3 web_accessible_resources detected: ${JSON.stringify(
stringResources,
)}. When manually defining web_accessible_resources, define them as MV3 objects ({ matches: [...], resources: [...] }), and WXT will automatically convert them to MV2 when necessary.`,
);
}
}
+1
View File
@@ -236,6 +236,7 @@ export const fakeResolvedConfig = fakeObjectCreator<ResolvedConfig>(() => {
analysis: {
enabled: false,
template: 'treemap',
outputFile: fakeFile(),
},
zip: {
artifactTemplate: '{{name}}-{{version}}.zip',
+8
View File
@@ -209,6 +209,12 @@ export interface InlineConfig {
* @default "treemap"
*/
template?: PluginVisualizerOptions['template'];
/**
* Name of the output HTML file. Relative to the project's root directory.
*
* @default "stats.html"
*/
outputFile?: string;
};
/**
* Add additional paths to the `.wxt/tsconfig.json`. Use this instead of overwriting the `paths`
@@ -895,6 +901,8 @@ export interface ResolvedConfig {
analysis: {
enabled: boolean;
template: NonNullable<PluginVisualizerOptions['template']>;
/** Absolute file path */
outputFile: string;
};
userConfigMetadata: Omit<C12ResolvedConfig<UserConfig>, 'config'>;
/**