Making Monaco compatible with the integration of Vuejs and electron

I am intrigued by the idea of integrating the Monaco editor into a Vue.js backed Electron project. So far, I have successfully run Microsoft's Electron sample for the Monaco editor.

There are several npm repositories for vue.js and monaco, but none of them seem to fully support Electron straight out of the box. The most promising one appears to be vue-monaco, however, I have encountered difficulties in properly integrating it.

AMD Require?

The code from the Microsoft sample provided for use with Electron is as follows:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Monaco Editor!</title>
    </head>
    <body>
        <h1>Monaco Editor in Electron!</h1>
        <div id="container" style="width:500px;height:300px;border:1px solid #ccc"></div>
    </body;

    ...

The module I am using allows something like this:

<template>
    <monaco-editor :require="amdRequire" />
</template>

...

However, I am struggling to define the correct 'amdRequire' variable in Electron + vue. Overcoming this hurdle seems crucial to me at this point.

The Electron FAQ may offer some insights on this matter: I can not sue jQuery/RequireJS/Meteor/AngularJS in Electron

Sample Code

I have uploaded a sample project on GitHub here, with the component causing the issue located in ./src/renderer/components/Monaco.vue.

Summary

How can I successfully load the Monaco Editor inside a Vue.js component running within Electron?

Any help or guidance you can provide would be greatly appreciated.

Answer №1

My approach is quite similar, except I didn't use the extra vue-monaco component. It took me some time to figure it out, but here's how I solved the problem:

function loadMonacoEditor () {
  const nodeRequire = global.require

  const loaderScript = document.createElement('script')

  loaderScript.onload = () => {
    const amdRequire = global.require
    global.require = nodeRequire

    var path = require('path')

    function uriFromPath (_path) {
      var pathName = path.resolve(_path).replace(/\\/g, '/')

      if (pathName.length > 0 && pathName.charAt(0) !== '/') {
        pathName = '/' + pathName
      }

      return encodeURI('file://' + pathName)
    }

    amdRequire.config({
      baseUrl: uriFromPath(path.join(__dirname, '../../../node_modules/monaco-editor/min'))
    })

    // workaround monaco-css not understanding the environment
    self.module = undefined

    // workaround monaco-typescript not understanding the environment
    self.process.browser = true

    amdRequire(['vs/editor/editor.main'], function () {
      this.monaco.editor.create(document.getElementById('container'), {
        value: [
          'function x() {',
          '\tconsole.log("Hello world!");',
          '}'
        ].join('\n'),
        language: 'javascript'
      })
    })
  }

  loaderScript.setAttribute('src', '../node_modules/monaco-editor/min/vs/loader.js')
  document.body.appendChild(loaderScript)
}

I basically modified the electron-amd sample code a bit and used the loadMonacoEditor function in the components' created function.

To prevent the issue of

Not allowed to load local resource: file:///C:/.../node_modules/monaco-editor/min/vs/editor/editor.main.css
, you also need to add

webPreferences: {
  webSecurity: false
}

to your BrowserWindow instance.

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

The multi-level navigation bar is not displaying properly

I am currently facing an issue with my Mega menu. It displays two levels of menus perfectly fine, but I need to add a third level as shown in the image below. However, when I try to include the third level, it disrupts the design and causes the Grand Child ...

Sending optional data in Angular routesIn Angular, you can include additional

In my project utilizing angular 5, I have a lengthy routing file: const homeRoutes: Routes = [ { path: 'home', component: HomeComponent, children: [ { path: 'registration', component: RegistrationCompone ...

Border appearing around a table row when it expands

I am working with a table that has multiple rows, and my goal is to make the border of a row extend over other rows when it is expanded. Refer to the image below for a visual representation. I am utilizing Bootstrap 5 and JQuery for this task. I have creat ...

@casl/vue: What is the recommended structure for an ability.js file?

I'm currently working on integrating @casl/vue with Vue 3, and it seems like I'm encountering some issues. Following the provided instructions, I've included the following code in my /main.js: import { abilitiesPlugin } from '@casl/vue ...

Infrastructural setup for multiplayer games using Socket.io

var connectionHandler = function(socket) { var player = null; socket.on('login', function(data) { player = { data: okeyServer.playerJoin(data), socket: socket }; socket.emit('welcome'); }); socket. ...

What is the reason behind watches not triggering when there are changes in history?

<script setup> import InputChat from '../components/InputChat.vue' import Chat from '../components/Chat.vue' import Layout from "@/components/Layout.vue"; import Sidebar from "@/components/Sidebar.vue"; import ...

Single-page website experiencing Bootstrap problem

I've been struggling with creating a card component for array elements in Vue Bootstrap. The goal is to open a modal specific to the clicked element when the header of the card is clicked. However, the issue I'm facing is that clicking on any hea ...

What crucial element am I overlooking in the React Transition Group Component while implementing it for a carousel design?

I'm trying to add a feature to my Carousel where the opacity changes between images. When clicking on the icons, the images should transition smoothly. I've been using React Transition Group, but for some reason, it's not working as expected ...

Unable to access TemplateUrl in ngRoute

I'm currently working with ngRoute in AngularJS. I have created an index.php file with an embedded ng-view div connected to my app.js file, which in turn contains my routeProvider. However, I am facing issues when trying to specify the templateUrl for ...

Is there a simple way to delete an element from a multidimensional array object in React JS?

In my current project using React Js, I'm facing an issue with removing an item that corresponds to the "product_option_value_id". The task at hand is to remove an item from the product_option_value (a child array object) if the given itemId matches t ...

Issue with Javascript variables

In Javascript, I have an array of strings that I need to use for loading images on my page through AJAX. After each image is loaded, there are additional tasks to be performed which include sending a HTTP request to delete the image. Below is the code I c ...

The Electron application starts up with a blank white screen, no issues or errors detected

After bundling my electron application recently, I encountered an issue where all I see is a blank white screen when trying to run it with no error messages. Upon further investigation, I observed that toggling the developer tools and navigating to source ...

Guide to setting up routes in nuxt.js

I am building a blog website with Nuxt.Js on the domain xyz.com. I would like to display different pages based on country code, such as xyz.com/en/home and xyz.com/en/about. Can someone guide me on how to define routes in Nuxt.js for displaying blog conte ...

Add a new div in Javascript and include an HTML icon inside

This Django project includes a JavaScript function that generates a new div to display certain data. for (var i = 0; i < files.length; i++) { var newDiv = document.createElement('div'); newDiv.setAttribute("class" ...

The issue of elements not appearing seems to be related to the passing of parameters to the state

In my AngularJS application, I have a form where users must input an application number. Upon successful entry, the corresponding data should be displayed below. This data can only be accessed through the scope if passed as a parameter to the current state ...

Mastering smooth zoom and scroll effects in JavaScript without any flickering

My web application has a zoom feature that scales some absolutely positioned DIVs while keeping the scroll position intact. However, during the animated zooming, there is a noticeable flickering effect where the boxes seem to jump up and down slightly. I a ...

Adjust the background color of a cell depending on its value - Implementing with VueJs and Vuetify

I am currently extracting data from a JSON file. My goal is to change the cell color to green if the value is "OK" and to red if the value is "KO". Currently, I have implemented a v-simple-table as shown below: <td :class="OK? 'primary' : &apo ...

Can you explain the concept of computed properties in vuejs?

There are a few queries on computed properties such as the ones listed below "Using computed properties in VueJS forms" "Exploring Computed properties within VueJs" "Understanding computed property usage in VueJS" "Implementing computed propert ...

What methods can be employed to execute a intricate substitution utilizing both javascript and jQuery?

Within the source code of my web pages, I have elements that resemble the following: <div id="opt_3" >A)</div> <div id="opt_2" >B)</div> <div id="opt_4" >C)</div> <div id="opt_5" >D)</div> <div id="op ...

Filter the array and determine the number of elements in the filtered array

I am looking to filter the contents of two arrays and then count the elements where "isimplemented: 'Yes'" is true: const array1 = [{ProjectName: "IT", Department: "Software"}] const array2 = [{Name: "IT", isimplemented: "Yes"}] The method I at ...