Skip to content

Commit d34044f

Browse files
mshanemcclaude
andauthored
perf(apex-oas): shrink bundle via esbuild ESM resolution of effect - W-23313204 (#7707)
* chore: plan for W-23313204 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * perf(apex-oas): resolve effect ESM to shrink bundle - W-23313204 * fix: apply medium/low review findings for apex-oas bundle - add dist/*-metafile.json to .vscodeignore (exclude 1MB debug metafile from VSIX) - add ../../scripts/bundling/effect.mjs to wireit vscode:bundle files (cache invalidation) - trim repeated caveats and multi-sentence bullets in plan doc Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent 01230c4 commit d34044f

4 files changed

Lines changed: 62 additions & 2 deletions

File tree

packages/salesforcedx-vscode-apex-oas/.vscodeignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*.xml
99
*.vsix
1010
out/**
11+
dist/*-metafile.json
1112
test/**
1213
src/**
1314
**/*.map

packages/salesforcedx-vscode-apex-oas/esbuild.config.mjs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@
55
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
77
import { nodeConfig } from '../../scripts/bundling/node.mjs';
8+
import { effectEsmConditions } from '../../scripts/bundling/effect.mjs';
89
import { build } from 'esbuild';
10+
import { writeFile } from 'fs/promises';
911

10-
await build({
12+
const nodeBuild = await build({
1113
...nodeConfig,
14+
...effectEsmConditions,
1215
external: ['vscode', 'applicationinsights', 'jsonpath', 'jsonc-parser'],
1316
keepNames: false,
1417
entryPoints: ['./src/index.ts'],
15-
outdir: 'dist'
18+
outdir: 'dist',
19+
metafile: true
1620
});
21+
22+
await writeFile('dist/node-metafile.json', JSON.stringify(nodeBuild.metafile, null, 2));

packages/salesforcedx-vscode-apex-oas/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
"files": [
109109
"esbuild.config.mjs",
110110
"../../scripts/bundling/node.mjs",
111+
"../../scripts/bundling/effect.mjs",
111112
"out/**"
112113
],
113114
"output": [

plans/W-23313204.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# W-23313204 [ai-auto] Shrink apex-oas bundle via esbuild ESM resolution of effect
2+
3+
## Context
4+
5+
- Goal: apply the node-build-only effect ESM conditions override (shared `effectEsmConditions`, ADR 0021, first landed via W-23293744 PR #7675 / W-23313202) to `salesforcedx-vscode-apex-oas`. Desktop bundle only — no web build exists.
6+
- Mechanism: effect `package.json` `exports` map (`import`→esm, `default`→cjs) + `sideEffects:[]`. CJS resolution (current) pulls full fast-check via `dist/cjs/Schema.js` unconditional `require("./FastCheck.js")`. `conditions:['import','module','default']` → esbuild resolves `dist/esm/*` → most fast-check tree-shakes out. Output stays CJS (from `nodeConfig.format`).
7+
- fast-check pull path in apex-oas is **transitive**: apex-oas `src/` imports effect submodules (`Data`, `Effect`, `Chunk`, `Layer`, `ManagedRuntime`, `Option`, `Predicate`, `Runtime`, `Schedule`, `Stream`, `Duration`, `Function`) — none is `Schema` directly. But dep `@salesforce/effect-ext-utils` (`allServicesLayer.ts`, `extensionPackageJson.ts`) `import * as Schema from 'effect/Schema'` → Schema → FastCheck. That transitive Schema is what the override tree-shakes.
8+
- `scripts/bundling/effect.mjs` (`effectEsmConditions`) and `docs/adr/0021-effect-esm-condition-override-scope.md` ALREADY exist in this branch (landed by sibling W-23313202). This WI is the 3rd opt-in package — no new ADR, no new shared constant. Just consume the existing constant + honest measurement.
9+
- Current `packages/salesforcedx-vscode-apex-oas/esbuild.config.mjs`: single `build()`, `entryPoints:['./src/index.ts']` (TS source, not `out/`), `outdir:'dist'`, `external:['vscode','applicationinsights','jsonpath','jsonc-parser']`, `keepNames:false`, NO metafile.
10+
- tsconfig extends common (CJS). Node platform. Output `dist/index.js` (+ `.map`) per wireit.
11+
12+
### Measured reality — this is NOT a W-23293744-parity shrink (addresses plan-adversary findings)
13+
14+
- MEASURED baseline in this worktree: `dist/index.js` = 5,646,740B → 4,836,391B WITH `effectEsmConditions` = **14.4% total reduction** — far below the sibling PRs' ~50-80% total-bundle figures. Do NOT set W-23293744/W-23313202 total-shrink numbers as the bar for apex-oas.
15+
- The fast-check mechanism itself DOES hold: fast-check `bytesInOutput` 219,568B → 44,562B (79.7%), consistent with org-browser/apex-debugger. The modest TOTAL reduction is because apex-oas is dominated by 7 additional direct deps, not effect.
16+
- **Blast radius (ADR 0021 warns: `conditions` changes module resolution for EVERY dependency, not just effect).** 8 non-effect direct deps re-point: `yaml`, `jsonpath-plus`, `fast-xml-parser`, `vscode-uri`, `ejs`, `@stoplight/spectral-core`, `@stoplight/spectral-functions`, `@stoplight/spectral-rulesets`. Isolated 5-dep smoke: with-conditions 534,101B vs without 453,695B — 18% INCREASE for those deps (some ESM builds larger). Net win: fast-check drop > dep growth. Verify per-dep resolution before claiming shrink.
17+
- Done-criteria: (a) build succeeds, (b) all 8 non-effect deps resolve to working entries (no `require-resolve-not-external` / broken ESM entry / runtime import failure), (c) NET `dist/index.js` smaller, delta as a NUMBER, (d) fast-check `bytesInOutput` drops ~80%. (See Measured-reality caveat above — not the sibling PRs' ~80% total bar.)
18+
19+
## Phases
20+
21+
### Phase 1 — Apply override + measure per-dep resolution (one commit)
22+
23+
- Edit `packages/salesforcedx-vscode-apex-oas/esbuild.config.mjs`:
24+
- `import { effectEsmConditions } from '../../scripts/bundling/effect.mjs'`.
25+
- `import { writeFile } from 'fs/promises'`.
26+
- spread `...effectEsmConditions` after `...nodeConfig` (keep existing `external`, `keepNames:false`, `entryPoints`, `outdir`).
27+
- `metafile: true`; capture the build result; `await writeFile('dist/node-metafile.json', JSON.stringify(nodeBuild.metafile, null, 2))` (matches org-browser/apex-debugger pattern — numbers needed for PR).
28+
- Measure: build WITHOUT override (git-stash or temp revert) → baseline `dist/index.js` bytes + fast-check `bytesInOutput` + per-dep resolved paths (cjs vs esm) for the 8 non-effect deps from the metafile `inputs` keys. Then WITH override → after. Only committed state = override applied.
29+
- **Per-dep blast-radius check (required before claiming shrink):** from both metafiles, diff the resolved input path for each of `yaml`, `jsonpath-plus`, `fast-xml-parser`, `vscode-uri`, `ejs`, `@stoplight/spectral-core`, `@stoplight/spectral-functions`, `@stoplight/spectral-rulesets`. Record which ones re-resolved (cjs→esm) and their `bytesInOutput` delta. Confirm none errored and none silently dropped exports the bundle needs. Note any that grew (expected for some ESM builds) so the net number is explained, not surprising.
30+
- Rebuild via wireit `vscode:bundle` task (or `node ./esbuild.config.mjs`; entry is `./src/index.ts` TS source — no `out/**` compile needed for the entry, but run `npm run compile -w salesforcedx-vscode-apex-oas` first if bundle-time deps require it).
31+
- Done-when: build succeeds; effect resolves `dist/esm/*` (was `dist/cjs/*`); fast-check `bytesInOutput` drops ~80% (record number, NOT absent); all 8 non-effect deps resolve to working entries; NET `dist/index.js` smaller with the ~14% delta recorded as a number. Numbers feed the PR body.
32+
- Commit msg: `perf(apex-oas): resolve effect ESM to shrink bundle - W-23313204`
33+
34+
## Skills to apply
35+
36+
- work-item-sequencing — ADR already landed (W-23313202); this WI adds no ADR, sequences after it
37+
- verification — build + size-diff evidence + per-dep resolution diff + runtime activation smoke (see Verification)
38+
- effect-best-practices — confirm effect resolution assumptions; confirm transitive Schema (via effect-ext-utils) is the fast-check pull
39+
- typescript — esbuild config edit conventions
40+
- concise — plan + PR body
41+
- pr-draft — PR body w/ before/after node bytes + % (see Measured-reality caveat), fast-check delta, per-dep resolution table, Playwright-inactive disclosure
42+
- wireit — bundle task deps/outputs
43+
- packageJson — none expected (build script only)
44+
45+
## Verification
46+
47+
- **Build + metafile:** build succeeds; `dist/node-metafile.json` written; metafile shows effect resolves `dist/esm/*` (was `dist/cjs/*`); fast-check `bytesInOutput` reduced ~80% (record number, not absent); NET `dist/index.js` bytes before vs after + % recorded (~14%, feeds PR body); no `import.meta`/top-level ESM syntax in CJS output (grep `module.exports` present / no ESM export at top level); no `require-resolve-not-external` / `unsupported-dynamic-import` errors.
48+
- **Per-dep blast-radius (required):** for each of the 8 non-effect direct deps, record resolved entry (cjs vs esm) and `bytesInOutput` delta from the before/after metafiles; confirm none errored, none dropped needed exports, and the net number is explained (fast-check drop outweighs any dep growth). Do NOT claim a shrink until this table is filled.
49+
- **Runtime coverage — Playwright suite is INACTIVE, do NOT claim it as e2e:** the apex-oas desktop Playwright suite is unconditionally skipped. `test/playwright/fixtures/desktopFixtures.ts:47-49` calls `oasDesktopTest.skip(true, 'A4V v4 removed the einstein-gpt isEnabled context key and LLMService — OAS commands unavailable')` in a `beforeEach`; all 9 specs under `test/playwright/specs/` re-export that fixture, so `npm run test:desktop -w salesforcedx-vscode-apex-oas` reports every test SKIPPED and never loads the bundled `dist/index.js`. It therefore provides ZERO coverage for this runtime module-resolution change and must NOT be asserted as e2e coverage in the plan or PR. Unskipping the suite (the A4V v4 LLMService regression) is out of scope for a bundling WI.
50+
- Evidence step (optional, cheap): run `npm run test:desktop -w salesforcedx-vscode-apex-oas -- test/playwright/specs/decomposedSimpleAccount.headless.spec.ts` and observe it reports skipped — documents in the PR that the suite is inactive rather than green.
51+
- **Runtime coverage — manual activation smoke (required before PR):** module resolution changed for effect AND 8 other deps, so build-size + metafile inspection insufficient. Load bundled `dist/index.js` in desktop VS Code (install VSIX or launch extension host); confirm: activates without error; `effect/Effect` + `effect/Data` path runs (e.g. OAS generation flow / command constructing effect `ManagedRuntime`); re-resolved spectral/yaml/fast-xml-parser deps still function (e.g. validation path using spectral + yaml). Record what was exercised.
52+
- **PR body disclosure (matches sibling W-23313202):** state Playwright suite currently inactive (globally skipped, A4V v4); runtime confidence rests on (1) org-browser Playwright validation of identical effect-ESM mechanism (PR #7675), (2) per-dep resolution diff showing no regressions, (3) manual activation smoke performed here. Report shrink as NUMBER (see Measured-reality caveat).

0 commit comments

Comments
 (0)