[Feature Request] ESM build that can be loaded from CDNs
Context
- [X] This issue is not a bug report. (please use a different template for reporting a bug)
- [X] This issue is not a duplicate of an existing issue. (please use the search to find existing issues)
Description
This is a suggestion to provide an ESM build that can be loaded from CDN.
Currently, the recommended way is to build the editor with a bundler and host it with the page that needs to load it. In addition it requires the user to configure the MonacoEnvironment.getWorkerUrl
This is a bit cumbersome and exposes implementation details that the end-user does not need to be concerned with.
The other alternative is to use the loader, that loads an AMD version, which I think should no longer be the recommended way, with ESM being used across the whole eco-system. In addition, it is prone to conflicts with other libraries and getting such errors:
Error: Can only have one anonymous define call per script file
My suggestion is something like this:
<div id="container" style="height: 200px;"></div>
<script type="module">
import { monaco } from "https://cdn.jsdelivr.net/npm/monaco-editor-esm-cdn/monaco.js";
monaco.editor.create(document.getElementById("container"), {
value: `function x() {\n\tconsole.log("Hello world!");\n}`,
language: "javascript",
});
</script>
This works by using a simple workaround that allows using web workers from a CDN.
I believe this can make using Monaco editor much simpler. If you think this way is acceptable, I can start a PR to either provide such build that can just be published with the npm package or at least add docs for using something like this.
Please see the example repo: https://github.com/hatemhosny/monaco-editor-esm-cdn
Monaco Editor Playground Link
No response
Monaco Editor Playground Code
No response
This is not a big deal to run it through esm.sh
import * as Monaco from 'https://esm.sh/[email protected]?bundle';
import EditorWorker from 'https://esm.sh/[email protected]/esm/vs/editor/editor.worker?worker';
import JsonWorker from 'https://esm.sh/[email protected]/esm/vs/language/json/json.worker?worker';
import CssWorker from 'https://esm.sh/[email protected]/esm/vs/language/css/css.worker?worker';
import HtmlWorker from 'https://esm.sh/[email protected]/esm/vs/language/html/html.worker?worker';
import TSWorker from 'https://esm.sh/[email protected]/esm/vs/language/typescript/ts.worker?worker';
async function loadCSS() {
const css = await fetch(`https://esm.sh/[email protected]?css`).then(response => response.text());
const style = document.createElement('style');
style.id = 'monaco-css';
style.innerHTML = css;
document.getElementById('monaco-css')?.remove();
document.head.appendChild(style);
}
self.monaco = monaco;
self.MonacoEnvironment = {
getWorker(_, label) {
if (label === 'json') {
return new JsonWorker();
}
if (label === 'css' || label === 'scss' || label === 'less') {
return new CssWorker();
}
if (label === 'html') {
return new HtmlWorker();
}
if (label === 'typescript' || label === 'javascript') {
return TSWorker();
}
return new EditorWorker();
}
};
loadCSS();
monaco.editor.create(document.getElementById("container"), {
value: `function x() {\n\tconsole.log("Hello world!");\n}`,
language: "javascript",
});
But yes, it's really strange that Microsoft recommends using that silly require loader instead of ESM.
The link is dead - the weird AMD solution is still available through e.g. https://log.schemescape.com/posts/web-development/embedding-monaco-from-cdn.html
Closing as duplicate of https://github.com/microsoft/monaco-editor/issues/886
@hediet This issue is not just about loading CSS as discussed #886
It is everything related to loading Monaco from a CDN (separate origin), including loading web workers.
Currently to use the ESM setup, I have to manually build monaco and place all the built files on the same origin that uses it for web workers to work.
I'm proposing loading everything as ESM from a CDN as shown in the code snippet posted above which just works in any HTML page with no build steps: (demo: https://livecodes.io/?x=id/dgzkpnfzzbq)
<div id="container" style="height: 200px;"></div>
<script type="module">
import { monaco } from "https://cdn.jsdelivr.net/npm/monaco-editor-esm-cdn/monaco.js";
monaco.editor.create(document.getElementById("container"), {
value: `function x() {\n\tconsole.log("Hello world!");\n}`,
language: "javascript",
});
</script>