Search code examples
javascriptgoogle-chrome-extensionrequirejsmonaco-editor

Monaco editor in content script. "Define is not defined", "synchronous require cannot resolve module 'vs/editor/editor.api'."


I'm trying to make it work in content script:

manifest.json

"content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": [
        "monaco-editor/min/vs/loader.js",
        "content.js",
        "monaco-editor/min/vs/editor/editor.main.nls.js",
        "monaco-editor/min/vs/editor/editor.main.js",
        "editor.js"
      ],
    }
]

content.js

let root_path = chrome.runtime.getURL("")
require.config({
    paths: { vs: root_path + 'monaco-editor/min/vs' }
})

editor.js

require(['vs/editor/editor.main'], function () {
    init_monaco_editor(...)
})

Everything is okay, yet it doesn't support any language. Here's the error:

Uncaught ReferenceError: define is not defined
    at markdown.js:7:1

I tried to add every language handler manually like this:

"content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": [
        "monaco-editor/min/vs/loader.js",
        "content.js",
        "monaco-editor/min/vs/editor/editor.main.nls.js",
        "monaco-editor/min/vs/editor/editor.main.js",
        ...
        "monaco-editor/min/vs/basic-languages/lua/lua.js",
        "monaco-editor/min/vs/basic-languages/m3/m3.js",
        "monaco-editor/min/vs/basic-languages/markdown/markdown.js",
        "monaco-editor/min/vs/basic-languages/mips/mips.js",
        "monaco-editor/min/vs/basic-languages/msdax/msdax.js",
        "monaco-editor/min/vs/basic-languages/mysql/mysql.js",
        "monaco-editor/min/vs/basic-languages/objective-c/objective-c.js",
        ...
        "editor.js"
      ],
    }
]

Most of the languages started to work, but some of them (javascript, html, python) now produce an error of another kind:

Uncaught Error: Check dependency list! Synchronous require cannot resolve module 'vs/editor/editor.api'. This module has not been resolved completely yet.
    at u.synchronousRequire (loader.js:1477:23)
    at u._relativeRequire (loader.js:1460:29)
    at r (loader.js:1636:30)
    at python.js:8:999
    at python.js:8:516
    at python.js:8:1097
    at python.js:8:4195
    at u._invokeFactory (loader.js:1188:41)
    at u.complete (loader.js:1198:36)
    at u._onModuleComplete (loader.js:1828:20)

Uncaught Error: Check dependency list! Synchronous require cannot resolve module 'vs/editor/editor.api'. This module has not been resolved completely yet.
    at u.synchronousRequire (loader.js:1477:23)
    at u._relativeRequire (loader.js:1460:29)
    at r (loader.js:1636:30)
    at javascript.js:8:999
    at javascript.js:8:516
    at javascript.js:8:1097
    at javascript.js:8:6651
    at u._invokeFactory (loader.js:1188:41)
    at u.complete (loader.js:1198:36)
    at u._onModuleComplete (loader.js:1828:20)

I don't know how to fix it. Any ideas?


Solution

  • I just injected editor.main and the language files separately and it started to work:

    content.js

    let root_path = chrome.runtime.getURL("")
    require.config({
        paths: { vs: root_path + 'monaco-editor/min/vs' }
    })
    
    // (communicate with the background script to call `some_func`.)
    

    background.js

    async function some_func(tab) {
        await injectFiles(tab.id, [
            'monaco-editor/min/vs/editor/editor.main.nls.js',
            'monaco-editor/min/vs/editor/editor.main.js'])
    
        await injectFiles(tab.id, monaco_language_files) // everything from basic-languages folder
    }
    
    function injectFiles(id, files) {
        return chrome.scripting.executeScript(
            {
                target: { tabId: id },
                files: files,
                world: "ISOLATED"
            })
    }
    

    That's it, require(['vs/editor/editor.main']) is not needed anymore.