serdarciplak / BlazorMonaco

Blazor component for Microsoft's Monaco Editor which powers Visual Studio Code.
https://serdarciplak.github.io/BlazorMonaco/
MIT License
441 stars 99 forks source link

Error using Monaco Editor together with Blazorise #81

Open yuramag opened 1 year ago

yuramag commented 1 year ago

When adding Monaco Editor to a project that already contains Blazorise I get the following exception in the browser console:

Microsoft.JSInterop.JSException: Can only have one anonymous define call per script file
Error: Can only have one anonymous define call per script file

Here is a basic project to reproduce the issue: https://github.com/yuramag/BlazoriseWithMonaco

Seems like there is some sort of conflict between the JS code backing Tooltip component and BlazorMonaco internals. Any suggestion on how to address this problem?

beliy26 commented 1 year ago

Similar problem with Blazorise.Bootstrap 1.2.1 and BlazorMonaco 3.0.0

Error: Microsoft.JSInterop.JSException: Can only have one anonymous define call per script file Error: Can only have one anonymous define call per script file at s.enqueueDefineAnonymousModule (https://localhost:59356/_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js:8:5413) at g (https://localhost:***/_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js:9:1857) at https://localhost:***/_content/Blazorise/vendors/sha512.js?v=1.2.1.0:9:17673 at https://localhost:***/_content/Blazorise/vendors/sha512.js?v=1.2.1.0:9:17703 at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args) at Blazorise.Modules.BaseJSModule.InvokeSafeVoidAsync(String identifier, Object[] args) at Blazorise.BaseComponent.OnAfterRenderAsync(Boolean firstRender) at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

shaunsales commented 1 year ago

Also having the same issue after upgrading to Blazorise 1.2.2 and BlazorMonaco 3.0.0. Has anyone found a workaround?

Aggror commented 1 year ago

Stuck here as well...

LeoRizzoli-4wardPRO commented 1 year ago

I have the same problem

BlazorMonaco version 3.0.0 Blazorise (bootstrap and other dependecies) version 1.0.7 Any update?

wdaniel1993 commented 1 year ago

no expert on JS, but after some digging I think the problem stems from Blazorise using ESM and Monaco using AMD.

I have a working application using Blazorise 0.9.3.5 and BlazorMonaco 2.0.0, but I can't upgrade, because it breaks with the same error message you got.

Found this and played around according to the suggestions, unsuccessfully unfortunately: https://github.com/microsoft/monaco-editor/issues/2283

claybrooks commented 9 months ago

Stuck as well

gt-jkinter commented 8 months ago

Having the same issue here too. Should we expect to see this issue addressed or will we need to look for alternative solutions?

Edit: I was able to find a solution here.

According to the solution in #59, you can replace the following scripts:

- <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
- <script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/monaco-yaml-prebuilt/dist/monaco-editor.min.js"></script>
yuramag commented 8 months ago

@gt-jkinter - This is great, thanks for sharing!

joergkrause commented 6 months ago

I have solved this by replacing the way the JavaScript is bundled. It works in all combinations of Blazorise and Monaco.

Advantage: Full control of code and can be bundled locally (with LigerSharp or similar), no external repo calls!

Steps:

  1. Prepare to compile javascript, add npm to your project (I use Blazor server). Use this package.json:
{
  "name": "my.app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "css-loader": "^6.9.0",
    "file-loader": "^6.2.0",
    "monaco-editor-webpack-plugin": "^7.1.0",
    "style-loader": "^3.3.4",
    "webpack": "^5.89.0",
    "webpack-cli": "^5.1.4"
  },
  "dependencies": {
    "monaco-editor": "^0.45.0"
  }
}

This includes the original monaco editor sources.

  1. Create your own bundler, I use Webpack. This is "webpack.config.js':
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
  const path = require('path');

  module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
      path: path.resolve(__dirname, 'wwwroot/assets/vendor/monaco-editor'),
      filename: 'editor.js'
    },
    module: {
      rules: [
        {`const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
  const path = require('path');

  module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
      path: path.resolve(__dirname, 'wwwroot/assets/vendor/monaco-editor'),
      filename: 'editor.js'
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: ['style-loader', 'css-loader']
        },
        {
          test: /\.ttf$/,
          use: ['file-loader']
        }
      ]
    },
    plugins: [new MonacoWebpackPlugin()]
  };`
          test: /\.css$/,
          use: ['style-loader', 'css-loader']
        },
        {
          test: /\.ttf$/,
          use: ['file-loader']
        }
      ]
    },
    plugins: [new MonacoWebpackPlugin()]
  };
  1. Compile using Webpack CLI: npx webpack. A lot output appears

image

  1. You get the JS bundle in wwwroot/assets/vendor/monaco-editor. Now reference in your app.razor (or whereever)
<script src="/assets/vendor/monaco-editor/editor.js"></script>
<script src="_content/BlazorMonaco/jsInterop.js"></script>  

Put the BlazorMonaco script afterwards!

This bundle uses a different loader and is fully compatible with Blazorise. Also, I run this with Syncfusion and this works too.

GeertvanHorrik commented 6 months ago

Tried to make this work as well. I followed the steps by @joergkrause , but it wasn't fully working for me yet. A few changes I made:

  1. Create the package.json
{
  "version": "1.0.0",
  "name": "my-app",
  "main": "index.js",
  "private": true,
  "devDependencies": {
    "css-loader": "6.10.0",
    "file-loader": "6.2.0",
    "monaco-editor-webpack-plugin": "7.1.0",
    "style-loader": "3.3.4",
    "webpack": "5.90.3",
    "webpack-cli": "5.1.4"
  },
  "dependencies": {
    "monaco-editor": "0.46.0"
  }
}
  1. Create webpack.config.js:

Note that this differs from the original code, found this example at https://github.com/microsoft/monaco-editor/blob/main/samples/browser-esm-webpack-monaco-plugin/webpack.config.js

const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const path = require('path');

// See https://github.com/microsoft/monaco-editor/blob/main/samples/browser-esm-webpack-monaco-plugin/webpack.config.js

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'wwwroot/vendor/monaco-editor'),
        filename: 'editor.js'
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.ttf$/,
                use: ['file-loader']
            }
        ]
    },
    plugins: [
        new MonacoWebpackPlugin({
            languages: ['csharp' ]
        })
    ]
};
  1. Create ./src/index.js (but not sure about the content, what should go in here?):
import * as monaco from 'monaco-editor';

window.monaco = monaco;
  1. Compile using npx webpack, creates the files in wwwroot/vendor/monaco-editor

  2. Add this on the top of the page where the editor is used:

<script src="/assets/vendor/monaco-editor/editor.js"></script>
<script src="/assets/vendor/monaco-editor/editor.worker.js"></script>
<script src="_content/BlazorMonaco/jsInterop.js"></script>  
imclint21 commented 3 months ago

Having the same issue, as @gt-jkinter said, use this CDN fix the issue:

<script src="https://cdn.jsdelivr.net/npm/monaco-yaml-prebuilt/dist/monaco-editor.min.js"></script>
UweKeim commented 1 month ago

Will this ever get fixed within the NuGet package itself?

I'm getting this error together with Bootstrap:

Error: Can only have one anonymous define call per script file
    at c.enqueueDefineAnonymousModule (loader.js:8:4917)
    at p (loader.js:9:1802)
    at bootstrap.js:8:48
    at bootstrap.js:10:3

Would be awesome if this would work out of the box 😊