Merge commit '36c66dd290d3ce6eb1ccd310d0c658d4a32bb8eb' as 'repos/effect'
This commit is contained in:
226
repos/effect/packages/tools/bundle/README.md
Normal file
226
repos/effect/packages/tools/bundle/README.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# Bundle Size Development Workflow
|
||||
|
||||
This package contains the internal bundle-size tooling used to measure Effect
|
||||
entrypoints with Rollup, minification, and gzip.
|
||||
|
||||
## AI Agent Instructions
|
||||
|
||||
Use this workflow when a user wants to quickly understand how a local source
|
||||
change affects bundle size for one or more explicitly selected fixture files.
|
||||
|
||||
Do not scan `scratchpad/` or `packages/tools/bundle/fixtures/` for this workflow.
|
||||
Only measure files that the user explicitly names, or files you create
|
||||
specifically for the current investigation.
|
||||
|
||||
Before running a comparison, ask the user which mode they want:
|
||||
|
||||
- default cleanup mode for a single check or one-off investigation;
|
||||
- keep-base mode for many repeated measurements, followed by explicit cleanup at
|
||||
the end.
|
||||
|
||||
Use cleanup mode unless the user says they expect to run multiple trials.
|
||||
|
||||
If the user asks what a generated bundle is made of, use the bundle composition
|
||||
workflow instead of the size comparison workflow.
|
||||
|
||||
### Analyze Bundle Composition
|
||||
|
||||
Use this workflow when the user gives an explicit fixture and wants to
|
||||
understand which modules make up the produced bundle.
|
||||
|
||||
Agent procedure:
|
||||
|
||||
1. Confirm the exact fixture path or paths to analyze. Do not scan directories.
|
||||
2. Run `pnpm bundle-analyze` with only those explicit paths.
|
||||
3. Read the printed Markdown table and identify the generated `*.raw-data.json`
|
||||
path for each fixture.
|
||||
4. Analyze `*.raw-data.json` first. Use `*.treemap.html` only when the user wants
|
||||
a visual artifact to open.
|
||||
5. Report the largest modules, notable dependency groups, and any surprising
|
||||
inclusions. Mention the generated artifact paths in the answer.
|
||||
|
||||
Prefer the repository-level wrapper:
|
||||
|
||||
```sh
|
||||
pnpm bundle-analyze scratchpad/my-fixture.ts
|
||||
```
|
||||
|
||||
You can pass multiple explicit files:
|
||||
|
||||
```sh
|
||||
pnpm bundle-analyze \
|
||||
scratchpad/schema-codec.ts \
|
||||
scratchpad/schema-arbitrary.ts
|
||||
```
|
||||
|
||||
The wrapper builds the current checkout with `pnpm build` before generating
|
||||
analysis artifacts, so the bundle is not produced from stale `dist` files.
|
||||
|
||||
By default, artifacts are written to `tmp/bundle-analysis`. Use `--output-dir`
|
||||
to choose another directory:
|
||||
|
||||
```sh
|
||||
pnpm bundle-analyze --output-dir tmp/schema-analysis scratchpad/my-fixture.ts
|
||||
```
|
||||
|
||||
For each selected fixture, the tool writes:
|
||||
|
||||
- `<name>.min.js`: the generated Rollup output for inspection;
|
||||
- `<name>.treemap.html`: an interactive treemap for human inspection;
|
||||
- `<name>.raw-data.json`: raw visualizer data suitable for AI analysis.
|
||||
|
||||
The analysis build disables identifier mangling so module and export names stay
|
||||
readable in the visualizer output. Use `bundle-compare-selected` or `report`
|
||||
when exact size measurement is the goal.
|
||||
|
||||
After running the command, inspect the Markdown table it prints to find the exact
|
||||
paths. For an AI analysis, read the `*.raw-data.json` file first and summarize
|
||||
the largest modules and dependency groups. Use the `*.treemap.html` file when
|
||||
the user wants to inspect the bundle visually.
|
||||
|
||||
The raw data contains a tree plus module metadata. For a quick size-oriented
|
||||
summary, rank module parts by `renderedLength` or `gzipLength`, then map each
|
||||
part through `metaUid` to `nodeMetas[metaUid].id`.
|
||||
|
||||
Example inspection command:
|
||||
|
||||
```sh
|
||||
node -e 'const data = JSON.parse(require("node:fs").readFileSync(process.argv[1], "utf8")); console.log(Object.entries(data.nodeParts).map(([uid, part]) => ({ uid, id: data.nodeMetas[part.metaUid]?.id, rendered: part.renderedLength, gzip: part.gzipLength })).sort((a, b) => b.rendered - a.rendered).slice(0, 20))' tmp/bundle-analysis/my-fixture.raw-data.json
|
||||
```
|
||||
|
||||
Do not treat the generated `.min.js` size from this workflow as the exact bundle
|
||||
size comparison number. The analysis build keeps names readable for the
|
||||
visualizer. Use `bundle-compare-selected` or `report` for exact size reporting.
|
||||
|
||||
Do not use this workflow to compare against a base ref. Use
|
||||
`bundle-compare-selected` for size impact and `bundle-analyze` for current bundle
|
||||
composition.
|
||||
|
||||
### Compare Explicit Scratchpad Fixtures
|
||||
|
||||
Prefer the repository-level wrapper:
|
||||
|
||||
```sh
|
||||
pnpm bundle-compare-selected --base main scratchpad/my-fixture.ts
|
||||
```
|
||||
|
||||
You can pass multiple explicit files:
|
||||
|
||||
```sh
|
||||
pnpm bundle-compare-selected --base main \
|
||||
scratchpad/schema-codec.ts \
|
||||
scratchpad/schema-arbitrary.ts
|
||||
```
|
||||
|
||||
If `--base` is omitted, the script compares against `main`.
|
||||
|
||||
By default, the wrapper removes `tmp/bundle-base` before exiting, including on
|
||||
failure. This avoids leaving extra git worktree state after a one-off
|
||||
measurement.
|
||||
|
||||
For repeated measurements where the user explicitly wants a faster feedback loop,
|
||||
pass `--keep-base`:
|
||||
|
||||
```sh
|
||||
pnpm bundle-compare-selected --base main --keep-base scratchpad/my-fixture.ts
|
||||
```
|
||||
|
||||
When using `--keep-base`, clean up `tmp/bundle-base` after the last measurement.
|
||||
The explicit final cleanup command is:
|
||||
|
||||
```sh
|
||||
git worktree remove --force tmp/bundle-base
|
||||
```
|
||||
|
||||
The wrapper:
|
||||
|
||||
- builds the current checkout with `pnpm build`;
|
||||
- creates or reuses `tmp/bundle-base` at the requested base ref;
|
||||
- builds the base checkout when needed and writes
|
||||
`tmp/bundle-base/.bundle-build-stamp` only after a successful build;
|
||||
- reuses a kept base checkout only when its HEAD and `.bundle-build-stamp`
|
||||
both match the requested base ref;
|
||||
- copies only the selected files into the base checkout at the same relative
|
||||
paths;
|
||||
- invokes the internal bundle CLI to compare current vs base sizes.
|
||||
|
||||
The selected files are copied into the base checkout so the report isolates
|
||||
source changes instead of changes to the fixture text.
|
||||
|
||||
Expected output is a Markdown table:
|
||||
|
||||
```md
|
||||
| File Name | Current Size | Previous Size | Difference |
|
||||
| :------------------------- | :----------: | :-----------: | :---------------: |
|
||||
| `scratchpad/my-fixture.ts` | 42.10 KB | 40.80 KB | +1.30 KB (+3.19%) |
|
||||
```
|
||||
|
||||
### Internal CLI
|
||||
|
||||
Use the internal CLI directly only when the base checkout is already prepared
|
||||
and built:
|
||||
|
||||
```sh
|
||||
node packages/tools/bundle/src/bin.ts compare-selected \
|
||||
--base-dir tmp/bundle-base \
|
||||
scratchpad/my-fixture.ts
|
||||
```
|
||||
|
||||
The `--base-dir` value must be the root of the base checkout, not the base
|
||||
fixture directory.
|
||||
|
||||
### Current Size Only
|
||||
|
||||
If the user only asks for the current bundled size, use:
|
||||
|
||||
```sh
|
||||
pnpm --dir packages/tools/bundle report ../../../scratchpad/my-fixture.ts
|
||||
```
|
||||
|
||||
This does not compare against a base ref.
|
||||
|
||||
### Fixture Guidance
|
||||
|
||||
Keep temporary fixtures in `scratchpad/`.
|
||||
|
||||
Good temporary fixtures are small, focused entrypoints that import public
|
||||
package APIs:
|
||||
|
||||
```ts
|
||||
import * as Effect from "effect/Effect"
|
||||
import * as Schema from "effect/Schema"
|
||||
|
||||
const schema = Schema.Struct({
|
||||
name: Schema.String
|
||||
})
|
||||
|
||||
Schema.decodeUnknownEffect(schema)({ name: "effect" }).pipe(Effect.runFork)
|
||||
```
|
||||
|
||||
Prefer self-contained fixtures. The compare-selected workflow copies only the
|
||||
explicit entry files into the base checkout. If a fixture imports local relative
|
||||
helpers, either avoid that shape or make the entry fixture self-contained before
|
||||
measuring.
|
||||
|
||||
Do not add temporary fixtures to `packages/tools/bundle/fixtures/`. That
|
||||
directory is for stable comparison fixtures used by the regular bundle-size
|
||||
workflow.
|
||||
|
||||
### Cleanup
|
||||
|
||||
The wrapper cleans up `tmp/bundle-base` by default. If `--keep-base` was used for
|
||||
a multi-run investigation, remove the worktree when the user is done.
|
||||
|
||||
To remove it:
|
||||
|
||||
```sh
|
||||
git worktree remove --force tmp/bundle-base
|
||||
```
|
||||
|
||||
To verify that cleanup succeeded:
|
||||
|
||||
```sh
|
||||
git worktree list
|
||||
```
|
||||
|
||||
Only the main repository worktree should remain.
|
||||
Reference in New Issue
Block a user