Skip to content

refactor(FR-2874): replace codemirror with monaco in BAICodeEditor#7390

Merged
yomybaby merged 5 commits into
mainfrom
fix/FR-2874-codemirror-lang-jinja
May 12, 2026
Merged

refactor(FR-2874): replace codemirror with monaco in BAICodeEditor#7390
yomybaby merged 5 commits into
mainfrom
fix/FR-2874-codemirror-lang-jinja

Conversation

@yomybaby
Copy link
Copy Markdown
Member

@yomybaby yomybaby commented May 12, 2026

Resolves #7378 (FR-2874)

Summary

Make pnpm dev actually boot on main again, post-FR-2856 (enableGlobalVirtualStore). Two latent issues were exposed by the global virtual store; both are fixed here.

1. codemirror → monaco (drop unused editor stack)

@codemirror/lang-jinja@6.0.0 (pulled transitively via @uiw/codemirror-extensions-langs) imports @codemirror/state / @codemirror/view as phantom deps. Under enableGlobalVirtualStore esbuild/Vite can't resolve them and dev fails:

✘ [ERROR] Could not resolve "@codemirror/state"
✘ [ERROR] Could not resolve "@codemirror/view"

BAICodeEditor was the only consumer of the codemirror stack, and the project already has a Monaco wrapper (loadMonacoEditor + @monaco-editor/react) used by VFolderTextFileEditorModal and ThemeJsonConfigModal. Rewrite BAICodeEditor on top of Monaco and drop the entire @codemirror / @uiw editor surface (-58 packages from the graph).

Also wraps the Monaco editor with a 1px solid token.colorBorder (+ token.borderRadius) so it reads as a bounded field, and pads the loading Skeleton with token.paddingContent{Horizontal,Vertical}.

Removed from react/package.json:

  • @codemirror/lang-jinja
  • @codemirror/lang-liquid
  • @codemirror/language
  • @uiw/codemirror-extensions-langs
  • @uiw/react-codemirror

Removed from pnpm-workspace.yaml overrides:

  • @codemirror/state
  • @codemirror/lang-jinja (had been needed to dodge the phantom imports)

2. `vite-plugin-node-polyfills` Buffer TDZ in dev

With the new dep graph, dev served the app but the browser crashed on load with:

```
chunk-XXXXXX.js Uncaught ReferenceError: Cannot access '__vite__cjsImport0_vitePluginNodePolyfills_shims_buffer' before initialization
```

`Buffer: true` makes the plugin prepend `import __buffer_polyfill from 'vite-plugin-node-polyfills/shims/buffer'; globalThis.Buffer = ... __buffer_polyfill` to every chunk that touches Buffer. Vite's dep optimizer also wraps the shim itself into a CJS-interop chunk — that chunk then ends up importing its own default export, producing the TDZ.

Scope `globals.Buffer` to `'build'`. Prod build behavior is unchanged; dev pre-bundles the polyfill (via `include: ['buffer']`) for explicit `import { Buffer } from 'buffer'` callers. No browser-side code in this repo references the Buffer global — only `src/lib/backend.ai-client-node.ts`, which isn't part of the React bundle.

Test plan

  • `pnpm i && pnpm dev` boots; browser loads without the buffer-polyfill TDZ (verified via Playwright headless run — 3 consecutive loads, 0 page errors).
  • Environment → Container Registry: create/edit a registry, JSON `extra` field uses Monaco; dark/light follows app theme; bordered container.
  • User Settings → Bootstrap / Userdata script: open `ShellScriptEditModal`, edit and save — Monaco loads with `shell` language.
  • Service → Endpoint detail: `BAIJSONViewerModal` renders read-only formatted JSON.
  • `pnpm why @codemirror/lang-jinja` / `@uiw/react-codemirror` resolve to no entries.
  • Production build (`pnpm build`) still bundles a working `Buffer` global (verified manually via `backend.ai-client-node` consumers if applicable).

Copy link
Copy Markdown
Member Author


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • flow:merge-queue - adds this PR to the back of the merge queue
  • flow:hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has required the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions github-actions Bot added the size:XS ~10 LoC label May 12, 2026
@yomybaby yomybaby marked this pull request as ready for review May 12, 2026 10:28
Copilot AI review requested due to automatic review settings May 12, 2026 10:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the workspace-level pnpm dependency resolution to avoid a known phantom-import issue with @codemirror/lang-jinja under enableGlobalVirtualStore, which can break Vite/esbuild resolution in this monorepo.

Changes:

  • Adds a pnpm overrides rule to force @codemirror/lang-jinja to resolve to ^6.0.1 (instead of 6.0.0) to avoid phantom imports.

Comment thread pnpm-workspace.yaml Outdated
Comment thread pnpm-workspace.yaml Outdated
@yomybaby yomybaby force-pushed the fix/FR-2874-codemirror-lang-jinja branch from 1e40223 to 526ef4b Compare May 12, 2026 10:44
@github-actions github-actions Bot added size:XL 500~ LoC and removed size:XS ~10 LoC labels May 12, 2026
@yomybaby yomybaby force-pushed the fix/FR-2874-codemirror-lang-jinja branch from e2a03f1 to 568dbbc Compare May 12, 2026 11:47
yomybaby added 4 commits May 12, 2026 12:34
The phantom-import build failure under enableGlobalVirtualStore (FR-2856) came from a transitively-pulled @codemirror/lang-jinja that isn't even used. Instead of pinning a fixed version, drop the only codemirror consumer (BAICodeEditor) and switch it to the project's existing Monaco wrapper.

Monaco is already used elsewhere (VFolderTextFileEditorModal, ThemeJsonConfigModal), so this consolidates on a single editor stack and removes the entire @codemirror / @uiw editor dependency surface.
…ild only

In dev, vite's dep optimizer wraps `vite-plugin-node-polyfills/shims/buffer` into its own CJS-interop chunk while the plugin also injects `import __buffer_polyfill from '...'; globalThis.Buffer = ... __buffer_polyfill` at the top of every chunk that touches Buffer. The shim chunk ends up importing its own default export, causing a TDZ access on `__vite__cjsImport0_vitePluginNodePolyfills_shims_buffer` that blocks the entire app from booting.

Scoping `globals.Buffer` to `'build'` keeps the prod bundle behavior unchanged while letting dev pre-bundle the polyfill (via `include: ['buffer']`) for explicit `import { Buffer } from 'buffer'` consumers. No browser code in this repo references the Buffer global — only `backend.ai-client-node.ts`, which isn't part of the React bundle.
- Wrap Monaco editor with a 1px `token.colorBorder` border + `token.borderRadius` so the editor reads as a bounded field (matches the visual weight of antd inputs around it).
- Pad the loading Skeleton with `token.paddingContent{Horizontal,Vertical}` so the placeholder doesn't sit flush against the border before the editor mounts.
- Caller `style` still wins via spread, so consumers can override border or padding when needed.
PR #7390 removed '@codemirror/state' from pnpm-workspace.yaml overrides
without refreshing pnpm-lock.yaml, so CI's pnpm install --frozen-lockfile
failed with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH. After rebasing onto main
(picks up FR-2866 which disables gitBranchLockfile), regenerate the root
lockfile to match the current overrides and remove the now-stale
pnpm-lock.fix!fr-2874-codemirror-lang-jinja.yaml branch lockfile.
@yomybaby yomybaby force-pushed the fix/FR-2874-codemirror-lang-jinja branch from 568dbbc to aaa50b3 Compare May 12, 2026 12:37
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

Coverage Report for react-coverage (./react)

Status Category Percentage Covered / Total
🔵 Lines 6.45% 1783 / 27614
🔵 Statements 5.31% 1978 / 37250
🔵 Functions 5.18% 296 / 5709
🔵 Branches 3.71% 1293 / 34798
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
react/src/components/BAICodeEditor.tsx 0% 0% 0% 0% 13-76
react/src/components/BAIJSONViewerModal.tsx 0% 0% 0% 0% 16-60
react/src/components/ContainerRegistryEditorModal.tsx 0% 0% 0% 0% 51-537
Generated in workflow #588 for commit b470bd9 by the Vitest Coverage Report Action

@yomybaby yomybaby changed the title fix(FR-2874): pin @codemirror/lang-jinja to ^6.0.1 to fix phantom imports refactor(FR-2874): replace codemirror with monaco in BAICodeEditor May 12, 2026
Expand the inline comment to document the two pieces of context that aren't obvious from the code: (a) why `Buffer: true` deadlocks dev (vite optimizer self-import TDZ on the polyfill shim chunk), and (b) why scoping to 'build' is safe specifically in this repo — no app code references Buffer; the only surviving `Buffer.byteLength` call is in a Node-only branch of cross-fetch (pulled transitively by i18next-http-backend) that never executes in the browser. Notes that the polyfill itself is a candidate for full removal in a follow-up.
@yomybaby yomybaby merged commit 9d9ff41 into main May 12, 2026
12 checks passed
@yomybaby yomybaby deleted the fix/FR-2874-codemirror-lang-jinja branch May 12, 2026 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500~ LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace codemirror with monaco in BAICodeEditor

2 participants