Building an integrated Monaco editor using Electron and AngularJS

Struggling to integrate the Monaco editor into my Electron app. Despite following electron examples, encountering persistent errors in my application.

The errors I'm facing include:

"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)"

Interestingly, everything works smoothly when excluding the loader.js script file from Monaco.

The issue arises within one of my AngularJS services whenever I attempt to incorporate the "fs" module:

var fs = require("fs");

However, without including the monaco loader.js file, there are no problems.

Seeking advice on resolving this issue. My goal is to seamlessly integrate the Monaco editor into my Electron app and potentially utilize it in AngularJS directives or services to streamline my application as compared to using the ACE editor.

Answer №1

It appears that the Node.js' require function has been replaced by the loader.js. Rather than loading it directly in the HTML, import it as a node module.

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

For more information, visit the vscode-loader GitHub page.

Answer №2

My current method of incorporating the Monaco editor with AngularJS in my Electron application involves:

<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>

By including these lines in my HTML file, I am able to load the amdRequire for Monaco and save/restore the Node.js require.

In my AngularJS controller, I use the following code to load the Monaco editor:

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() {
...

So far, this setup is functioning smoothly.

However, integrating Monaco into projects involving various languages can be quite challenging. The Monaco team acknowledges this issue and is actively working on improving the integration process.

Answer №3

My approach for achieving a seamless integration is to utilize an iframe. This method eliminates any potential conflicts with your existing system. To access the content, you can use

$("#iframe-id").contentWindow.editor.getValue()
. (Please ensure that you have stored the editor reference in a global variable named editor within the iframe)

To learn more about this technique, refer to the following page: https://github.com/Microsoft/monaco-editor-samples/tree/master/sample-iframe

Answer №4

Utilizing Monaco in conjunction with NW.JS shares similar Electron requirements for using the editor. To achieve this, I must save the current context's require function prior to loading the Monaco loader.js script, as this script will establish the custom monaco AMD loader within the global require. Upon loading the loader.js, I store the Monaco loader in a separate global variable, named meRequire, and restore the original NW.JS global require.

<script type="text/javascript">
    // Save the global require function before it gets overwritten by monaco loader.js
    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">
    // Store monaco's custom loader
    meRequire = require;
    // Restore the global require function
    require = tempRequire;
    // Configure monaco's loader
    meRequire.config(
    {
        baseUrl: 'https://microsoft.github.io/monaco-editor/node_modules/monaco-editor/min/'
    } );
</script>

To create editor instances, simply use the meRequire now.

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

I have developed a knockout binding specifically for generating Monaco-editor instances, which is available on GitHub. This solution does not rely on node or npm packages, but rather downloads all necessary sources. You can access it at: https://github.com/simpert/MonacoEditorKnockoutBindingHandler.git

In addition, the editor's playground serves as a valuable resource for exploring examples of utilizing the editor. Furthermore, the samples on GitHub provide demonstrations of NW.JS and Electron application.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Cannot retrieve authorization cookie

Currently, I am in the process of setting up backend authentication using Express, Node, and Supabase for my frontend built with React. //auth.js import { supabase } from "../config/supabaseConfig.js"; export const checkAuthorizationStatus = asy ...

When a button is clicked, retrieve information from a server using Node.js

In my front end code, I have a scenario where upon clicking a button, I need to retrieve specific data from the node server to populate a map on the client side. The map can be viewed at: "http://localhost:8080/" Here's how I'm making the reques ...

When you invoke a function within Angular 1.5 as a fresh component emerges

I have a component where clicking on a button triggers the invocation of another component. model.alert = function () { modalInstance = $uibModal.open({ template: '<abc-xyz return-value="model" on-cancel="Cancel()">& ...

Converting a JS string into HTML markup

I recently developed a basic web application to manage telnet connections with routers using Node.js, Express, and WebSockets. After establishing a connection, the terminal stream is transmitted through a websocket as UTF-8 strings. However, my current is ...

activate the button once valid input has been provided

How can I enable a button based on the amount entered? Let's say there is a minimum of 100 and a maximum of 200. If the user enters an amount below 100, display an error message and keep the button disabled. If the user enters an amount above 200, ...

Generating symbols that combine both images and text seamlessly

I am working with a circle image that I need to resize based on its placement. This image is intended to be a background for a character or two of text. Specifically, whenever the number 1 or 2 appears in a certain element, I want the circle to appear beh ...

What is the best way to eliminate index.html and exclamation mark from a URL when using AngularJs ui-router?

Recently, I've been working on my state configuration in JavaScript Currently, my URL appears as follows: https://i.stack.imgur.com/FEgjx.png I am looking to eliminate 'index.html' and the exclamation mark from my URL, similar to this exa ...

Warning issued by npm during compilation: The template string expression is unexpected as there should be no curly braces in the

Getting an npm warning during compiling (Unexpected template string expression no-template-curly-in-string) import React from 'react'; const Card = ({name, email, id }) => { return ( <div className='tc bg-light-green dib b ...

Tips for organizing components in jQuery Mobile

Displaying a survey creation form: <!-- HTML structure --> <div data-role="page" data-theme="b"> <div data-role="header"> <h1> Create Survey </h1> </div> <div id="main" data ...

Incorporate a new JavaScript animation as the background for an established website, replacing the static background image

Seeking assistance with my portfolio as I delve into the world of Webdesign and learn the basics from templates. How can I integrate this javascript code into the background of my site, replacing the current minecraft image? Every attempt to implement it ...

Is it possible to switch from kilometers to miles on the distance matrix service in Google Maps?

let distanceService = new google.maps.DistanceMatrixService(); distanceService.getDistanceMatrix({ origins: [sourceLocation], destinations: [destinationLocation], travelMode: google.maps.TravelMode.DRIVING, unitSystem: google.maps.UnitSystem.IMPERI ...

Instructions on creating a number increment animation resembling Twitter's post engagement counter

I've been attempting to replicate the animation seen on Twitter's post like counter (the flipping numbers effect that happens when you like a post). Despite my best efforts, I can't seem to make it work. Here is what I have tried: $(fun ...

Utilizing Dynamic IDs within an AngularJS Template

Incorporating a jQuery plugin within an AngularJS directive is the task at hand. The directive is intended to be called like this: <my-dialog data-trigger-id="myTriggerId">My dialog content...</my-dialog> Within the directive template, it app ...

error encountered when working with date arrays in JavaScript

I find myself perplexed by this particular issue. Although the following code snippet appears to function correctly, it exhibits some peculiar behavior. var tmpcurdte = eval(dataSource[i].startDate); tmpcurdte.setDate(tmpcurdte.getDate() + 1); while (tm ...

Transmit intricate data structure to a web API endpoint using AJAX requests

When attempting to send a complex object named vm containing an object 'Budget' and an array 'BudgetDetails' populated with rows from an HTML table to my API controller using AJAX, I encounter the error message "Uncaught RangeError: Max ...

The WebView.HitTestResult method is currently only receiving <img src> elements and not <a href> elements

I am attempting to open a new window in the Android browser using "_blank". I have set up an event listener for this purpose. mWebView.getSettings().setSupportMultipleWindows(true); mWebView.setWebChromeClient(new WebChromeClient() { ...

Customizing error messages in Joi validationorHow to show custom

Hi there, currently I am utilizing "@hapi/joi": "^15.1.1". Unfortunately, at this moment I am unable to upgrade to the most recent Joi version. This represents my validation schema const schema = { name: Joi.string() .all ...

Is there an array containing unique DateTime strings?

I am dealing with an Array<object> containing n objects of a specific type. { name: 'random', startDate: '2017-11-10 09:00', endDate: '2017-11-23 11:00' } My goal is to filter this array before rendering the resu ...

angularslideables retro animation

I'm currently using the AngularSlideables library to toggle a modal within my Ionic project. You can check out a functional example in this fiddle: http://jsfiddle.net/3sVz8/19/ However, I am facing an issue where the initial height is set to 100% i ...

Combining jQuery MixItUp with AngularJS's NgRoute for seamless functionality

Successfully incorporated jQuery MixItUp into my AngularJs application. The content to be displayed with MixItUp is loaded from custom services. After fetching all items, I trigger the instantiation of jQuery MixItUp. I am also utilizing AngularJS NgRout ...