BlazorMonaco icon indicating copy to clipboard operation
BlazorMonaco copied to clipboard

Error when running in Electron

Open matengo opened this issue 4 years ago • 10 comments

Can't have it to run in Electron.

To reproduce: Create a new Blazor Server project. Add ElectronNet.Api Add Blazor Monaco and add an MonacoEditor according to instructions.

electronize start

It's working fine when running in IIS with dotnet run, but not when running as Electron with electronize start..

matengo avatar Sep 23 '20 21:09 matengo

Hi @matengo. What's the error message you get? I do not have electron setup on my computer.

serdarciplak avatar Sep 27 '20 13:09 serdarciplak

Hi, this is the error message in the console:

stdout: warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100] Unhandled exception rendering component: monaco is not defined ReferenceError: monaco is not defined at Object.create (http://localhost:8001/_content/BlazorMonaco/jsInterop.js:39:22) at http://localhost:8001/_framework/blazor.server.js:8:31619 at new Promise () at e.beginInvokeJSFromDotNet (http://localhost:8001/_framework/blazor.server.js:8:31587) at http://localhost:8001/_framework/blazor.server.js:1:20052 at Array.forEach () at e.invokeClientMethod (http://localhost:8001/_framework/blazor.server.js:1:20022) at e.processIncomingData (http://localhost:8001/_framework/blazor.server.js:1:18006) at e.connection.onreceive (http://localhost:8001/_framework/blazor.server.js:1:11091) at WebSocket.i.onmessage (http://localhost:8001/_framework/blazor.server.js:1:39007) Microsoft.JSInterop.JSException: monaco is not defined ReferenceError: monaco is not defined at Object.create (http://localhost:8001/_content/BlazorMonaco/jsInterop.js:39:22) at http://localhost:8001/_framework/blazor.server.js:8:31619 at new Promise () at e.beginInvokeJSFromDotNet (http://localhost:8001/_framework/blazor.server.js:8:31587) at http://localhost:8001/_framework/blazor.server.js:1:20052 at Array.forEach () at e.invokeClientMethod (http://localhost:8001/_framework/blazor.server.js:1:20022) at e.processIncomingData (http://localhost:8001/_framework/blazor.server.js:1:18006) at e.connection.onreceive (http://localhost:8001/_framework/blazor.server.js:1:11091) at WebSocket.i.onmessage (http://localhost:8001/_framework/blazor.server.js:1:39007) at Microsoft.JSInterop.JSRuntime.InvokeWithDefaultCancellation[T](String identifier, Object[] args) at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args) at BlazorMonaco.MonacoEditorBase.Create(String id, StandaloneEditorConstructionOptions options) at BlazorMonaco.MonacoEditor.OnAfterRenderAsync(Boolean firstRender) at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle) stdout: fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111] Unhandled exception in circuit 'Xcliwmvj5eC33XUdzLpdPC0pUwvZpAQxoeqLVi4JPrE'. Microsoft.JSInterop.JSException: monaco is not defined ReferenceError: monaco is not defined at Object.create (http://localhost:8001/_content/BlazorMonaco/jsInterop.js:39:22) at http://localhost:8001/_framework/blazor.server.js:8:31619 at new Promise () at e.beginInvokeJSFromDotNet (http://localhost:8001/_framework/blazor.server.js:8:31587) at http://localhost:8001/_framework/blazor.server.js:1:20052 at Array.forEach () at e.invokeClientMethod (http://localhost:8001/_framework/blazor.server.js:1:20022) at e.processIncomingData (http://localhost:8001/_framework/blazor.server.js:1:18006) at e.connection.onreceive (http://localhost:8001/_framework/blazor.server.js:1:11091) at WebSocket.i.onmessage (http://localhost:8001/_framework/blazor.server.js:1:39007) at Microsoft.JSInterop.JSRuntime.InvokeWithDefaultCancellation[T](String identifier, Object[] args) at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args) at BlazorMonaco.MonacoEditorBase.Create(String id, StandaloneEditorConstructionOptions options) at BlazorMonaco.MonacoEditor.OnAfterRenderAsync(Boolean firstRender) at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)

matengo avatar Sep 30 '20 11:09 matengo

I've also run into this, but made a small amount of progress. Think it's basically this issue: https://stackoverflow.com/questions/32621988/electron-jquery-is-not-defined

If you follow the most suggested answer, and wrap the Monaco JS imports you then get to a second error:

Uncaught TypeError: Cannot read property 'addEventListener' of null
    at Object.onFirstListenerAdd (event.ts:19)
    at _event._event (event.ts:501)
    at new t (suggestRangeHighlighter.ts:104)
    at suggestRangeHighlighter.ts:97
    at Function.t._invokeFactory (loader.js:1036)
    at t.complete (loader.js:1046)
    at s._onModuleComplete (loader.js:1663)
    at s._resolve (loader.js:1623)
    at s.defineModule (loader.js:1274)
    at n (loader.js:1713)

EDIT: That was just me being stupid I think, didn't have the scripts in the correct place.

I've got this in my _Host.cshtml

@page "/"
@namespace WealthKernel.Pdfs.TemplateHelper.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = null;
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>WealthKernel.Pdfs.TemplateHelper</title>
    <base href="~/"/>
    <link href="css/site.css" rel="stylesheet"/>
    <link href="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.css" rel="stylesheet" />
</head>
<body>
<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
<script>require.config({ paths: { 'vs': '_content/BlazorMonaco/lib/monaco-editor/min/vs' } });</script>
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
<script>if (window.module) module = window.module;</script>
<script src="_content/BlazorMonaco/jsInterop.js"></script>
<script src="_framework/blazor.server.js"></script>
<app>
    <component type="typeof(App)" render-mode="ServerPrerendered"/>
</app>
</body>
</html>

No errors now, but the editor doesn't start, inspecting the HTML you can see:

<div id="any-id-string" class="monaco-editor-container "></div>

But that's it.

deadwards90 avatar Oct 19 '20 09:10 deadwards90

@dantheman999301 I think you've found the solution, but did not apply it fully. Can you please try adding the module check lines as below to cover all js files? The javascript that processes the monaco-editor-container div and converts it to an actual monaco editor instance is in BlazorMonaco/jsInterop.js file and it's not covered by the module checks in your example.

<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>

<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
<script>require.config({ paths: { 'vs': '_content/BlazorMonaco/lib/monaco-editor/min/vs' } });</script>
<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
<script src="_content/BlazorMonaco/jsInterop.js"></script>
<script src="_framework/blazor.server.js"></script>

<script>if (window.module) module = window.module;</script>

serdarciplak avatar Dec 06 '20 13:12 serdarciplak

@dantheman999301 I think you've found the solution, but did not apply it fully. Can you please try adding the module check lines as below to cover all js files? The javascript that processes the monaco-editor-container div and converts it to an actual monaco editor instance is in BlazorMonaco/jsInterop.js file and it's not covered by the module checks in your example.

<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>

<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
<script>require.config({ paths: { 'vs': '_content/BlazorMonaco/lib/monaco-editor/min/vs' } });</script>
<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
<script src="_content/BlazorMonaco/jsInterop.js"></script>
<script src="_framework/blazor.server.js"></script>

<script>if (window.module) module = window.module;</script>

I have encountered the same issue but sadly this does not fix it. Experiencing the same as @dantheman999301 where it now appears where it should but the actual editor doesn't load.

According to this Stackoverflow answer monaco only loads with its own loader. I guess this is an issue as electron uses its own loader?

EDIT Coming from this announcement by Richard Lander we may have to wait until .NET 6 to ship with Blazor Desktop Apps, thus removing the need for electron. That is unless @serdarciplak you have any ideas on how to work around this?

tub5 avatar Feb 24 '21 16:02 tub5

Are there any updates on getting this to run in Electron.NET? Would be pretty neat, as Blazor Desktop will only have a final release at the end of the year :/ Is there a workaround to get the Monaco loader to load it in maybe? I haven't looked to deep into it yet (maybe somebody got it to work).

WakanaYuki avatar Apr 06 '21 21:04 WakanaYuki

Great news! I seem to have fixed the issue now. The Monaco is loading in a electron window now. Here is my _Host.cshtml


    <script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
    <script>if (window.module) module = window.module;</script>

    <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
    <script>require.config({ paths: { 'vs': '_content/BlazorMonaco/lib/monaco-editor/min/vs' } });</script>
    <script>require(['_content/BlazorMonaco/lib/monaco-editor/vs/editor/editor.main'], function onMonacoLoaded(){console.log(monaco);});</script>
      <script>
        // Monaco uses a custom amd loader that over-rides node's require. 
        // Keep a reference to node's require so we can restore it after executing the amd loader file.
        var nodeRequire = global.require;
      </script>
    <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.nls.js"></script>
    <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
    <script>
        // Save Monaco's amd require and restore Node's require
        var amdRequire = global.require;
        global.require = nodeRequire;
           // ... remainder of example below
      </script>
    <script src="_content/BlazorMonaco/jsInterop.js"></script>
    <script src="_framework/blazor.server.js"></script>

I am not sure, what here is required and which lines are not making any difference, but it works.

Sources: https://github.com/microsoft/monaco-editor/issues/90#issuecomment-259997687 https://stackoverflow.com/a/50051855

WakanaYuki avatar Apr 07 '21 06:04 WakanaYuki

I have a similar issue while I tried to integrate BlazorMonaco with Chromely demos

Unfortunately, the suggested fix didn't work

Great news! I seem to have fixed the issue now. The Monaco is loading in a electron window now. Here is my _Host.cshtml


    <script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
    <script>if (window.module) module = window.module;</script>

    <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
    <script>require.config({ paths: { 'vs': '_content/BlazorMonaco/lib/monaco-editor/min/vs' } });</script>
    <script>require(['_content/BlazorMonaco/lib/monaco-editor/vs/editor/editor.main'], function onMonacoLoaded(){console.log(monaco);});</script>
      <script>
        // Monaco uses a custom amd loader that over-rides node's require. 
        // Keep a reference to node's require so we can restore it after executing the amd loader file.
        var nodeRequire = global.require;
      </script>
    <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.nls.js"></script>
    <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
    <script>
        // Save Monaco's amd require and restore Node's require
        var amdRequire = global.require;
        global.require = nodeRequire;
           // ... remainder of example below
      </script>
    <script src="_content/BlazorMonaco/jsInterop.js"></script>
    <script src="_framework/blazor.server.js"></script>

I am not sure, what here is required and which lines are not making any difference, but it works.

Sources: microsoft/monaco-editor#90 (comment) https://stackoverflow.com/a/50051855

What is strange: When I run app I could see smth like an "edge" of monaco editor изображение

m0rphed avatar Apr 23 '21 02:04 m0rphed

I have a similar issue while I tried to integrate BlazorMonaco with Chromely demos

Unfortunately, the suggested fix didn't work

Great news! I seem to have fixed the issue now. The Monaco is loading in a electron window now. Here is my _Host.cshtml


    <script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
    <script>if (window.module) module = window.module;</script>

    <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
    <script>require.config({ paths: { 'vs': '_content/BlazorMonaco/lib/monaco-editor/min/vs' } });</script>
    <script>require(['_content/BlazorMonaco/lib/monaco-editor/vs/editor/editor.main'], function onMonacoLoaded(){console.log(monaco);});</script>
      <script>
        // Monaco uses a custom amd loader that over-rides node's require. 
        // Keep a reference to node's require so we can restore it after executing the amd loader file.
        var nodeRequire = global.require;
      </script>
    <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.nls.js"></script>
    <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
    <script>
        // Save Monaco's amd require and restore Node's require
        var amdRequire = global.require;
        global.require = nodeRequire;
           // ... remainder of example below
      </script>
    <script src="_content/BlazorMonaco/jsInterop.js"></script>
    <script src="_framework/blazor.server.js"></script>

I am not sure, what here is required and which lines are not making any difference, but it works. Sources: microsoft/monaco-editor#90 (comment) https://stackoverflow.com/a/50051855

What is strange: When I run app I could see smth like an "edge" of monaco editor изображение

Set the height in CSS

.monaco-editor-container {
    height: 600px;
    border: 1px solid gray;
}

tub5 avatar Apr 23 '21 08:04 tub5

I had the same problem using Electron and Blazor Server. I found out a few things.

First I was missing this in <head> in _Host.cshtml <link href="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.css" rel="stylesheet" />

I put the scripts defined in README before _framework/blazor.server.js <component type="typeof(App)" render-mode="ServerPrerendered" /> <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script> <script>require.config({ paths: { 'vs': '_content/BlazorMonaco/lib/monaco-editor/min/vs' } });</script> <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script> <script src="_content/BlazorMonaco/jsInterop.js"></script> <script src="_framework/blazor.server.js"></script>

The next issue was that I did not have <div class="col-xl-10">, I only had the <div class="row"> around the <MonacoEditor/> so I surrounded it with that div. That made it finally show up but it was tiny. So I added the style that was also a suggested solution.

<div class="row"> <div class="col-xl-10"> <style> .monaco-editor-container { height: 600px; border: 1px solid gray; } </style> <MonacoEditor Id="monacoEditor-1" @ref="_editor" ConstructionOptions="EditorConstructionOptions" /> </div> </div>

sigmb avatar May 27 '21 05:05 sigmb

Closing due to inactivity.

serdarciplak avatar Jan 14 '24 21:01 serdarciplak