fix(front): set up Monaco workers for GraphQL playground (#21620)

## Problem

The GraphQL API playground (`/settings/playground/graphql/core`) crashes
with:

```
Uncaught Error: Cannot read properties of undefined (reading 'toUrl')
  at FileAccessImpl.toUri (monaco-editor)
  at WorkerManager.getLanguageServiceWorker (graphqlMode)
  at DiagnosticsAdapter._doValidate (graphqlMode)
```

## Root cause

GraphiQL 5 (adopted in the React 19 migration, #21531) renders its
editors with **Monaco** instead of CodeMirror. Monaco spawns web workers
for GraphQL validation/autocomplete and needs a
`globalThis.MonacoEnvironment.getWorker` factory. None was ever
configured, so Monaco fell back to a main-thread worker whose URL
resolves to `undefined` → the `toUrl` crash.

## Why not the official helper

GraphiQL ships `@graphiql/react/setup-workers/vite`, but its bundled
`?worker` imports are incompatible with our rolldown-based Vite setup:
- **pre-bundled** (in `optimizeDeps`): esbuild's optimizer can't process
`?worker` → the dep 504s and the page fails to load the chunk.
- **excluded** from `optimizeDeps`: rolldown tries to load
`editor.worker.js?worker` as a literal path → `UNLOADABLE_DEPENDENCY`,
crashing the dev server.

## Fix

- Register `MonacoEnvironment.getWorker` in **app source**
(`setupGraphiqlMonacoWorkers.ts`), where Vite's worker plugin handles
`?worker` reliably, and side-effect import it from
`GraphQLPlayground.tsx` before GraphiQL mounts.
- Align `monaco-editor` to `0.52.2` and add `monaco-graphql@1.8.0` as
direct deps so the workers run on the **same deduped Monaco instance**
GraphiQL uses on the main thread (a version mismatch would break the
worker protocol).

## Verification

Ran the playground locally against the dev server:
- Editor renders, syntax highlighting works, operation name parses
(GraphQL language service alive).
- All three worker files (`editor`, `json`, `graphql`) load `200` and
instantiate as module workers.
- Console is free of `toUrl` / `Cannot read` errors and the "must define
MonacoEnvironment.getWorker" warning.
- `oxlint`, `oxfmt`, and `nx typecheck twenty-front` pass.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21620?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
Charles Bochet
2026-06-15 17:51:51 +02:00
committed by GitHub
parent 2de60d7ea1
commit 9dd097e11e
4 changed files with 28 additions and 10 deletions
+2 -1
View File
@@ -186,8 +186,9 @@
"jest": "29.7.0",
"jest-environment-jsdom": "30.0.0-beta.3",
"jest-fetch-mock": "^3.0.3",
"monaco-editor": "^0.51.0",
"monaco-editor": "0.52.2",
"monaco-editor-auto-typings": "^0.4.5",
"monaco-graphql": "1.8.0",
"msw": "^2.12.7",
"msw-storybook-addon": "^2.0.6",
"optionator": "^0.9.1",
@@ -1,3 +1,4 @@
import '@/settings/playground/utils/setupGraphiqlMonacoWorkers';
import {
isPlaygroundApiKeyFresh,
playgroundApiKeyState,
@@ -0,0 +1,22 @@
import { type Environment } from 'monaco-editor';
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker.js?worker';
import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker.js?worker';
import GraphqlWorker from 'monaco-graphql/esm/graphql.worker.js?worker';
// GraphiQL 5's Monaco editors need a worker factory; without it Monaco throws "Cannot read properties of undefined (reading 'toUrl')".
const monacoEnvironment: Environment = {
getWorker: (_workerId, label) => {
switch (label) {
case 'json':
return new JsonWorker();
case 'graphql':
return new GraphqlWorker();
default:
return new EditorWorker();
}
},
};
(
globalThis as unknown as { MonacoEnvironment?: Environment }
).MonacoEnvironment = monacoEnvironment;
+3 -9
View File
@@ -42629,14 +42629,7 @@ __metadata:
languageName: node
linkType: hard
"monaco-editor@npm:^0.51.0":
version: 0.51.0
resolution: "monaco-editor@npm:0.51.0"
checksum: 10c0/7fde310c747e46cd7293e1a0f5e1fa85c389df9a1f8db03b9ccd58fd45356ab021a591b46198d19345566ad54556158f6489e2da4ad428a7a6ca3ea7b504afcb
languageName: node
linkType: hard
"monaco-graphql@npm:^1.8.0":
"monaco-graphql@npm:1.8.0, monaco-graphql@npm:^1.8.0":
version: 1.8.0
resolution: "monaco-graphql@npm:1.8.0"
dependencies:
@@ -53537,8 +53530,9 @@ __metadata:
lodash.uniqby: "npm:^4.7.0"
marked: "npm:^17.0.1"
microdiff: "npm:^1.3.2"
monaco-editor: "npm:^0.51.0"
monaco-editor: "npm:0.52.2"
monaco-editor-auto-typings: "npm:^0.4.5"
monaco-graphql: "npm:1.8.0"
msw: "npm:^2.12.7"
msw-storybook-addon: "npm:^2.0.6"
optionator: "npm:^0.9.1"