Here's the gist:
<script lang="ts">
import type monaco from 'monaco-editor';
import { onMount } from 'svelte';
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
let divEl: HTMLDivElement = null;
let editor: monaco.editor.IStandaloneCodeEditor;
let Monaco;
onMount(async () => {
// @ts-ignore
self.MonacoEnvironment = {
getWorker: function (_moduleId: any, label: string) {
if (label === 'json') {
return new jsonWorker();
}
if (label === 'css' || label === 'scss' || label === 'less') {
return new cssWorker();
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return new htmlWorker();
}
if (label === 'typescript' || label === 'javascript') {
return new tsWorker();
}
return new editorWorker();
}
};
Monaco = await import('monaco-editor');
editor = Monaco.editor.create(divEl, {
value: ['function x() {', '\tconsole.log("Hello world!");', '}'].join('\n'),
language: 'javascript'
});
return () => {
editor.dispose();
};
});
</script>
<div bind:this={divEl} class="h-screen" />
Key points
- Don't do
module.default
as shown on the FAQ - With Vite, you don't need to configure workers with your bundler
Top comments (15)
As it turned out, the code snippet of the original post (and the official documentation) causes subtle bugs Firefox (e.g. the highlighting in monaco's diff editor did not work).
I think this happens because Firefox needs an explicit
type: module
for registering the worker, otherwise an error happens:import declarations may only appear at top level of a module
Here is the version that works in Chrome + Firefox. Maybe you want to update your post accordingly, @lawrencecchen ?
In addition, setting
let Monaco: typeof monaco;
will help TypeScript to figure stuff out ;-)Thanks for pointing that out @dan1ve
I get the following warning in firefox:
self.MonacoEnvironment.getWorkerUrl is not a function
Do you know the solution to this?
In the meantime, I used the monaco-loader library, which does the heavy lifting for us, and works best.
Blog post coming tomorrow (I'll link it here)
No blog post yet, but here is the gist:
Works perfectly for both Firefox and Chrome @dan1ve
Thank you very much! Looking forward to read your blog article!
You're welcome, but please be aware that this still loads the editor from a CDN if I remember correctly. (Meaning the comment is wrong). I've been fighting with this for a while, maybe tomorrow the post is finally ready.
If you are fine with a CDN, the loader library is a good solution.
I'd be fine with a CDN, but I get a 404 after building and deploying my app:
GET - 404 -
https://my-domain.com/node_modules/monaco-editor/min/vs/loader.js
Seems like it doesn't use a CDN.
Did you remove the loader.config() line? (You should :)
A blog post with a full how-to is here: codelantis.com/blog/sveltekit-mona...
I've been struggling with monaco and svelte in electron. What does the ?worker at the end of the import statement do? It's required for me to build the app buit throws and Uncaught TypeError: Relative references must start with either "/", "./", or "../". in the console and doesn't run. Thanks for any additional insight.
Nice, thanks man! I can confirm this works for me :)
This is great, thanks!
I had to add a min-height to the div so it wouldn't have a zero-height:
I just added an answer on StackOverflow which shows how to create a SvelteKit project from scratch around this code.
I wrap my on onMount function with:
if (browser) {
onMount...
}
It usually helps with compile errors.
Is there any way to optimize this further? The compiled bundle is over 2MB.
Does not work for me :(
On
npm run build && npm run preview
I get the error:self is not defined