From 24bdf1731aa2e41f882f0cbd811ecd256f6a6c0b Mon Sep 17 00:00:00 2001 From: chanx <1243304602@qq.com> Date: Wed, 3 Dec 2025 15:51:36 +0800 Subject: [PATCH] Fix:Dynamically importing jsonEditor reduces packaging time. --- web/src/components/json-edit/index.tsx | 133 ++++++++++++++++--------- web/src/custom.d.ts | 6 ++ 2 files changed, 92 insertions(+), 47 deletions(-) diff --git a/web/src/components/json-edit/index.tsx b/web/src/components/json-edit/index.tsx index 2ab49c4e2..31586c59e 100644 --- a/web/src/components/json-edit/index.tsx +++ b/web/src/components/json-edit/index.tsx @@ -1,8 +1,9 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import './css/cloud9_night.less'; import './css/index.less'; import { JsonEditorOptions, JsonEditorProps } from './interface'; + const defaultConfig: JsonEditorOptions = { mode: 'code', modes: ['tree', 'code'], @@ -14,6 +15,7 @@ const defaultConfig: JsonEditorOptions = { enableTransform: false, indentation: 2, }; + const JsonEditor: React.FC = ({ value, onChange, @@ -25,43 +27,62 @@ const JsonEditor: React.FC = ({ const editorRef = useRef(null); const { i18n } = useTranslation(); const currentLanguageRef = useRef(i18n.language); + const [isLoading, setIsLoading] = useState(true); useEffect(() => { - if (typeof window !== 'undefined') { - const JSONEditor = require('jsoneditor'); - import('jsoneditor/dist/jsoneditor.min.css'); + let isMounted = true; - if (containerRef.current) { - // Default configuration options - const defaultOptions: JsonEditorOptions = { - ...defaultConfig, - language: i18n.language === 'zh' ? 'zh-CN' : 'en', - onChange: () => { - if (editorRef.current && onChange) { - try { - const updatedJson = editorRef.current.get(); - onChange(updatedJson); - } catch (err) { - // Do not trigger onChange when parsing error occurs - console.error(err); - } + const initEditor = async () => { + if (typeof window !== 'undefined') { + try { + const JSONEditorModule = await import('jsoneditor'); + const JSONEditor = JSONEditorModule.default || JSONEditorModule; + + await import('jsoneditor/dist/jsoneditor.min.css'); + + if (isMounted && containerRef.current) { + // Default configuration options + const defaultOptions: JsonEditorOptions = { + ...defaultConfig, + language: i18n.language === 'zh' ? 'zh-CN' : 'en', + onChange: () => { + if (editorRef.current && onChange) { + try { + const updatedJson = editorRef.current.get(); + onChange(updatedJson); + } catch (err) { + // Do not trigger onChange when parsing error occurs + console.error(err); + } + } + }, + ...options, // Merge user provided options with defaults + }; + + editorRef.current = new JSONEditor( + containerRef.current, + defaultOptions, + ); + + if (value) { + editorRef.current.set(value); } - }, - ...options, // Merge user provided options with defaults - }; - editorRef.current = new JSONEditor( - containerRef.current, - defaultOptions, - ); - - if (value) { - editorRef.current.set(value); + setIsLoading(false); + } + } catch (error) { + console.error('Failed to load jsoneditor:', error); + if (isMounted) { + setIsLoading(false); + } } } - } + }; + + initEditor(); return () => { + isMounted = false; if (editorRef.current) { if (typeof editorRef.current.destroy === 'function') { editorRef.current.destroy(); @@ -92,26 +113,38 @@ const JsonEditor: React.FC = ({ } // Recreate the editor with new language - const JSONEditor = require('jsoneditor'); + const initEditorWithNewLanguage = async () => { + try { + const JSONEditorModule = await import('jsoneditor'); + const JSONEditor = JSONEditorModule.default || JSONEditorModule; - const newOptions: JsonEditorOptions = { - ...defaultConfig, - language: i18n.language === 'zh' ? 'zh-CN' : 'en', - onChange: () => { - if (editorRef.current && onChange) { - try { - const updatedJson = editorRef.current.get(); - onChange(updatedJson); - } catch (err) { - // Do not trigger onChange when parsing error occurs - } - } - }, - ...options, // Merge user provided options with defaults + const newOptions: JsonEditorOptions = { + ...defaultConfig, + language: i18n.language === 'zh' ? 'zh-CN' : 'en', + onChange: () => { + if (editorRef.current && onChange) { + try { + const updatedJson = editorRef.current.get(); + onChange(updatedJson); + } catch (err) { + // Do not trigger onChange when parsing error occurs + } + } + }, + ...options, // Merge user provided options with defaults + }; + + editorRef.current = new JSONEditor(containerRef.current, newOptions); + editorRef.current.set(currentData); + } catch (error) { + console.error( + 'Failed to reload jsoneditor with new language:', + error, + ); + } }; - editorRef.current = new JSONEditor(containerRef.current, newOptions); - editorRef.current.set(currentData); + initEditorWithNewLanguage(); } }, [i18n.language, value, onChange, options]); @@ -135,7 +168,13 @@ const JsonEditor: React.FC = ({ ref={containerRef} style={{ height }} className={`ace-tomorrow-night w-full border border-border-button rounded-lg overflow-hidden bg-bg-input ${className} `} - /> + > + {isLoading && ( +
+
Loading editor...
+
+ )} + ); }; diff --git a/web/src/custom.d.ts b/web/src/custom.d.ts index f73d61b39..dafdf09f1 100644 --- a/web/src/custom.d.ts +++ b/web/src/custom.d.ts @@ -2,3 +2,9 @@ declare module '*.md' { const content: string; export default content; } + +declare module 'jsoneditor' { + const JSONEditor: any; + export default JSONEditor; + export = JSONEditor; +}