Skip to content

fix(example): mount monaco directly instead of react-monaco-editor, cover example in CI - #3

Merged
murrayju merged 1 commit into
mainfrom
murrayju/fix-example-monaco-editor
Aug 4, 2026
Merged

fix(example): mount monaco directly instead of react-monaco-editor, cover example in CI#3
murrayju merged 1 commit into
mainfrom
murrayju/fix-example-monaco-editor

Conversation

@murrayju

@murrayju murrayju commented Aug 4, 2026

Copy link
Copy Markdown
Member

Problem

yarn build in ./example fails, which breaks the GitHub Pages deploy at the end of the publish workflow:

Module not found: Error: Can't resolve 'monaco-editor/esm/vs/editor/editor.api'
  in '.../node_modules/react-monaco-editor/lib'

react-monaco-editor does import * as monaco from "monaco-editor/esm/vs/editor/editor.api", but monaco-editor 0.56 added an exports map:

"./*": "./esm/vs/*.js"

That rewrites the old specifier to ./esm/vs/esm/vs/editor/editor.api.js, which the package doesn't ship. This is upstream fallout from the monaco 0.56 upgrade in 1d50b6areact-monaco-editor's latest release (0.59.0) still peer-depends on monaco-editor@^0.52.0 and hasn't adapted, so there's no version to upgrade to.

Changes

Drop react-monaco-editor and mount the editor directly with monaco.editor.create, importing via the supported monaco-editor/editor/editor.api specifier.

  • Language switching now uses monaco.editor.setModelLanguage on the existing model, so the editor's contents survive a dialect change (previously the wrapper remounted with reset state).
  • Language registration is guarded to run once, since it mutates global monaco state.
  • MonacoEnvironment.getWorker is set in index.js; without it monaco tries to load its editor worker from a CDN-style absolute path that doesn't exist here. webpack 5 bundles the worker from the new URL(..., import.meta.url) form.
  • The language dropdown is populated from the definition list at module scope rather than being filled in as a side effect of the mount callback.
  • Removed example/src/App.css — unreferenced CRA boilerplate (spinning-logo styles).

Add an example job to CI. The example consumes the package through file:../, so it's the only check that exercises the built entry points and the monaco-editor peer dependency the way a real consumer does. The publish workflow builds it to deploy Pages, so without this job a break is only discovered mid-release — which is exactly what happened here. react-scripts runs eslint as part of a production build, so the job covers lint and compilation.

Verification

  • yarn lint, yarn test (228 passed), and yarn build pass at the root; yarn install --frozen-lockfile + yarn build pass in ./example, all from a clean clone of this branch.
  • Served the production build and loaded it in Chrome: editor renders, no console errors.
  • Confirmed tokenization works for all six dialects by reading the rendered token classes after switching each one — including pgsql, which lazy-loads from monaco's own language definitions.
  • Confirmed editing works by typing WHERE created_at > now() via real keyboard events and checking the resulting tokens.
  • Confirmed the web worker actually loads and executes at runtime (not merely that an asset was emitted) by invoking MonacoEnvironment.getWorker and watching for error/messageerror plus the extra chunk fetch.
  • yarn start compiles successfully.
  • Sanity-checked that the new CI job catches this regression class: reverting just the import specifier back to the old path makes the example job fail with the original error.

Note

The 117 Dependabot alerts on this repo are pre-existing (mostly react-scripts 5.0.1's transitive dev deps) and out of scope here.

react-monaco-editor imports `monaco-editor/esm/vs/editor/editor.api`, but
monaco-editor 0.56 added an `exports` map ("./*": "./esm/vs/*.js") that
rewrites that specifier to ./esm/vs/esm/vs/editor/editor.api.js, which the
package does not ship. This broke `yarn build` in ./example, failing the
publish workflow's GitHub Pages deploy. Its latest release (0.59.0) still
peer-depends on monaco-editor ^0.52.0 and has not adapted.

Drop the wrapper and create the editor with monaco.editor.create, importing
through the supported `monaco-editor/editor/editor.api` specifier. Switching
dialects now uses setModelLanguage so the editor's contents are preserved
instead of being remounted.

Also add an `example` job to CI. The example consumes the package via
`file:../`, so it is the only check that exercises the built entry points and
the monaco-editor peer dependency as a real consumer would; previously a break
there was only discovered mid-release. react-scripts runs eslint during a
production build, so the job covers lint and compilation.

Remove the unreferenced CRA boilerplate App.css.
@murrayju
murrayju merged commit d4826e6 into main Aug 4, 2026
2 checks passed
@murrayju
murrayju deleted the murrayju/fix-example-monaco-editor branch August 4, 2026 19:23
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.

1 participant