如何从类似cdnjs的CDN上运行Monaco编辑器?

19

我有些困难,想要找到一个最小的可运行示例,它只从CDN上运行,而不是现有的大部分使用本地服务器的内置示例。

3个回答

33

在谷歌搜索一下后,我找到了 https://jsfiddle.net/developit/bwgkr6uq/ ,它只与unpkg.com配合工作,所以我大部分只是将其适应于cdnjs,这里是一个有效的HTML文件:

index.html

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Monaco editor</title>
<link rel="stylesheet" data-name="vs/editor/editor.main" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.20.0/min/vs/editor/editor.main.min.css">
</head>
<body>
<div id="container" style="height:400px;border:1px solid black;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/loader.min.js"></script>
<script>
// require is provided by loader.min.js.
require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs' }});
require(["vs/editor/editor.main"], () => {
  monaco.editor.create(document.getElementById('container'), {
    value: `function x() {
  console.log("Hello world!");
}`,
    language: 'javascript',
    theme: 'vs-dark',
  });
});
</script>
</body>
</html>

直播:http://cirosantilli.com/_raw/web-cheat/monaco-editor.html

https://jsfiddle.net/developit/bwgkr6uq 也设置了window.MonacoEnvironment,看起来有些 hacky,但现在似乎不需要它就可以正常工作。

使用 less loader magic

灵感来自:how to use monaco editor without node.js

less-loader.html

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Monaco editor no loader</title>
<link rel="stylesheet" data-name="vs/editor/editor.main" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/editor/editor.main.min.css">
</head>
<body>
<div id="container" style="height:400px;border:1px solid black;"></div>
<script>var require = { paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs' } }</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/loader.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/editor/editor.main.nls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/editor/editor.main.js"></script>
<script>
monaco.editor.create(document.getElementById('container'), {
  value: `function x() {
  console.log("Hello world!");
}`,
  language: 'javascript',
  theme: 'vs-dark',
});
</script>
</body>
</html>

实时:http://cirosantilli.com/web-cheat/monaco-editor-no-loader.html

不使用加载器

专用问题:如何在没有node.js的情况下使用monaco编辑器

我不知道如何完全不使用丑陋的加载器。

通过查看Chrome中的网络检查器选项卡,我们可以看到在打开上述HTML时加载了以下内容:

那么我们可以尝试:

no-loader.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Monaco editor no loader TODO</title>
    <link rel="stylesheet" data-name="vs/editor/editor.main" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.20.0/min/vs/editor/editor.main.min.css">
</head>
<body>
<div id="container" style="height:400px;border:1px solid black;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.20.0/min/vs/editor/editor.main.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.20.0/min/vs/editor/editor.main.nls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.20.0/min/vs/language/typescript/tsMode.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.20.0/min/vs/basic-languages/javascript/javascript.js"></script>
<script>
let editor = monaco.editor.create(document.getElementById('container'), {
    value: `function x() {
  console.log("Hello world!");
}`,
    language: 'javascript',
    theme: 'vs-dark',
});
</script>
</body>
</html>

但是这种方法失败了,因为所有.js文件都依赖于存在一个全局的define(函数,而这个函数是在加载器中定义的。

如果我们将加载器添加回上面的代码中,编辑器似乎可以工作,但是JavaScript控制台会显示一堆错误,因为有些文件正在尝试动态加载本地文件系统中的其他文件。

Webpack集成

对于任何稍微复杂一点的项目,这将是一种可行的方式。

由于它们的库分发非常复杂,所以他们提供了这个Webpack插件来帮助:https://github.com/microsoft/monaco-editor-webpack-plugin

以下是一个看起来完美运行的最小示例,请注意,当从file://运行时会出现JavaScript错误“EditorSimpleWorker.loadForeignModule上的意外使用”,因此假定仍然使用加载器来获取动态资源。构建和查看:

npm install
npm run build
python3 -m http.server

然后访问http://localhost:8080

package.json

{
  "name": "monaco-editor-webpack-plugin-demo",
  "version": "1.0.0",
  "private": true,
  "dependencies": {
    "css-loader": "5.2.4",
    "file-loader": "^6.2.0",
    "monaco-editor": "0.26.1",
    "monaco-editor-webpack-plugin": "4.1.1",
    "style-loader": "2.0.0",
    "webpack": "5.36.1",
    "webpack-cli": "4.6.0"
  },
  "scripts": {
    "build": "webpack",
    "start": "webpack serve --open --config webpack.config.js"
  }
}

index.js

import * as monaco from 'monaco-editor'
// or import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
// if shipping only a subset of the features & languages is desired

monaco.editor.create(document.getElementById('container'), {
  value: `function x() {
  console.log("Hello world!");
}`,
  language: 'javascript',
  theme: 'vs-dark',
});

index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Monaco editor webpack plugin</title>
</head>
<body>
<div id="container" style="height:400px;border:1px solid black;"></div>
<script src="dist/index.js"></script>
</body>
</html>

这个例子也可以从它们的上游测试中提取出来: https://github.com/microsoft/monaco-editor-webpack-plugin/tree/2459e4a023f9026ae5796a6e92f584c5d38e583e/test 该测试使用了包本身的 package.json,但是你需要从中提取一些 devDependencies 到你自己的 package.json 中,因为它们并不是真正的 devDependencies。完整运行:

git clone https://github.com/microsoft/monaco-editor-webpack-plugin
cd monaco-editor-webpack-plugin
npm install
npm run prepublishOnly
npm test
chromium test/dist/index.html

一个mode: 'production'的构建非常缓慢,在我的Lenovo P51上大约需要50秒。

'development'要快得多,只需要5秒,因此问题可能是所有资产的优化。

该插件提供了选择子集功能以加速和减小捆绑包的选项,我尝试过一些:

  • new MonacoWebpackPlugin({
      languages: ['javascript', 'typescript'],
    })
    

    可能可以节省几秒钟,但不是非常明显。如文档所述,使用 javascript 时必须使用 typescript

  • languages: [],: 22秒

  • languages: [], features: [],: 同样是22秒,features: [] 没有任何影响

让它与 Next.js 协同工作

就在我以为一切都结束了的时候......但不是!上述 webpack 设置在 Next.js 11 中无法正常工作,在Monaco editor with nextjs中出现了错误,但我成功通过使用https://github.com/suren-atoyan/monaco-react来解决。


6

2023 更新:如果您不需要支持旧版浏览器,最简单的方法是直接导入它。您可以使用 jsdelivr 或者 skypack

无需使用 webpack 或任何额外的加载逻辑。

<script type="module">
  import * as monaco from 'https://cdn.jsdelivr.net/npm/monaco-editor@0.39.0/+esm';

  monaco.editor.create(document.querySelector('.monaco'));
</script>
<div class="monaco" style="min-height: 100px"></div>


你能分享一个使用你在这里添加的代码行的工作示例吗? - StefanOverFlow

4

官方示例

具体而言,您可能需要查看https://github.com/microsoft/monaco-editor/blob/main/docs/integrate-amd-cross.md

使用Unpkg的示例

<script type="text/javascript" src="https://unpkg.com/monaco-editor@latest/min/vs/loader.js"></script>
<script>
  require.config({ paths: { 'vs': 'https://unpkg.com/monaco-editor@latest/min/vs' }});

  // Before loading vs/editor/editor.main, define a global MonacoEnvironment that overwrites
  // the default worker url location (used when creating WebWorkers). The problem here is that
  // HTML5 does not allow cross-domain web workers, so we need to proxy the instantiation of
  // a web worker through a same-domain script
  window.MonacoEnvironment = {
    getWorkerUrl: function(workerId, label) {
      return `data:text/javascript;charset=utf-8,${encodeURIComponent(`
        self.MonacoEnvironment = {
          baseUrl: 'https://unpkg.com/monaco-editor@latest/min/'
        };
        importScripts('https://unpkg.com/monaco-editor@latest/min/vs/base/worker/workerMain.js');`
      )}`;
    }
  };

  require(["vs/editor/editor.main"], function () {
    monaco.editor.create(document.querySelector('.monaco-editor-container'), {
      value: `function x() {
  console.log("Hello world!");
}`,
      language: 'javascript',
      theme: 'vs-dark',
    });
  });
</script>

由于埃及和其他国家目前封锁了unpkg,所以我改用cdnjs,但这段代码对我有效!其他答案都不起作用,一直出现monaco未定义的错误。谢谢! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接