-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
webpack/browserify compatible AMD headers #18
Comments
+1 |
https://webpack.github.io/docs/amd.html I thought webpack understands AMD code? What more should be done on our side to get the editor loadable with webpack? |
I think webpack parses headers(imports/exports) and obviously using the constructs like https://github.com/Microsoft/vscode/blob/master/build/lib/bundle.ts#L278 breaks parsing. |
Well, the editor.main.js that ships is already packed (contains 500+ AMD modules). Is the intent here to repack it (run the editor.main.js + all the javascript files we ship) through webpack? I have not used webpack so I'm not sure what we can do on our side... Should we also ship an unbundled/unpacked version where each AMD module sits in its own file? |
@alexandrudima i tried to use monaco in my script like that: require(['vs/editor/editor.main'], function() {
var editor = monaco.editor.create(document.getElementById('container'), {
value: [
'function x() {',
'\tconsole.log("Hello world!");',
'}'
].join('\n'),
language: 'javascript'
});
}); But it dosent work because Webpack cant find "edcore.main" for example, because he try to find it like file in "vs/editor" folder.
Maybe unpacked version will be work. |
@alexandrudima, yes I think shipping not bundled amd modules would definitely work for webpack/browserify. @MazheM before you can see the error I faced you need to remap paths: |
To be totally honest I believe that main npm package should only contain CommonJS version + d.ts with external modules. Bundles for different formats amd, umd etc(and ambient d.ts) should be distributed as bower or jspm packages, or at least as secondary npm packages. |
@NikGovorov Yes, i know it. I placed monaco to |
I would also appreciate some examples or help on how to get it to run with webpack. Added to webpack resolve configuration:
and did
in my main module.
Both end up with missing references to |
@alexandrudima is any update on this? |
I got monaco working now with webpack and angular2. What I did:
and build a monaco angular2 component that loads the AMD loader if required and then loads monaco as a global variable: import { Component, ViewChild, ElementRef, ViewQuery }
from '@angular/core';
import { COMMON_DIRECTIVES }
from '@angular/common';
import * as _ from 'lodash';
declare const monaco: any;
declare const require: any;
@Component({
selector: 'monaco-editor',
directives: [COMMON_DIRECTIVES],
template: `
<div id='editor' #editor class="monaco-editor" style="width: 1000px; height: 1000px">
`,
})
export class MonacoEditor {
@ViewChild('editor') editorContent: ElementRef;
constructor(
) {
}
ngAfterViewInit() {
var onGotAmdLoader = () => {
// Load monaco
(<any>window).require(['vs/editor/editor.main'], () => {
this.initMonaco();
});
};
// Load AMD loader if necessary
if (!(<any>window).require) {
var loaderScript = document.createElement('script');
loaderScript.type = 'text/javascript';
loaderScript.src = 'vs/loader.js';
loaderScript.addEventListener('load', onGotAmdLoader);
document.body.appendChild(loaderScript);
} else {
onGotAmdLoader();
}
}
// Will be called once monaco library is available
initMonaco() {
var myDiv: HTMLDivElement = this.editorContent.nativeElement;
var editor = monaco.editor.create(myDiv, {
value: [
'function x() {',
'\tconsole.log("Hello world!");',
'}'
].join('\n'),
language: 'javascript'
});
}
} This should work in a similar fashion for a react component. It might be problematic if another application part loads an incompatible AMD loader and a commonjs or unbundled version might be easier to integrate, but it works for me now. |
Still, it would be more usable in many projects if we could use it with webpack without the |
just did as what @Matthias247 suggested, but got ERROR in ./app/~/monaco-editor/dev/vs/editor/editor.main.js
Module not found: Error: Cannot resolve 'file' or 'directory' /Users/egoist/dev/jslab/app/node_modules/monaco-editor/dev/vs/editor/edcore.main in /Users/egoist/dev/jslab/app/node_modules/monaco-editor/dev/vs/editor
@ ./app/~/monaco-editor/dev/vs/editor/editor.main.js 83129:173-266 83136:173-267 83143:0-3357 83144:0-244 Version 0.5.3 |
Any update? It's basically unusable in angular2 projects as it is. |
This is a major missing part 😞 would be really nice to get it working with webpack without hacking with |
Tried to implement monaco using systemJS with jspm, which supports AMD modules. Getting the following error on import:
On closer inspection it looks like it doesn't like global for _amdLoaderGlobal, so I set it to AMDLoader. Same thing with global being set for the NLSLoaderPlugin. It then blows up in editor.main.js with the following error:
Setting the window require and define to the systemJS implementations of amdRequire and amdDefine doesn't help, but setting the define / require in the editor.main.js to use the window level objects does. At that point, it hits a monaco is undefined error. Edit: here's the systemJS mapping:
And the requires generated:
|
thanks to @Matthias247 I got it working with |
I have created a package named react-monaco-editor, it based on the approaches mentioned above (thanks to @Matthias247), hope it helps if someone uses React stack. Also hope it to be abandoned in the near future (after a better way appeared). |
For anyone using TypeScript and React, here's the component I came up with: /// <reference path="../node_modules/monaco-editor/monaco.d.ts" />
import * as React from 'react';
declare const require: any;
interface Props {
value: string;
language: string;
onChange: (newValue: string) => any;
}
export default class MonacoEditor extends React.Component<Props, {}> {
editor: monaco.editor.IStandaloneCodeEditor;
render(): JSX.Element {
return <div className='monaco-editor' ref='editor'></div>;
}
componentDidMount() {
// Monaco requires the AMD module loader to be present on the page. It is not yet
// compatible with ES6 imports. Once that happens, we can get rid of this.
// See https://github.com/Microsoft/monaco-editor/issues/18
(window['require'])(['vs/editor/editor.main'], () => {
this.editor = monaco.editor.create(this.refs['editor'] as HTMLDivElement, {
value: this.props.value,
language: this.props.language,
lineNumbers: false,
});
this.editor.onDidChangeModelContent(event => {
this.props.onChange(this.editor.getValue());
});
});
}
componentDidUpdate(prevProps: Props) {
if (prevProps.value !== this.props.value && this.editor) {
this.editor.setValue(this.props.value);
}
if (prevProps.language !== this.props.language) {
throw new Error('<MonacoEditor> language cannot be changed.');
}
}
} |
@danvk, @Matthias247: How are you working around the edcore.main and fs errors in Sorry if this is a silly question. Kind of confused though as I've tried essentially the same thing the 2 of you mentioned but with different results. |
Hm. I was getting the error using their AMD loader and |
@Matthias247 I took your example and nicely packaged it into an ugly npm package https://github.com/0plus1/ng2-monaco-editor, it's there for myself mainly and for the community, if anybody wishes to contribute please feel free! |
Regarding @Matthias247 's example, I would like to add that using this angular2 seed, it's not necessary to do any symlinking or using webpack to copy files. You can simply import from ngAfterViewInit() {
var onGotAmdLoader = () => {
// Load monaco
(<any>window).require.config({ paths: { 'vs': 'node_modules/monaco-editor/min/vs' } });
(<any>window).require(['vs/editor/editor.main'], () => {
this.initMonaco();
});
};
// Load AMD loader if necessary
if (!(<any>window).require) {
var loaderScript = document.createElement('script');
loaderScript.type = 'text/javascript';
loaderScript.src = 'node_modules/monaco-editor/min/vs/loader.js';
loaderScript.addEventListener('load', onGotAmdLoader);
document.body.appendChild(loaderScript);
} else {
onGotAmdLoader();
}
} |
@siovene thanks for that, tested it on angular-cli and it doesn't work :-( |
@alexandrudima I believe #40 #60 can now be closed also |
The challenge with the editor is that is creates web workers. Web workers have a completely different JS context, i.e. they are a fresh runtime. Also, web workers must behave differently than the source code in the UI thread. In the UI thread, our sources set up a @timkendrick has managed to bundle the worker code as a The error you are running into is IMHO a configuration error. I believe you are not defining the self.MonacoEnvironment = {
getWorkerUrl: function (moduleId, label) {
if (label === 'json') {
return './json.worker.bundle.js';
}
if (label === 'css') {
return './css.worker.bundle.js';
}
if (label === 'html') {
return './html.worker.bundle.js';
}
if (label === 'typescript' || label === 'javascript') {
return './ts.worker.bundle.js';
}
return './editor.worker.bundle.js';
}
} The UI thread talks 100% the same way to the web workers, both in the AMD and the ESM case. In the AMD case, a web worker is loaded and then it gets specialized into a language worker via TL;DR put a breakpoint in your @TheLarkInn @timkendrick I am a webpack noob and this might be obvious :). When you get a chance, can you please take a look at the two examples and let me know if there are easier ways to set things up for webpack or if there are more things we can do in the way we distribute the ESM source code to make things easier. |
wow thanks! that's great. @TheLarkInn wouldn't it be possible to use dynamic imports to generate seperate bundles (files) for the workers? |
@alexandrudima The second thing is that I try to use your config with my project which is a VueJS project. |
@rockymontana I am trying to get it up in a vue app also if you want to collaborate. |
Would |
@corbinu Absolutely! How would you like to do that? |
@rockymontana Well at the moment my version is in a private Gitlab repo. I can give you access or try to open source it later today. If it is easier your welcome to drop me an email |
What’s your email? |
@rockymontana If you do find a solution for vue, do share. I'm trying to set this up in a CodeSandBox vue environment but I'm having trouble figuring this out as well. See the editor component if you are curious. |
@moranje it might be because that Codesandbox does the bundling for you, which you can't choose the entry file (then no way to set up the worker). I'll sync with Ives and see if we can fix this problem or set up a Monaco editor template. |
edit: removed email I will note mine is using the new vue-cli 3 beta |
@rockymontana i don’t think the web worker files should be included in a script tag. The editor will create a new worker using the URLs you provide. You probably need to customise the template to exclude web worker files. this probably belongs in a new issue btw. the |
@meyer However - I checked the debugger dev tool tab and I can see that ts.worker.js is defined as a worker there, so I guess the browser can figure out that it's a worker even though it's a script tag. |
@rebornix @CompuIves thanks, that'll be great |
I opensourced what I have so far here. It is a bit of a mess but everybody feel free to make experimental PRs or I am happy to add people as developers. I will move it to github as soon as I have time to clean it up and write a readme. |
@corbinu Can I recommend that for specific changes you break them up and submit PR's to the source? This can help ensure that changes are tracked and understood and the Diff's can be reviewed etc. |
And have issues that tie to said PR's it would be nice to have people discussion implementation details and whatnot in a shared context like a code review (even if it doesn't get merged, it still helps identify all the things that have to be cleaned up for this to work really well!) |
@timkendrick has created a webpack plugin that hides all of this config away in PR #767 , and adds cool options to be able to pick whichever languages you want to use, or whichever features you want to use. I will create a new editor release with this plugin shortly, and I hope that will simplify things tremendously. |
Hi guys. Sorry to bother but I have write a blog post here to show how to integrate Monaco editor into Angular 7. |
Hello,
Is there any way to change AMD headers to be compatible with webpack/browserify?
Are there any plans to support CommonJS, UMD or ECMAscript 6 for the package and external modules in monaco.d.ts?
The text was updated successfully, but these errors were encountered: