DEV Community

Discussion on: Monaco Editor + Svelte Kit

Collapse
 
dan1ve profile image
Daniel Veihelmann • Edited

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 ?

onMount(async () => {
        // @ts-ignore
        self.MonacoEnvironment = {
            getWorker: function (workerId: string, label: string) {
                const getWorkerModule = (moduleUrl: string, label: string): Worker => {
                    // @ts-ignore
                    return new Worker(self.MonacoEnvironment.getWorkerUrl(moduleUrl), {
                        name: label,
                        type: 'module'
                    });
                };

                switch (label) {
                    case 'json':
                        return getWorkerModule('/monaco-editor/esm/vs/language/json/json.worker?worker', label);
                    case 'css':
                    case 'scss':
                    case 'less':
                        return getWorkerModule('/monaco-editor/esm/vs/language/css/css.worker?worker', label);
                    case 'html':
                    case 'handlebars':
                    case 'razor':
                        return getWorkerModule('/monaco-editor/esm/vs/language/html/html.worker?worker', label);
                    case 'typescript':
                    case 'javascript':
                        return getWorkerModule(
                            '/monaco-editor/esm/vs/language/typescript/ts.worker?worker',
                            label
                        );
                    default:
                        return getWorkerModule('/monaco-editor/esm/vs/editor/editor.worker?worker', label);
                }
            }
        };

        Monaco = await import('monaco-editor');
    });
Enter fullscreen mode Exit fullscreen mode

In addition, setting let Monaco: typeof monaco; will help TypeScript to figure stuff out ;-)

Collapse
 
enoy profile image
Enis

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?

Collapse
 
dan1ve profile image
Daniel Veihelmann

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)

Thread Thread
 
dan1ve profile image
Daniel Veihelmann • Edited

No blog post yet, but here is the gist:

<script lang="ts">
    import loader from '@monaco-editor/loader';
    import { onDestroy, onMount } from 'svelte';
    import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';

    let editor: Monaco.editor.IStandaloneCodeEditor;
    let monaco: typeof Monaco;
    let editorContainer: HTMLElement;

    onMount(async () => {

        // Remove this line to load the monaco editor from a CDN
        // see https://www.npmjs.com/package/@monaco-editor/loader#config
        loader.config({ paths: { vs: '/node_modules/monaco-editor/min/vs' } });

        monaco = await loader.init();

       // Sample
        const editor = monaco.editor.create(editorContainer);
        const model = monaco.editor.createModel(
            "console.log('Hello from Monaco! (the editor, not the city...)')",
            undefined,
            // Give monaco a hint which syntax highlighting to use
            monaco.Uri.file('sample.js')
        );
        editor.setModel(model);
    });

    onDestroy(() => {
        monaco?.editor.getModels().forEach((model) => model.dispose());
    });
</script>
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
enoy profile image
Enis

Works perfectly for both Firefox and Chrome @dan1ve
Thank you very much! Looking forward to read your blog article!

Thread Thread
 
dan1ve profile image
Daniel Veihelmann • Edited

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.

Thread Thread
 
enoy profile image
Enis • Edited

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.

Thread Thread
 
dan1ve profile image
Daniel Veihelmann

Did you remove the loader.config() line? (You should :)

Thread Thread
 
dan1ve profile image
Daniel Veihelmann

A blog post with a full how-to is here: codelantis.com/blog/sveltekit-mona...