0

I want to get the monaco editor up and running in Electron. I found the electron examples for monaco but they won't work in my app.

All I get are errors like:

"loader.js:1817 Uncaught Error: Unrecognized require call"

"angular.js:13920 Error: Check dependency list! Synchronous require cannot resolve module 'fs'. This is the first mention of this module! at e.synchronousRequire (loader.js:1063)"

All is working fine if the loader.js of monaco isn't included as a script file.

The error appears in one of my AngularJS services at the beginning of the file when I try to include the "fs" module:

var fs = require("fs");

But as said: without the monaco loader.js file included this is working fine.

Any suggestions how I can fix that? I want to include the monaco editor in my Electron app and in best cases access it in my AngularJS directives and/or services. Would simplify my app compared to the ACE editor.

FDeitelhoff
  • 638
  • 6
  • 18

4 Answers4

0

It look like the Node.js' require function is overwritten by loader.js one. Instead load in html directly, load it as a node module.

var loader = require('loader');
loader.config({
    // ...
});
loader(['an/amd/module'], function(value) {
    // code is loaded here
});

See vscode-loader github page for detail.

SomeBruh
  • 422
  • 2
  • 15
  • I think that's not possible. I'm using AngularJS and some Controllers and Services are instantiated later. I can't load all node.js modules before. As far as I know at this time. Maybe I'm missing something. – FDeitelhoff Aug 26 '16 at 18:18
  • @FDeitelhoff Answer updated. Let me know if it doesn't work – SomeBruh Aug 28 '16 at 10:51
0

Currently I'm using the following way to integrate the Monaco editor with AngularJS in my Electron application:

<script>
    var nodeRequire = global.require;
</script>

<script src="node_modules/monaco-editor/min/vs/loader.js"></script>

<script>

    var amdRequire = global.require;
    global.require = nodeRequire;

</script>

With those lines in my HTML file I'm loading the amdRequire for Monaco and saving/restoring the Node.js require.

Within my AngularJS controller I can load the Monaco editor with the following lines:

amdRequire.config({
    baseUrl: 'node_modules/monaco-editor/min'
});
self.module = undefined;
// workaround monaco-typescript not understanding the environment
self.process.browser = true;
amdRequire(['vs/editor/editor.main'], function() {
...

That's working fine right now.

Nevertheless the integration of Monaco in various projects with different languages is a pain in the ass process. The Monaco team has "confirmed" that and is working on the integration process.

FDeitelhoff
  • 638
  • 6
  • 18
0

I have found that the cleanest way for my use case is to load it in an iframe. That avoids all the conflicts with your current system. You can access the contents with $("#iframe-id").contentWindow.editor.getValue(). (Note, this assumes that in your iframe, you stored the editor reference in a global var called editor)

See this page for how: https://github.com/Microsoft/monaco-editor-samples/tree/master/sample-iframe

user3413723
  • 8,503
  • 4
  • 47
  • 56
0

I am using Monaco with NW.JS and so the Electron requirements to use the editor are similar. This requires me to persist the current context's require function before loading the Monaco loader.js script as this script sets the custom monaco AMD loader to the global require. Just after loading the loader.js I persist the Monaco loader into a separate global variable perhaps meRequire and restore NW.JS global require to that which was firstly persisted.

<script type="text/javascript">
    // persist global require function before monaco loader.js overwrites it
    tempRequire = require;
</script>
<script src="https://microsoft.github.io/monaco-editor/node_modules/monaco-editor/min/vs/loader.js" type="text/javascript"></script>
<script type="text/javascript">
    // persist monaco's custom loader
    meRequire = require;
    // restore global require function
    require = tempRequire;
    // configure monaco's loader
    meRequire.config(
    {
        baseUrl: 'https://microsoft.github.io/monaco-editor/node_modules/monaco-editor/min/'
    } );
</script>

now to create editor instances just use the meRequire

meRequire( [ 'vs/editor/editor.main' ], () =>
{ 
    // create an editor instance
    let editor = monaco.editor.create( document.getElementById('elementId'), {} );
})

I created a knockout binding for creating Monaco-editor instances and put it on GitHub. It doesn't use node or the npm package rather downloads all sources. You can find it at: https://github.com/simpert/MonacoEditorKnockoutBindingHandler.git

Also, the editor's playground is a great source for examples of how to use the editor and the samples on GitHub give examples of NW.JS and Electon use.

SimperT
  • 2,641
  • 2
  • 12
  • 18