build: drop sourcemaps from the localstudio bundle, strip them from deploys - #1624
Conversation
…eploys Sourcemaps were 76% of the build output — 71 MB of the 94 MB that `build:local` produced — because each one embeds `sourcesContent`, the full original text of every module it covers. `build.sourcemap` was an unconditional `true`, so every mode paid for them whether or not anything read them. Replace it with `sourcemapFor(mode)`: - `localstudio` → `false`. This is the UI bundled into the Harper distribution; the harper repo builds it via `build:local` and packages `web/` as-is, and nothing on that path uploads or reads maps. Omitting them here keeps the fix on this side of the repo boundary, so harper's build scripts need no change. 94 MB → 23 MB. - `dev`/`stage`/`prod` → `'hidden'`. The deploy workflows now delete the maps after the Datadog upload and before `mv web deploy/`, so ~71 MB is no longer replicated to every node for a consumer that keeps its own copy. `'hidden'` omits the `//# sourceMappingURL=` comment that would otherwise dangle onto a 404 once the files are gone; `datadog-ci sourcemaps upload` pairs maps to bundles by filename and never needs it (verified by dry-run: 173/173 paired). - bare `vite build` → `true`, unchanged, so a developer inspecting a production build locally still gets linked maps. Deployed payload goes 95 MB → 23 MB with all bundles, css and html intact. This is size containment, not source protection — the repo is public. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces dynamic sourcemap configuration based on the build mode in vite.config.ts and documents this design in AGENTS.md. Sourcemaps are disabled for localstudio to optimize bundle size, set to 'hidden' for deploy modes (dev, stage, prod) to facilitate Datadog uploads while avoiding dangling source map comments, and enabled for local production builds. I have no feedback to provide.
Coverage Report
File CoverageNo changed files found. |
| */ | ||
| function sourcemapFor(mode: string): boolean | 'hidden' { | ||
| if (mode === 'localstudio') { return false; } | ||
| if (DEPLOY_MODES.has(mode)) { return 'hidden'; } |
There was a problem hiding this comment.
All stage builds now emit hidden sourcemaps, but both stage workflows first run a verification build whose output is never uploaded: merge-queue runs stop after that build, while push/restart runs immediately rebuild and replace it. That leaves roughly 71 MB of unused map generation per verification build, contrary to the stated consume-only policy. Could the verification build disable maps (for example through a config-only environment switch), or could the redundant first build be skipped when the release build will run? — KrAIs (GPT-5)
Why
npm run build:localemitted 94 MB of assets. 76% of that — 71 MB — was sourcemaps, because each one embedssourcesContent, the full original text of every module it covers.build.sourcemapwas an unconditionaltrue, so every build mode paid for maps whether or not anything read them.This is size containment, not source protection — the repo is public.
build:local→ bundled into the Harper distributionweb/, replicated to every nodeWhat changed
build.sourcemapbecomessourcemapFor(mode), because the three kinds of build want three different things:pnpm build:local(localstudio)falsepnpm build --mode dev|stage|prod'hidden'pnpm buildtruelocalstudiogets no maps at all. This is the UI bundled into the Harper distribution: the harper repo drives the build from its own scripts (roughlyVITE_STUDIO_VERSION="v$(jq -r '.version' ../package.json)" pnpm run build:local) and packages the resultingweb/as-is. Nothing on that path uploads maps to Datadog or reads them, so they only inflated the published Harper package. Configuring the omission here rather than post-processing in harper means harper's build scripts need no change.Deploy modes get
'hidden', and the sixdeploy-*.yamlworkflows now delete the maps after the Datadog upload and beforemv web deploy/. Datadog keeps its own copy and is their only consumer, so replicating ~71 MB to every node bought nothing.'hidden'rather thantrueis load-bearing: it omits the trailing//# sourceMappingURL=comment that would otherwise dangle onto a 404 once the files are gone.Verification
build:local: 94M → 23M, 0 maps, no danglingsourceMappingURL. (The one grep hit ints.workeris asourceMappingURL=${r}template literal inside the bundled TypeScript compiler, not a build reference.)--mode prod: 173 maps written for the upload, and confirmed nosourceMappingURLcomment in the bundles. Simulating the strip step takes it 95M → 23M with all 191 js / 7 css / 2 html intact.datadog-ci sourcemaps upload --dry-runhandled 173/173 sourcemaps, pairing each.js.mapto its bundle by filename.vite buildstill emits linked maps.dprint,oxlint,tsc -bclean; 291 test files / 2255 tests pass.No behavioral change to the app — the shipped JS/CSS is byte-identical, only the maps alongside it differ.
Notes for reviewers
src/lib/monaco/setup.ts(8 languages, not all ~90),editor.apistays lazy, and the eager critical path is 1.93 MB uncompressed across 25 files. The 13.7 MB of Monaco JS is dominated byts.worker(6.6 MB — the TypeScript compiler) and is genuinely load-on-demand. No change made there.AGENTS.mdgains a Builds section recording the per-mode policy and how Studio ships inside Harper, solocalstudiomaps don't get switched back on — that would silently add ~71 MB to the Harper package with no consumer and no failing test to catch it.web/; this takes effect going forward rather than retroactively.🤖 Generated with Claude Code