Skip to content

Bundle Monaco through the Angular build (ESM) - #5651

Merged
norman-abramovitz merged 2 commits into
cloudfoundry:developfrom
nabramovitz:norm/feat/monaco-esm
Jul 18, 2026
Merged

Bundle Monaco through the Angular build (ESM)#5651
norman-abramovitz merged 2 commits into
cloudfoundry:developfrom
nabramovitz:norm/feat/monaco-esm

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

Closes #5561.

What changes

Monaco previously loaded through its own AMD loader from a wholesale copy of the vs/ distribution in assets: unversioned URLs that can never be served cache-control: immutable (one of the two cache-policy blockers the issue records), a serialized loader → editor.main.js → css sequence, and a peer conflict — @cfstratos/monaco-yaml 2.5.0 pins monaco ^0.20 while the repo ships 0.52, which breaks plain npm install.

  • The editor is now a hashed lazy chunk (673 kB wire, vs 966 kB across three unversioned requests), dynamically imported on first editor use; the copied vs/ asset tree is retired. Initial bundle is unchanged — Monaco stays off the critical path (perf(core): lazy-load monaco, right-size assets; add load diagnostics #5560's lazy-load behavior preserved).
  • Language workers are bundled from relative new Worker(new URL(...)) references via one-line wrapper modules (the builder doesn't resolve bare package specifiers there). Only the languages Stratos actually edits get a worker — json and yaml; every editor surface in the repo is json/yaml/plaintext (verified by census of all app-monaco-editor usages and createModel/setModelLanguage call sites). Other labels fall back to the basic editor worker: syntax highlighting is main-thread and unaffected, workers only add validation/completion.
  • @cfstratos/monaco-yaml → upstream monaco-yaml 5.5.1 (peers monaco-editor >= 0.36, actively maintained). Registered once by the ESM loader; schema registration goes through a configureYaml() helper wrapping the v5 update() handle — same global last-writer semantics as the old yamlDefaults surface. The Helm chart-values editor drops its AMD contribution load and now surfaces schema-registration failures instead of losing them as unhandled rejections.
  • Two toolchain notes baked into the diff: monaco's codicon font needs a .ttf file-loader entry in angular.json, and the dynamic import uses the concrete esm/vs/editor/editor.main.js path because the package publishes only a module field — esbuild accepts the bare specifier but vitest's vite resolver does not (typed by a small local ambient declaration).

Verification

  • Full gate green (lint, all unit tests, production build) on the final tree.
  • Monaco had zero e2e coverage; this adds a runtime smoke that drives the variable-edit dialog on a real app: editor renders from the lazily imported chunk, a keystroke round-trips, and an invalid yaml model produces diagnostics from the monaco-yaml worker. Green through the live harness.
  • Two adversarial self-review passes; the notable catch was the chart-values editor's init path still calling the removed AMD window.require — exactly the k8s surface the CF-side smoke doesn't reach.

Follow-on candidate (noted, not done here): import a tree-shaken feature subset via editor.api instead of full editor.main to shrink the editor chunk further.

Net −231 lines.

Monaco previously loaded through its own AMD loader from a wholesale
copy of the vs/ distribution in assets — unversioned URLs that can
never be served immutable (the cache-policy blocker cloudfoundry#5561 records),
a serialized loader -> editor.main.js -> css load sequence, and a
peer-dependency conflict: @cfstratos/monaco-yaml 2.5.0 pins monaco
^0.20 while the repo ships 0.52, breaking plain npm install.

The editor is now a hashed lazy chunk (673 kB wire vs 966 kB over
three unversioned requests), loaded by dynamic import on first use;
the copied asset tree is gone. Language workers are bundled from
relative new Worker(new URL(...)) references via one-line wrapper
modules (the builder does not resolve bare specifiers there) — only
the languages Stratos edits get one (json, yaml; every editor surface
is json/yaml/plaintext), everything else falls back to the basic
editor worker. The codicon font needs an explicit .ttf loader entry,
and the dynamic import uses the concrete esm file path because the
package publishes only a module field, which vitest's resolver
rejects as a bare specifier (typed by a local ambient declaration).

@cfstratos/monaco-yaml is replaced by upstream monaco-yaml 5.5.1
(peers >=0.36): registered once by the loader, schemas applied
through its update() handle via configureYaml() — same global
last-writer semantics as the old yamlDefaults surface. The chart
values editor drops its AMD contribution load (init now completes
without window.require, which no longer exists) and surfaces schema
registration failures instead of losing them as unhandled rejections.
Stale AMD-era mocks and the completed-migration guide are removed;
follow-on candidate: a tree-shaken feature subset via editor.api
instead of full editor.main.
Monaco had no e2e coverage at all — nothing would have caught a broken
loader path. The smoke drives the variable edit dialog on a real app:
the editor must render from the lazily imported chunk, a typed
keystroke must round-trip, and an invalid yaml model must produce
diagnostics from the monaco-yaml worker (polling that model's own
markers — the global marker event fires for any model and races
unrelated traffic).

@norman-abramovitz norman-abramovitz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@norman-abramovitz
norman-abramovitz merged commit bceaea3 into cloudfoundry:develop Jul 18, 2026
22 checks passed
@nabramovitz
nabramovitz deleted the norm/feat/monaco-esm branch July 18, 2026 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bundle Monaco through the Angular build (ESM) and version its asset URLs

2 participants