refactor(editor): monaco-editor是使用npm包版本

This commit is contained in:
roymondchen 2022-03-11 15:14:20 +08:00 committed by jia000
parent 2bfb85bdbf
commit 6479751354
5 changed files with 71 additions and 59 deletions

View File

@ -20,6 +20,8 @@ editor中组件自定义属性配置由[magic-form](../form/introduction.md)提
$ npm install @tmagic/form@next element-plus -S
```
editor中还包含了[monaco-editor](https://github.com/microsoft/monaco-editor)可以参考monaco-editor的[配置指引](https://github.com/microsoft/monaco-editor/blob/main/docs/integrate-esm.md)。
## 快速上手
### 引入 @tmagic/editor

5
package-lock.json generated
View File

@ -15638,6 +15638,11 @@
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"monaco-editor": {
"version": "0.32.1",
"resolved": "https://mirrors.tencent.com/npm/monaco-editor/-/monaco-editor-0.32.1.tgz",
"integrity": "sha512-LUt2wsUvQmEi2tfTOK+tjAPvt7eQ+K5C4rZPr6SeuyzjAuAHrIvlUloTcOiGjZW3fn3a/jFQCONrEJbNOaCqbA=="
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",

View File

@ -1,6 +1,7 @@
{
"version": "1.0.0-beta.2",
"name": "@tmagic/editor",
"sideEffects": false,
"main": "dist/tmagic-editor.umd.js",
"module": "dist/tmagic-editor.es.js",
"style": "dist/style.css",
@ -36,6 +37,7 @@
"element-plus": "^2.0.2",
"events": "^3.3.0",
"lodash-es": "^4.17.21",
"monaco-editor": "^0.32.1",
"serialize-javascript": "^6.0.0",
"vue": "^3.2.0"
},

View File

@ -4,28 +4,10 @@
<script lang="ts">
import { defineComponent, onMounted, onUnmounted, ref, watch } from 'vue';
import * as monaco from 'monaco-editor';
import serialize from 'serialize-javascript';
import { asyncLoadJs } from '@tmagic/utils';
const initEditor = () => {
if ((globalThis as any).monaco) {
Promise.resolve((globalThis as any).monaco);
}
return asyncLoadJs(`https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs/loader.min.js`).then(() => {
(globalThis as any).require.config({
paths: { vs: `https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.26.1/min/vs` },
});
return new Promise((resolve) => {
(globalThis as any).require(['vs/editor/editor.main'], () => {
resolve((globalThis as any).monaco);
});
});
});
};
const toString = (v: any, language: string): string => {
const toString = (v: string | any, language: string): string => {
let value = '';
if (typeof v !== 'string') {
value = serialize(v, {
@ -64,60 +46,63 @@ export default defineComponent({
},
},
emits: ['inited', 'save'],
emits: ['initd', 'save'],
setup(props, { emit }) {
let vsEditor: any = null;
let vsEditor: monaco.editor.IStandaloneCodeEditor | null = null;
let vsDiffEditor: monaco.editor.IStandaloneDiffEditor | null = null;
const values = ref('');
const loading = ref(false);
const codeEditor = ref<HTMLDivElement>();
const setEditorValue = (v: any, m: any) => {
const setEditorValue = (v: string | any, m: string | any) => {
values.value = toString(v, props.language);
if (props.type === 'diff') {
const originalModel = (globalThis as any).monaco.editor.createModel(values.value, 'text/javascript');
const modifiedModel = (globalThis as any).monaco.editor.createModel(
toString(m, props.language),
'text/javascript',
);
const originalModel = monaco.editor.createModel(values.value, 'text/javascript');
const modifiedModel = monaco.editor.createModel(toString(m, props.language), 'text/javascript');
return vsEditor.setModel({
return vsDiffEditor?.setModel({
original: originalModel,
modified: modifiedModel,
});
}
return vsEditor.setValue?.(values.value);
return vsEditor?.setValue(values.value);
};
const resizeHandler = () => {
vsEditor?.layout();
vsDiffEditor?.layout();
};
const getEditorValue = () => vsEditor.getValue?.() || '';
const getEditorValue = () =>
props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue();
const init = async () => {
if (!codeEditor.value) return;
vsEditor = (globalThis as any).monaco.editor[props.type === 'diff' ? 'createDiffEditor' : 'create'](
codeEditor.value,
{
value: values.value,
language: props.language,
tabSize: 2,
theme: 'vs-dark',
fontFamily: 'dm, Menlo, Monaco, "Courier New", monospace',
fontSize: 15,
formatOnPaste: true,
},
);
const options = {
value: values.value,
language: props.language,
tabSize: 2,
theme: 'vs-dark',
fontFamily: 'dm, Menlo, Monaco, "Courier New", monospace',
fontSize: 15,
formatOnPaste: true,
};
if (props.type === 'diff') {
vsDiffEditor = monaco.editor.createDiffEditor(codeEditor.value, options);
} else {
vsEditor = monaco.editor.create(codeEditor.value, options);
}
setEditorValue(props.initValues, props.modifiedValues);
loading.value = false;
emit('inited', vsEditor);
emit('initd', vsEditor);
codeEditor.value.addEventListener('keydown', (e) => {
if (e.keyCode === 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
@ -127,7 +112,7 @@ export default defineComponent({
});
if (props.type !== 'diff') {
vsEditor.onDidBlurEditorWidget(() => {
vsEditor?.onDidBlurEditorWidget(() => {
emit('save', getEditorValue());
});
}
@ -138,7 +123,7 @@ export default defineComponent({
watch(
() => props.initValues,
(v, preV) => {
if (vsEditor && v !== preV) {
if (v !== preV) {
setEditorValue(props.initValues, props.modifiedValues);
}
},
@ -151,17 +136,7 @@ export default defineComponent({
onMounted(async () => {
loading.value = true;
await initEditor();
if (!(globalThis as any).monaco) {
const interval = setInterval(() => {
if ((globalThis as any).monaco) {
clearInterval(interval);
init();
}
}, 300);
} else {
init();
}
init();
});
onUnmounted(() => {
@ -174,13 +149,14 @@ export default defineComponent({
codeEditor,
getEditor() {
return vsEditor;
return vsEditor || vsDiffEditor;
},
setEditorValue,
focus() {
vsEditor.focus();
vsEditor?.focus();
vsDiffEditor?.focus();
},
};
},

View File

@ -21,6 +21,12 @@ import './polyfills';
import { createApp } from 'vue';
import ElementPlus from 'element-plus';
import zhCn from 'element-plus/es/locale/lang/zh-cn';
import * as monaco from 'monaco-editor';
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
import MagicEditor from '@tmagic/editor';
import MagicForm from '@tmagic/form';
@ -32,6 +38,27 @@ import router from './route';
import 'element-plus/dist/index.css';
import '@tmagic/editor/src/theme/index.scss';
// @ts-ignore
globalThis.MonacoEnvironment = {
getWorker(_: any, label: string) {
if (label === 'json') {
return new JsonWorker();
}
if (label === 'css' || label === 'scss' || label === 'less') {
return new CssWorker();
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return new HtmlWorker();
}
if (label === 'typescript' || label === 'javascript') {
return new TsWorker();
}
return new EditorWorker();
},
};
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
const app = createApp(App);
app.use(router);
app.use(ElementPlus, {