diff --git a/packages/editor/package.json b/packages/editor/package.json index 035b5d3d..0a95d00b 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -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", diff --git a/packages/editor/src/layouts/CodeEditor.vue b/packages/editor/src/layouts/CodeEditor.vue index 47c93d82..b0f22207 100644 --- a/packages/editor/src/layouts/CodeEditor.vue +++ b/packages/editor/src/layouts/CodeEditor.vue @@ -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; diff --git a/packages/editor/src/type.ts b/packages/editor/src/type.ts index ad1296db..66e9b88d 100644 --- a/packages/editor/src/type.ts +++ b/packages/editor/src/type.ts @@ -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 export interface EditorInstallOptions { parseDSL: (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; customCreateMonacoDiffEditor: ( - monaco: typeof Monaco, + monaco: typeof import('monaco-editor'), codeEditorEl: HTMLElement, options: Monaco.editor.IStandaloneEditorConstructionOptions & { editorCustomType?: string }, - ) => Monaco.editor.IStandaloneDiffEditor; + ) => Promise | Monaco.editor.IStandaloneDiffEditor; [key: string]: any; } diff --git a/packages/editor/src/utils/monaco-editor.ts b/packages/editor/src/utils/monaco-editor.ts index 23de29be..d2748044 100644 --- a/packages/editor/src/utils/monaco-editor.ts +++ b/packages/editor/src/utils/monaco-editor.ts @@ -1,8 +1,15 @@ -import { emmetCSS, emmetHTML } from 'emmet-monaco-es'; -import * as monaco from 'monaco-editor'; +let cached: Promise | 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; +}; diff --git a/packages/editor/src/utils/props.ts b/packages/editor/src/utils/props.ts index f0679bbb..333a7c10 100644 --- a/packages/editor/src/utils/props.ts +++ b/packages/editor/src/utils/props.ts @@ -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', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d25602f1..73701139 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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