MetaMask / MetaMask/metamask-extension

Dual-Track Bundle Size Migration Plan

Open
#41,629 0 comments 0 reactions 1 assignee View on GitHub

@davidmurdoch is already working on this.

Since Apr 9, 2026.

INVALID-ISSUE-TEMPLATE
Dominant language
TypeScript
Stars
13.2k
Forks
5.6k
Avg merge
2d 5h
Merged PRs (30d)
451

Description

# Dual-Track Bundle Size Migration Plan

## Summary
- Make webpack bundle-reporting use a single `--stats` flag and remove `--bundleAnalyzer`.
- Run bundle-size tracking for both bundlers during the transition, but never compare webpack to browserify.
- Introduce a new stats schema with explicit bundler metadata and a new `contentScripts` category.
- Use webpack-generated `stats.json` as the source of truth for webpack classification, not filename regexes.
- Start fresh on baseline history: no legacy fallback and no historical backfill.

## Public Interfaces And Data Shapes
- Webpack CLI:
- Remove `--bundleAnalyzer`.
- Redefine `--stats` to mean “full bundle reporting mode”: verbose console stats, static analyzer HTML, and machine-readable `stats.json`.
- Bundle-size collector CLI:
- Add explicit inputs so the collector is bundler-aware:
- `--bundler browserify|webpack`
- `--dist-dir `
- `--out `
- `--stats-file ` required for webpack, ignored for browserify
- Per-run artifact shape:
```ts
type BundleSizeArtifactV2 = {
schemaVersion: 2;
bundler: 'browserify' | 'webpack';
background: { name: 'background'; size: number; fileList: FileStat[] };
ui: { name: 'ui'; size: number; fileList: FileStat[] };
common: { name: 'common'; size: number; fileList: FileStat[] };
contentScripts: { name: 'contentScripts'; size: number; fileList: FileStat[] };
};

type BundleSizeSummaryV2 = {
schemaVersion: 2;
bundler: 'browserify' | 'webpack';
background: number;
ui: number;
common: number;
contentScripts: number;
timestamp: number;
};
```
- Baseline store shape in `extension_bundlesize_stats`:
```ts
type StoredBundleSizeDataV2 = Record<
string,
Partial>
>;
```

## Implementation Changes
- Webpack reporting:
- Update webpack CLI parsing and tests so `--stats` controls both console verbosity and bundle-report generation.
- Fix the current stats logging path so `--stats` reliably prints full webpack stats even after webpack normalizes `options.stats`.
- When `--stats` is enabled, emit both `dist/report.html` and `dist/stats.json` from the analyzer plugin.
- Keep the existing analyzer HTML artifact URL stable; add `stats.json` alongside it.

- Bundle-size collection:
- Replace the current single browserify-specific scanner with a bundler-aware collector.
- Browserify path:
- Keep existing `background`, `ui`, and `common` logic unchanged.
- Add `contentScripts` as the sum of `scripts/contentscript.js`, `scripts/inpage.js`, and `vendor/trezor/content-script.js`.
- Webpack path:
- Use analyzer-generated `stats.json` as the source of truth.
- Define logical surfaces as:
- `ui`: `bootstrap`, `home`, `notification`, `popup`, `sidepanel` and any emitted JS for `loading` / `popup-init` if present
- `background`: `service-worker`, `offscreen`, `usb-permissions`
- `contentScripts`: `scripts/contentscript.js`, `scripts/inpage.js`, `vendor/trezor/content-script.js`
- Derive emitted initial JS asset sets per surface from webpack stats.
- Compute disjoint categories:
- `contentScripts`: all content-script assets, excluded from the other categories
- `common`: assets used by at least one UI surface and at least one background surface
- `ui`: UI assets not in `common`
- `background`: background assets not in `common`
- Keep `fileList` stable and sorted by emitted asset path.

- CI and PR comment flow:
- Change the bundle-size workflow to depend on both `build-dist-browserify` and `build-dist-webpack`.
- Download both build artifacts in the same job and run the collector twice, writing separate outputs under bundler-specific directories.
- Upload a single bundle-size artifact tree containing both bundlers.
- Record both summaries into the external baseline store under the same commit SHA, keyed by bundler.
- Update the PR comment builder to render two separate collapsible sections: Browserify and Webpack.
- Each section must only compare against the same bundler and the same `schemaVersion`.
- If the merge-base baseline is missing, the schema version differs, or the stored bundler does not match, render “comparison unavailable” for that bundler instead of throwing.
- Preserve the existing warning threshold logic on `background + common` and `ui + common`.
- Show `contentScripts` as a separate informational row only; it does not participate in warnings.

## Test Plan
- Webpack CLI/config tests:
- `--stats` enables analyzer plugin, emits `stats.json`, and preserves verbose console stats.
- `--bundleAnalyzer` no longer exists.
- Stats logging works for normalized webpack config values, not just the literal `'normal'`.
- Bundle-size collector tests:
- Browserify fixtures still produce the same `background/ui/common` numbers and now add `contentScripts`.
- Webpack fixture stats classify assets into `background`, `ui`, `common`, and `contentScripts` exactly as specified.
- Content-script assets are excluded from `background/ui/common`.
- PR comment tests:
- Two sections render independently for browserify and webpack.
- Same-bundler comparison works.
- Cross-schema, cross-bundler, and missing-baseline cases render “comparison unavailable” rather than erroring.
- `contentScripts` is rendered but ignored by warning logic.
- Workflow/artifact tests:
- The bundle-size job consumes both build artifacts and publishes both bundler outputs.
- External baseline writer merges both bundlers under one SHA without overwriting the other.

## Assumptions And Defaults
- `--stats` is the only webpack bundle-reporting flag after this change.
- Dual-track mode is PR-facing: both Browserify and Webpack sections are shown during the transition.
- The new schema starts fresh; old stored bundle-size history is not migrated and not read through compatibility fallbacks.
- For webpack, `background` includes `service-worker`, `offscreen`, and `trezor-usb-permissions`.
- `vendor/trezor/content-script.js` is counted in `contentScripts`.
- `contentScripts` is informational only and does not affect bundle-size warnings.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.