ngx-monaco-editor icon indicating copy to clipboard operation
ngx-monaco-editor copied to clipboard

NgxMonacoEditorConfig Not working in angular production build

Open Stevertus opened this issue 7 years ago • 23 comments

I have the MonacoConfig in an extra file:

import { MonacoEditorModule, NgxMonacoEditorConfig } from 'ngx-monaco-editor';

const monacoConfig: NgxMonacoEditorConfig = {
  defaultOptions: {scrollBeyondLastLine: false},
  onMonacoLoad: () => {
    // Register a new language
    let monaco = (<any>window).monaco
    [...]

}
};
export default monacoConfig;

And I import it into app.module:

import monacoConfig from './editor/monaco-lang'
import { MonacoEditorModule, NgxMonacoEditorConfig } from 'ngx-monaco-editor';
...
imports: [
 MonacoEditorModule.forRoot(monacoConfig),
]

While serving and building everything acts normal, but when I build it as production the editor does not load and I am getting this error:

ERROR TypeError: Cannot read property 'defaultOptions' of null
    at e.set [as options] (main.d3395c8….bundle.js:1)
    at $r (main.d3395c8….bundle.js:1)
    at main.d3395c8….bundle.js:1
    at main.d3395c8….bundle.js:1
    at bi (main.d3395c8….bundle.js:1)
    at ro (main.d3395c8….bundle.js:1)
    at main.d3395c8….bundle.js:1
    at Object.updateDirectives (main.d3395c8….bundle.js:1)
    at Object.eo [as updateDirectives] (main.d3395c8….bundle.js:1)
    at _i (main.d3395c8….bundle.js:1)

Is my config wrong or is this a common issue?

  1. If I build it without --prod it works in the browser, but not in my electron app. I get this error:
ERROR Error: Uncaught (in promise): TypeError: window.require.config is not a function
TypeError: window.require.config is not a function
    at onGotAmdLoader (base-editor.js:50)
    at base-editor.js:68
    at new ZoneAwarePromise (zone-mix.js:891)
    at EditorComponent.webpackJsonp../node_modules/ngx-monaco-editor/base-editor.js.BaseEditor.ngAfterViewInit (base-editor.js:42)
    at callProviderLifecycles (core.js:12706)

Is something wrong with the way I import my config?

Stevertus avatar May 10 '18 13:05 Stevertus

I think that you have to set the baseUrl. Something like:

const monacoEditorConfig: NgxMonacoEditorConfig = {
    onMonacoLoad,
    baseUrl: './assets'
};

DevidCIC avatar May 15 '18 08:05 DevidCIC

Tried it already. Same problem. It also says property of null, so the whole object must be null. The same problems occures if I fix the baseUrl in the source code with the defaultOptions

Stevertus avatar May 16 '18 17:05 Stevertus

@Stevertus did you find a fix for this? I'm getting the same issue.

WarcraftYax avatar Jun 23 '18 20:06 WarcraftYax

not yet really. Had to upload my website in non-production build and it is pretty slow for some persons :(

Stevertus avatar Jun 24 '18 13:06 Stevertus

@Stevertus The same error can be replicated in the example by moving monacoConfig to an external file and building for production.

Instead of uploading a non-production build, I'd recommend just in-lining your monacoConfig in your app.module.ts file. It'll look ugly, but it will work.

WarcraftYax avatar Jun 26 '18 20:06 WarcraftYax

No its not working. This problem existing only for external server. Some other solutions or ideas what i can do it?

piotrjurczuk avatar Sep 06 '18 09:09 piotrjurczuk

I'm seeing the same issue, even with the basic example/sample provided in the README:

ERROR Error: Uncaught (in promise): TypeError: window.require.config is not a function TypeError: window.require.config is not a function.

Full trace: https://gist.github.com/1nv1n/34071e4c4fa9e37ceedd19872e939889

These are the dependencies in my package.json: https://gist.github.com/1nv1n/53b0fc655e0a9d70bbfaf4f8473373a2

And Angular config. JSON: https://gist.github.com/1nv1n/63ec946ee7b125799350b506c8281012

Any suggestions, @atul-wizni ?

1nv1n avatar Sep 20 '18 17:09 1nv1n

I fixed this issue a few days ago. You must add monaco config to app module with correct baseUrl. Do not forget attachment your config to providers.

piotrjurczuk avatar Sep 20 '18 17:09 piotrjurczuk

@piotrjurczuk , I tried to do that just now (setting baseUrl in monacoConfig in app.module.ts & passing it as MonacoEditorModule.forRoot(monacoConfig) ) & although the stack trace is slightly different, the error is the same.

Error: Uncaught (in promise): TypeError: window.require.config is not a function.

When I debug through it, on line 50 in base-editor.ts, I see window.require.config as undefined.

These are all the updates I've done to the basic Angular app so far: https://gist.github.com/1nv1n/635d0e261a76f6c1ad4f6e3e220827db

Could you please provide a complete example?

1nv1n avatar Sep 20 '18 18:09 1nv1n

Okey but in my opinion this part of code is invalid: baseUrl: './assets/monaco/' so change it to: baseUrl: 'app/assets' or to another address where your folder is actually located.

app - your app name

piotrjurczuk avatar Sep 20 '18 21:09 piotrjurczuk

Hi for all,

I tried @piotrjurczuk solution but I got same problem like above. Has anyone found a solution?

Thanks

ghost avatar Nov 09 '18 09:11 ghost

As mentioned above, I do think this looks as if the config becomes nulled once it's loaded into the editor. I chased it down in the source and I wonder if it's got to do with the provider scopes. Could it be that somehow when the module tries to add the new config it fails to provide it outside of the module, ending up making the default value null?

See affected code: https://github.com/atularen/ngx-monaco-editor/blob/master/src/platform/editor/editor.module.ts#L26

I tried setting the injector token directly in my main app.module.ts using the following and that worked perfectly:

import MonacoConfig from './monaco-config';
import { AppComponent } from './app.component';
import { EditorComponent } from './editor/editor.component';

@NgModule({
  declarations: [
    AppComponent,
    EditorComponent
  ],
  imports: [
    FormsModule,
    MonacoEditorModule.forRoot()
  ],
  providers: [
    { provide: NGX_MONACO_EDITOR_CONFIG, useValue: MonacoConfig }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

ddikman avatar Feb 10 '19 12:02 ddikman

providers: [ { provide: NGX_MONACO_EDITOR_CONFIG, useValue: MonacoConfig } ],

@ddikman Thank you very much. It really works

enginexon avatar Mar 12 '19 13:03 enginexon

@ddikman I'm having the same problem, could you share what you have in monaco-config

GlauberF avatar Nov 02 '19 20:11 GlauberF

@ddikman I'm having the same problem, could you share what you have in monaco-config

@GlauberF sure, it isn't much though but this is how it looks:

import { NgxMonacoEditorConfig } from 'ngx-monaco-editor';
const MonacoConfig: NgxMonacoEditorConfig = {
  onMonacoLoad: function() {
    monaco.editor.defineTheme('appname', {
      base: 'vs-dark',
      inherit: true,
      rules: [],
      colors: {
        'editor.lineHighlightBackground': '#444444'
      }
    });
    monaco.editor.setTheme('appname');
  }
};

export default MonacoConfig;

ddikman avatar Nov 03 '19 05:11 ddikman

Any updates on this.

I have tried all of the above and still not working for me :( BTW I am running this inside an Electron App so not sure if that has an impact?

ianadavies avatar Jan 27 '20 10:01 ianadavies

@ianadavies did you find anything out for this? I've the same issue inside of Electron.

JoBoDo avatar Jan 29 '20 06:01 JoBoDo

@JoBoDo No found nothing that works for me yet. I did find this https://github.com/Teradata/covalent-code-editor-nightly Which is basically a wrapper around monaco for Angular and claims to work with Electron, but it didn't work for me. I had similar issues with require. Worth a go though, do let me know if it works for you.

ianadavies avatar Jan 29 '20 08:01 ianadavies

@JoBoDo Actually just found this https://ngohungphuc.wordpress.com/2019/01/08/integrate-monaco-editor-with-angular/ Busy with something else atm but will try this myself in a few hours. Doesn't mention Electron, but I found it as a possible solution for integrating with Electron, it's a webpack based fix so maybe it removes all the issues with require and loader.js

ianadavies avatar Jan 29 '20 08:01 ianadavies

I switched to using @materia-ui/ngx-monaco-editor as I found it much easier to get working in Angular v9 with Ivy. Perhaps this will also work in Electron? https://github.com/materiahq/ngx-monaco-editor#readme

darrenmothersele avatar Jan 29 '20 12:01 darrenmothersele

Possible solution!

I was using SystemJS for some microfrontend stuff and SystemJS defines it's own "define" prop on global. The loader that monaco is trying to use has it's own conditions around a global "define". If it exists it will not create it's own ModuleManager.

My fix for this was to put a window['define'] = null somewhere before init'ing the editor.

This solved the issue however now I have side effects when using SystemJS which I'll have to sort out. Maybe other frameworks/libs are defining a "define" var for you guys as well.

Hope this helps!

alexboisselle-rd avatar Jul 06 '20 23:07 alexboisselle-rd

Looks like there is a race condition while loading the loader.js in the ngAfterViewInit function and the browser sending the load event when the loader.js has been added to the dom, this should be addressed with simplifying and updating ngAfterViewInit. A workaround is adding the following to the angular.json file, the downside is the loader is always included and not lazy loaded.

        "scripts": [
            "./node_modules/ngx-monaco-editor/assets/monaco/vs/loader.js"
        ]

markoj21 avatar Sep 22 '20 22:09 markoj21

@markoj21 Thanks ! This worked.

Infinity-Intellect avatar May 11 '21 07:05 Infinity-Intellect