feat(editor): monaco-editor改成异步加载

This commit is contained in:
roymondchen 2026-03-12 17:27:07 +08:00
parent 0d698b20e7
commit 71d6dd9e38
6 changed files with 44 additions and 29 deletions

View File

@ -54,7 +54,7 @@
"@tmagic/utils": "workspace:*",
"buffer": "^6.0.3",
"deep-object-diff": "^1.1.9",
"emmet-monaco-es": "^5.6.1",
"emmet-monaco-es": "^5.7.0",
"events": "^3.3.0",
"gesto": "^1.19.4",
"keycon": "^1.4.0",

View File

@ -20,13 +20,14 @@
import { computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, useTemplateRef, watch } from 'vue';
import { FullScreen } from '@element-plus/icons-vue';
import { throttle } from 'lodash-es';
import type * as Monaco from 'monaco-editor';
import serialize from 'serialize-javascript';
import { TMagicButton } from '@tmagic/design';
import MIcon from '@editor/components/Icon.vue';
import { getEditorConfig } from '@editor/utils/config';
import monaco from '@editor/utils/monaco-editor';
import loadMonaco from '@editor/utils/monaco-editor';
defineOptions({
name: 'MEditorCodeEditor',
@ -38,7 +39,7 @@ const props = withDefaults(
modifiedValues?: any;
type?: 'diff';
language?: string;
options?: monaco.editor.IStandaloneEditorConstructionOptions;
options?: Monaco.editor.IStandaloneEditorConstructionOptions;
height?: string;
autoSave?: boolean;
parse?: boolean;
@ -99,7 +100,7 @@ const calculateExtraHeight = (): number => {
extraHeight = Math.max(editorRect.height - scrollableRect.height, 0);
// 使
if (extraHeight === 0) {
if (extraHeight === 0 && monaco) {
const editorOptions = vsEditor.getOptions();
const scrollBeyondLastLine = editorOptions.get(monaco.editor.EditorOption.scrollBeyondLastLine);
const padding = editorOptions.get(monaco.editor.EditorOption.padding);
@ -127,7 +128,7 @@ const setAutoHeight = (v = '') => {
// 使
let lineHeight = 20;
if (vsEditor) {
if (vsEditor && monaco) {
const editorOptions = vsEditor.getOptions();
lineHeight = editorOptions.get(monaco.editor.EditorOption.lineHeight) || 20;
}
@ -188,8 +189,9 @@ const parseCode = (v: string | any, language: string): any => {
return getEditorConfig('parseDSL')(v);
};
let vsEditor: monaco.editor.IStandaloneCodeEditor | null = null;
let vsDiffEditor: monaco.editor.IStandaloneDiffEditor | null = null;
let monaco: typeof import('monaco-editor') | null = null;
let vsEditor: Monaco.editor.IStandaloneCodeEditor | null = null;
let vsDiffEditor: Monaco.editor.IStandaloneDiffEditor | null = null;
const values = ref('');
const loading = ref(false);
@ -207,6 +209,8 @@ const setEditorValue = (v: string | any, m: string | any) => {
setAutoHeight(values.value);
if (!monaco) return;
if (props.type === 'diff') {
const originalModel = monaco.editor.createModel(values.value, 'text/javascript');
const modifiedModel = monaco.editor.createModel(toString(m, props.language), 'text/javascript');
@ -255,6 +259,8 @@ const init = async () => {
//
cachedExtraHeight = null;
monaco = await loadMonaco();
const options = {
value: values.value,
language: props.language,
@ -264,7 +270,7 @@ const init = async () => {
};
if (props.type === 'diff') {
vsDiffEditor = getEditorConfig('customCreateMonacoDiffEditor')(monaco, codeEditorEl.value, options);
vsDiffEditor = await getEditorConfig('customCreateMonacoDiffEditor')(monaco!, codeEditorEl.value, options);
// diff
vsDiffEditor.getModifiedEditor().onDidChangeModelContent(() => {
@ -274,7 +280,7 @@ const init = async () => {
}
});
} else {
vsEditor = getEditorConfig('customCreateMonacoEditor')(monaco, codeEditorEl.value, options);
vsEditor = await getEditorConfig('customCreateMonacoEditor')(monaco!, codeEditorEl.value, options);
//
vsEditor.onDidChangeModelContent(() => {
@ -343,6 +349,7 @@ onBeforeUnmount(() => {
vsEditor = null;
vsDiffEditor = null;
monaco = null;
//
cachedExtraHeight = null;

View File

@ -18,6 +18,7 @@
import type { Component } from 'vue';
import type EventEmitter from 'events';
import type * as Monaco from 'monaco-editor';
import Sortable, { type Options, type SortableEvent } from 'sortablejs';
import type { PascalCasedProperties } from 'type-fest';
@ -32,8 +33,6 @@ import type {
UpdateDragEl,
} from '@tmagic/stage';
import Monaco from '@editor/utils/monaco-editor';
import type { CodeBlockService } from './services/codeBlock';
import type { ComponentListService } from './services/componentList';
import type { DataSourceService } from './services/dataSource';
@ -121,15 +120,15 @@ export type GetConfig = (config: FormConfig) => Promise<FormConfig> | FormConfig
export interface EditorInstallOptions {
parseDSL: <T = any>(dsl: string) => T;
customCreateMonacoEditor: (
monaco: typeof Monaco,
monaco: typeof import('monaco-editor'),
codeEditorEl: HTMLElement,
options: Monaco.editor.IStandaloneEditorConstructionOptions & { editorCustomType?: string },
) => Monaco.editor.IStandaloneCodeEditor;
) => Promise<Monaco.editor.IStandaloneCodeEditor> | Monaco.editor.IStandaloneCodeEditor;
customCreateMonacoDiffEditor: (
monaco: typeof Monaco,
monaco: typeof import('monaco-editor'),
codeEditorEl: HTMLElement,
options: Monaco.editor.IStandaloneEditorConstructionOptions & { editorCustomType?: string },
) => Monaco.editor.IStandaloneDiffEditor;
) => Promise<Monaco.editor.IStandaloneDiffEditor> | Monaco.editor.IStandaloneDiffEditor;
[key: string]: any;
}

View File

@ -1,8 +1,15 @@
import { emmetCSS, emmetHTML } from 'emmet-monaco-es';
import * as monaco from 'monaco-editor';
let cached: Promise<typeof import('monaco-editor')> | undefined;
// 注册emmet插件
emmetHTML(monaco);
emmetCSS(monaco, ['css', 'scss']);
export default () => {
if (!cached) {
cached = Promise.all([import('emmet-monaco-es'), import('monaco-editor')]).then(([emmet, monaco]) => {
const { emmetHTML, emmetCSS } = emmet;
emmetHTML(monaco);
emmetCSS(monaco, ['css', 'scss']);
export default monaco;
return monaco;
});
}
return cached;
};

View File

@ -47,6 +47,7 @@ export const numberOptions = [
export const styleTabConfig: TabPaneConfig = {
title: '样式',
lazy: true,
display: ({ services }: any) => !(services.uiService.get('showStylePanel') ?? true),
items: [
{
@ -114,6 +115,7 @@ export const styleTabConfig: TabPaneConfig = {
export const eventTabConfig: TabPaneConfig = {
title: '事件',
lazy: true,
items: [
{
name: 'events',

16
pnpm-lock.yaml generated
View File

@ -327,8 +327,8 @@ importers:
specifier: ^1.1.9
version: 1.1.9
emmet-monaco-es:
specifier: ^5.6.1
version: 5.6.1(monaco-editor@0.48.0)
specifier: ^5.7.0
version: 5.7.0(monaco-editor@0.48.0)
events:
specifier: ^3.3.0
version: 3.3.0
@ -4166,8 +4166,8 @@ packages:
peerDependencies:
vue: ^3.2.0
emmet-monaco-es@5.6.1:
resolution: {integrity: sha512-Bdh0CJaG2NvcwCgRYQMBqtIiDI9/BwYNTFUnYd68OXC8DXNcAVLsIKIEnDhOGYtEO60Knf2OgMrL7UDQ5zh1yA==}
emmet-monaco-es@5.7.0:
resolution: {integrity: sha512-q8jtgsEWWaXHnAJ6HAcwMB7WHraRtf032TWpeOpN6SGLtwxr7hd6RgF3Kbj2rPxb6Q19fYVVafAFODYRYUS8NQ==}
peerDependencies:
monaco-editor: '>=0.22.0'
@ -8380,7 +8380,7 @@ snapshots:
'@tmagic/utils': 1.7.2(@tmagic/schema@1.7.6(typescript@5.9.3))(typescript@5.9.3)
buffer: 6.0.3
deep-object-diff: 1.1.9
emmet-monaco-es: 5.6.1(monaco-editor@0.55.1)
emmet-monaco-es: 5.7.0(monaco-editor@0.55.1)
events: 3.3.0
gesto: 1.19.4
keycon: 1.4.0
@ -8407,7 +8407,7 @@ snapshots:
'@tmagic/utils': 1.7.6(@tmagic/schema@1.7.6(typescript@5.9.3))(typescript@5.9.3)
buffer: 6.0.3
deep-object-diff: 1.1.9
emmet-monaco-es: 5.6.1(monaco-editor@0.55.1)
emmet-monaco-es: 5.7.0(monaco-editor@0.55.1)
events: 3.3.0
gesto: 1.19.4
keycon: 1.4.0
@ -9848,12 +9848,12 @@ snapshots:
transitivePeerDependencies:
- '@vue/composition-api'
emmet-monaco-es@5.6.1(monaco-editor@0.48.0):
emmet-monaco-es@5.7.0(monaco-editor@0.48.0):
dependencies:
emmet: 2.4.11
monaco-editor: 0.48.0
emmet-monaco-es@5.6.1(monaco-editor@0.55.1):
emmet-monaco-es@5.7.0(monaco-editor@0.55.1):
dependencies:
emmet: 2.4.11
monaco-editor: 0.55.1