Skip to content

Commit 88e7376

Browse files
authored
Fix JSON syntax highlighting by using vite monaco plugin (#514)
1 parent b931965 commit 88e7376

File tree

4 files changed

+23
-89
lines changed

4 files changed

+23
-89
lines changed

package-lock.json

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@
113113
"stylelint-use-logical-spec": "^5.0.1",
114114
"typescript": "^5.9.3",
115115
"typescript-eslint": "^8.46.2",
116-
"vite": "^7.1.12"
116+
"vite": "^7.1.12",
117+
"vite-plugin-monaco-editor-esm": "^2.0.2"
117118
},
118119
"engines": {
119120
"node": "24"

src/monaco-editor/monaco-loader.ts

Lines changed: 3 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,15 @@
1-
import type * as _monaco from 'monaco-editor';
2-
type Monaco = typeof _monaco;
3-
import { version as monacoVersion } from 'monaco-editor/package.json';
4-
1+
import * as monaco from 'monaco-editor';
52
import schemaStylelintrc from '../schema/stylelintrc.json';
63

4+
type Monaco = typeof monaco;
5+
76
let monacoPromise: Promise<Monaco> | null = null;
87

98
/** Load the Monaco editor object. */
109
export function loadMonaco(): Promise<Monaco> {
1110
return (
1211
monacoPromise ||
1312
(monacoPromise = (async () => {
14-
const rawMonaco: Monaco | { m: Monaco } =
15-
(await loadMonacoFromEsmCdn()) || (await loadModuleFromMonaco('vs/editor/editor.main'));
16-
17-
let monaco: Monaco;
18-
19-
if ('m' in rawMonaco) {
20-
// Support for [email protected]
21-
monaco = rawMonaco.m || rawMonaco;
22-
} else {
23-
monaco = rawMonaco;
24-
}
25-
2613
monaco.languages.css.cssDefaults.setOptions({
2714
validate: false, //Turn off CSS built-in validation.
2815
});
@@ -52,77 +39,6 @@ export function loadMonaco(): Promise<Monaco> {
5239
);
5340
}
5441

55-
async function loadMonacoFromEsmCdn(): Promise<Monaco | null> {
56-
try {
57-
const result = await import(`https://cdn.jsdelivr.net/npm/monaco-editor@${monacoVersion}/+esm`);
58-
59-
const link = document.createElement('link');
60-
61-
link.rel = 'stylesheet';
62-
link.href = `https://cdn.jsdelivr.net/npm/monaco-editor@${monacoVersion}/min/vs/editor/editor.main.css`;
63-
document.head.append(link);
64-
65-
return result as Monaco;
66-
} catch (e: unknown) {
67-
console.warn('Failed to load Monaco editor from ESM CDN.', e);
68-
69-
return null;
70-
}
71-
}
72-
73-
async function loadModuleFromMonaco<T>(moduleName: string): Promise<T> {
74-
await setupMonaco();
75-
76-
return new Promise((resolve) => {
77-
if (typeof window !== 'undefined') {
78-
// @ts-expect-error -- global Monaco's require
79-
window.require([moduleName], (r: T) => {
80-
resolve(r);
81-
});
82-
}
83-
});
84-
}
85-
86-
async function setupMonaco(): Promise<void> {
87-
if (typeof window !== 'undefined') {
88-
const monacoScript =
89-
Array.from(document.head.querySelectorAll('script')).find(
90-
(script) => script.src && script.src.includes('monaco') && script.src.includes('vs/loader'),
91-
) ||
92-
// If the script tag that loads the Monaco editor is not found, insert the script tag.
93-
(await appendMonacoEditorScript());
94-
95-
// @ts-expect-error -- global Monaco's require
96-
window.require.config({ paths: { vs: monacoScript.src.replace(/\/vs\/.*$/u, '/vs') } });
97-
}
98-
}
99-
100-
/** Appends a script tag that loads the Monaco editor. */
101-
async function appendMonacoEditorScript(): Promise<HTMLScriptElement> {
102-
const script = document.createElement('script');
103-
104-
return new Promise((resolve) => {
105-
script.src = `https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.53.0/min/vs/loader.min.js`;
106-
script.onload = () => {
107-
script.onload = null;
108-
109-
watch();
110-
111-
function watch() {
112-
// @ts-expect-error -- global Monaco's require
113-
if (window.require) {
114-
resolve(script);
115-
116-
return;
117-
}
118-
119-
setTimeout(watch, 200);
120-
}
121-
};
122-
document.head.append(script);
123-
});
124-
}
125-
12642
function setupEnhancedLanguages(monaco: Monaco) {
12743
monaco.languages.register({ id: 'astro' });
12844
monaco.languages.registerTokensProviderFactory('astro', {

vite.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { defineConfig } from 'vite';
2+
import monacoEditorPlugin from 'vite-plugin-monaco-editor-esm';
23

34
export default defineConfig(() => ({
45
server: {
@@ -7,4 +8,9 @@ export default defineConfig(() => ({
78
'Cross-Origin-Opener-Policy': 'same-origin',
89
},
910
},
11+
plugins: [
12+
monacoEditorPlugin({
13+
languageWorkers: ['editorWorkerService', 'css', 'html', 'json', 'typescript'],
14+
}),
15+
],
1016
}));

0 commit comments

Comments
 (0)