Compare commits

..

17 Commits

Author SHA1 Message Date
GitHub Actions 9d97164c20 chore(release): v0.16.6 2024-02-10 10:29:52 +00:00
lionelhorn 6d526e7043 feat: Add option to customize the analysis artifacts output (#431)
Co-authored-by: Aaron Klinker <aaronklinker1@gmail.com>
2024-02-10 04:26:33 -06:00
Aaron Klinker 946072fc5a docs: Fix createShadowRootUi unmount calls 2024-02-10 04:04:16 -06:00
Aaron Klinker 6b8dfdf02d chore: Enable skipped test since it works now 2024-02-10 03:01:38 -06:00
okou ba85fdf470 fix: Use insertBefore on mounting content script UI 2024-02-10 03:01:38 -06:00
okou 295f8601e3 refactor: Use Element.prepend on mounting UI 2024-02-10 03:01:38 -06:00
Aaron a38ccd8624 doc: Fix custom block 2024-02-09 05:20:51 -06:00
GitHub Actions b2dcec2f8a chore(release): v0.16.5 2024-02-09 06:01:00 +00:00
Aaron Klinker e8355029d9 fix: Support node 20 when running wxt submit 2024-02-08 23:55:53 -06:00
Aaron Klinker 2b374b98d2 docs: Remove "coming soon" from automated publishing feature 2024-02-05 23:36:13 -06:00
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
24 changed files with 375 additions and 73 deletions
+60 -1
View File
@@ -1,5 +1,64 @@
# Changelog
## v0.16.6
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.16.5...v0.16.6)
### 🚀 Enhancements
- Add option to customize the analysis artifacts output ([#431](https://github.com/wxt-dev/wxt/pull/431))
### 🩹 Fixes
- Use `insertBefore` on mounting content script UI ([ba85fdf](https://github.com/wxt-dev/wxt/commit/ba85fdf))
### 💅 Refactors
- Use `Element.prepend` on mounting UI ([295f860](https://github.com/wxt-dev/wxt/commit/295f860))
### 📖 Documentation
- Fix `createShadowRootUi` unmount calls ([946072f](https://github.com/wxt-dev/wxt/commit/946072f))
### 🏡 Chore
- Enable skipped test since it works now ([6b8dfdf](https://github.com/wxt-dev/wxt/commit/6b8dfdf))
### ❤️ Contributors
- Lionelhorn
- Okou
## v0.16.5
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.16.4...v0.16.5)
### 🩹 Fixes
- Support node 20 when running `wxt submit` ([e835502](https://github.com/wxt-dev/wxt/commit/e835502))
### 📖 Documentation
- Remove "coming soon" from automated publishing feature ([2b374b9](https://github.com/wxt-dev/wxt/commit/2b374b9))
## 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 +85,7 @@
### ❤️ Contributors
- Chen Hua <hcljsq@gmail.com>
- Chen Hua ([@hcljsq](https://github.com/hcljsq))
- Florian Metz ([@Timeraa](http://github.com/Timeraa))
## v0.16.2
+2 -5
View File
@@ -55,14 +55,11 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get
- 📂 File based entrypoints
- 🚔 TypeScript
- 🦾 Auto-imports
- ⬇️ Download and bundle remote URL imports
- 🤖 Automated publishing
- 🎨 Frontend framework agnostic: works with Vue, React, Svelte, etc
- 🖍️ Quickly bootstrap a new project
- 📏 Bundle analysis
### Coming Soon
- 🤖 Automated publishing
- ⬇️ Download and bundle remote URL imports
## Contributors
+4 -4
View File
@@ -233,7 +233,7 @@ export default defineContentScript({
},
onRemove: (app) => {
// Unmount the app when the UI is removed
app.unmount();
app?.unmount();
},
});
@@ -268,7 +268,7 @@ export default defineContentScript({
},
onRemove: (root) => {
// Unmount the root when the UI is removed
root.unmount();
root?.unmount();
},
});
@@ -303,7 +303,7 @@ export default defineContentScript({
},
onRemove: (app) => {
// Destroy the app when the UI is removed
app.$destroy();
app?.$destroy();
},
});
@@ -335,7 +335,7 @@ export default defineContentScript({
},
onRemove: (unmount) => {
// Unmount the app when the UI is removed
unmount();
unmount?.();
},
});
+1 -1
View File
@@ -83,6 +83,6 @@ Normally, to manually reload an extension, you have to visit `chrome://extension
When running `wxt` command to start the dev server, WXT adds a keyboard shortcut, `ctrl+E` for Windows/Linux and `cmd+E` for Mac, that reloads the extension when pressed, without visiting `chrome://extensions`.
:::note
:::info
This shortcut is only available during development, and is not be added to your extension when running `wxt build` or `wxt-zip`.
:::
+8 -8
View File
@@ -47,11 +47,9 @@ features:
details: Nuxt-like auto-imports to speed up development.
link: /guide/auto-imports
linkText: Read docs
- icon: ⬇️
title: Bundle Remote Code
details: Downloads and bundles remote code imported from URLs.
link: /guide/remote-code
linkText: Read docs
- icon: 🤖
title: Automated Publishing
details: Automatically zip, upload, submit, and publish extensions.
- icon: 🎨
title: Frontend Framework Agnostic
details: Works with any front-end framework with a Vite plugin.
@@ -65,9 +63,11 @@ features:
- icon: 📏
title: Bundle Analysis
details: Tools for analyizing the final extension bundle and minimizing your extension's size.
- icon: 🤖
title: Automated Publishing
details: 'Coming soon. Automatically zip, upload, and release extensions.'
- icon: ⬇️
title: Bundle Remote Code
details: Downloads and bundles remote code imported from URLs.
link: /guide/remote-code
linkText: Read docs
---
<section class="vp-doc">
+93
View File
@@ -0,0 +1,93 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { TestProject } from '../utils';
import { resetBundleIncrement } from '~/core/builders/vite/plugins';
describe('Analysis', () => {
beforeEach(() => {
resetBundleIncrement();
});
it('should outptut a stats.html with no part files by default', async () => {
const project = new TestProject();
project.addFile('entrypoints/popup.html');
project.addFile('entrypoints/options.html');
project.addFile(
'entrypoints/background.ts',
'export default defineBackground(() => {});',
);
await project.build({
analysis: {
enabled: true,
},
});
expect(await project.fileExists('stats.html')).toBe(true);
expect(await project.fileExists('.output/chrome-mv3/stats-0.json')).toBe(
false,
);
});
it('should save part files when requested', async () => {
const project = new TestProject();
project.addFile('entrypoints/popup.html');
project.addFile('entrypoints/options.html');
project.addFile(
'entrypoints/background.ts',
'export default defineBackground(() => {});',
);
await project.build({
analysis: {
enabled: true,
keepArtifacts: true,
},
});
expect(await project.fileExists('stats.html')).toBe(true);
expect(await project.fileExists('stats-0.json')).toBe(true);
expect(await project.fileExists('stats-1.json')).toBe(true);
});
it('should support customizing the stats output directory', async () => {
const project = new TestProject();
project.addFile('entrypoints/popup.html');
project.addFile('entrypoints/options.html');
project.addFile(
'entrypoints/background.ts',
'export default defineBackground(() => {});',
);
await project.build({
analysis: {
enabled: true,
outputFile: 'stats/bundle.html',
},
});
expect(await project.fileExists('stats/bundle.html')).toBe(true);
});
it('should place artifacts next to the custom output file', async () => {
const project = new TestProject();
project.addFile('entrypoints/popup.html');
project.addFile('entrypoints/options.html');
project.addFile(
'entrypoints/background.ts',
'export default defineBackground(() => {});',
);
await project.build({
analysis: {
enabled: true,
outputFile: 'stats/bundle.html',
keepArtifacts: true,
},
});
console.log(project.root);
expect(await project.fileExists('stats/bundle.html')).toBe(true);
expect(await project.fileExists('stats/bundle-0.json')).toBe(true);
expect(await project.fileExists('stats/bundle-1.json')).toBe(true);
});
});
+2 -3
View File
@@ -1,7 +1,7 @@
{
"name": "wxt",
"type": "module",
"version": "0.16.3",
"version": "0.16.6",
"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",
@@ -133,7 +132,7 @@
"ora": "^7.0.1",
"picocolors": "^1.0.0",
"prompts": "^2.4.2",
"publish-browser-extension": "^2.1.1",
"publish-browser-extension": "^2.1.2",
"rollup-plugin-visualizer": "^5.9.2",
"unimport": "^3.4.0",
"vite": "^5.0.12",
+5 -12
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
@@ -99,8 +96,8 @@ importers:
specifier: ^2.4.2
version: 2.4.2
publish-browser-extension:
specifier: ^2.1.1
version: 2.1.1
specifier: ^2.1.2
version: 2.1.2
rollup-plugin-visualizer:
specifier: ^5.9.2
version: 5.12.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==}
@@ -4168,9 +4161,9 @@ packages:
sade: 1.8.1
dev: true
/publish-browser-extension@2.1.1:
resolution: {integrity: sha512-WqCnhHXbmiYn4vIbgcyKWVHiOvCoPjjpt3X+hfnU8rlOozU43TURpHUWZlQ0W49LhvJvBRsBfGRQxtRMGhqsxw==}
engines: {node: '18', pnpm: '8'}
/publish-browser-extension@2.1.2:
resolution: {integrity: sha512-g6+mtdR4Z+GYHPIrfaAwC7Kbt1oQlpJ8r0x1PAytScy33OFdK+HVUeDDYorBpPAiQlmYJRQga7rY9QVTyTw34g==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
dependencies:
cac: 6.7.14
@@ -367,7 +367,7 @@ describe('Content Script UIs', () => {
});
});
describe.todo('after', () => {
describe('after', () => {
it('should append the UI after the anchor', () => {
const ui = createIntegratedUi(ctx, {
position: 'inline',
+3 -7
View File
@@ -211,20 +211,16 @@ function mountUi(
anchor.append(root);
break;
case 'first':
if (anchor.firstChild) {
anchor.insertBefore(root, anchor.firstChild);
} else {
anchor.append(root);
}
anchor.prepend(root);
break;
case 'replace':
anchor.replaceWith(root);
break;
case 'after':
anchor.replaceWith(anchor, root);
anchor.parentElement?.insertBefore(root, anchor.nextElementSibling);
break;
case 'before':
anchor.replaceWith(root, anchor);
anchor.parentElement?.insertBefore(root, anchor);
break;
default:
options.append(anchor, root);
+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,25 @@
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`,
}) as vite.Plugin;
filename: path.resolve(
config.analysis.outputDir,
`${config.analysis.outputName}-${increment++}.json`,
),
});
}
/**
* @deprecated FOR TESTING ONLY.
*/
export function resetBundleIncrement() {
increment = 0;
}
+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 });
}
}
+15 -4
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)}`,
);
}
@@ -86,17 +87,27 @@ export async function internalBuild(): Promise<BuildOutput> {
}
async function combineAnalysisStats(): Promise<void> {
const unixFiles = await glob(`stats-*.json`, {
cwd: wxt.config.outDir,
const unixFiles = await glob(`${wxt.config.analysis.outputName}-*.json`, {
cwd: wxt.config.analysis.outputDir,
absolute: true,
});
const absolutePaths = unixFiles.map(unnormalizePath);
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' },
);
if (!wxt.config.analysis.keepArtifacts) {
await Promise.all(absolutePaths.map((statsFile) => fs.remove(statsFile)));
}
}
function printValidationResults({
+13 -3
View File
@@ -100,6 +100,13 @@ export async function resolveConfig(
}).map(([key, value]) => [key, path.resolve(root, value)]),
);
const analysisOutputFile = path.resolve(
root,
mergedConfig.analysis?.outputFile ?? 'stats.html',
);
const analysisOutputDir = path.dirname(analysisOutputFile);
const analysisOutputName = path.parse(analysisOutputFile).name;
const finalConfig: Omit<ResolvedConfig, 'builder'> = {
browser,
command,
@@ -129,6 +136,10 @@ export async function resolveConfig(
analysis: {
enabled: mergedConfig.analysis?.enabled ?? false,
template: mergedConfig.analysis?.template ?? 'treemap',
outputFile: analysisOutputFile,
outputDir: analysisOutputDir,
outputName: analysisOutputName,
keepArtifacts: mergedConfig.analysis?.keepArtifacts ?? false,
},
userConfigMetadata: userConfigMetadata ?? {},
alias,
@@ -216,9 +227,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.`,
);
}
}
+4
View File
@@ -236,6 +236,10 @@ export const fakeResolvedConfig = fakeObjectCreator<ResolvedConfig>(() => {
analysis: {
enabled: false,
template: 'treemap',
outputFile: fakeFile(),
outputDir: fakeDir(),
outputName: 'stats',
keepArtifacts: false,
},
zip: {
artifactTemplate: '{{name}}-{{version}}.zip',
+28
View File
@@ -209,6 +209,27 @@ export interface InlineConfig {
* @default "treemap"
*/
template?: PluginVisualizerOptions['template'];
/**
* Name of the output HTML file. Relative to the project's root directory.
*
* Changing the filename of the outputFile also effects the names of the artifacts generated
* when setting `keepArtifacts` to true:
* - "stats.html" => "stats-*.json"
* - "stats/bundle.html" => "bundle-*.json"
* - ".analysis/index.html" => "index-*.json"
*
* @default "stats.html"
*/
outputFile?: string;
/**
* By default, the `stats-*.json` artifacts generated during bundle analysis are deleted. Set to
* `true` to keep them.
*
* One stats file is output per build step.
*
* @default false
*/
keepArtifacts?: boolean;
};
/**
* Add additional paths to the `.wxt/tsconfig.json`. Use this instead of overwriting the `paths`
@@ -895,6 +916,13 @@ export interface ResolvedConfig {
analysis: {
enabled: boolean;
template: NonNullable<PluginVisualizerOptions['template']>;
/** Absolute file path to the `stats.html` file */
outputFile: string;
/** The directory where the final `stats.html` file is located */
outputDir: string;
/** Name of the `stats.html` file, minus ".html" */
outputName: string;
keepArtifacts: boolean;
};
userConfigMetadata: Omit<C12ResolvedConfig<UserConfig>, 'config'>;
/**
+1
View File
@@ -10,6 +10,7 @@ lerna-debug.log*
node_modules
.output
stats.html
stats-*.json
.wxt
web-ext.config.ts
+1
View File
@@ -10,6 +10,7 @@ lerna-debug.log*
node_modules
.output
stats.html
stats-*.json
.wxt
web-ext.config.ts
+1
View File
@@ -10,6 +10,7 @@ lerna-debug.log*
node_modules
.output
stats.html
stats-*.json
.wxt
web-ext.config.ts
+1
View File
@@ -10,6 +10,7 @@ lerna-debug.log*
node_modules
.output
stats.html
stats-*.json
.wxt
web-ext.config.ts
+1
View File
@@ -10,6 +10,7 @@ lerna-debug.log*
node_modules
.output
stats.html
stats-*.json
.wxt
web-ext.config.ts