|
| 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