mirror of
https://github.com/go-gost/gost-ui.git
synced 2024-08-11 17:53:29 +00:00
nonaco 后置加载
This commit is contained in:
@@ -0,0 +1 @@
|
||||
VITE_MONACO_URL=//unpkg.com/monaco-editor@0.47.0
|
||||
+16
-14
@@ -1,14 +1,16 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>GOST API Manage</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>GOST API Manage</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<script src="%VITE_MONACO_URL%/min/vs/loader.js"></script>
|
||||
<!-- <script src="//unpkg.com/monaco-editor@0.47.0/min/vs/loader.js"></script> -->
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
"qs": "^6.11.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-monaco-editor": "^0.54.0",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -21,8 +21,7 @@ import {
|
||||
useServerConfig,
|
||||
} from "../uitls/server";
|
||||
import { download, jsonFormat } from "../uitls";
|
||||
import { MonacoEditor } from "../uitls/userMonacoWorker";
|
||||
import Ctx from "../uitls/ctx";
|
||||
import { CodeEditor } from "../uitls/useMonacoEdit";
|
||||
import * as API from "../api";
|
||||
import ListCard, { ProCard } from "../components/ListCard";
|
||||
import ChainCard from "../components/ListCard/Chains";
|
||||
@@ -291,17 +290,17 @@ const Manage = () => {
|
||||
<Col span={24}>
|
||||
<ProCard boxShadow title="All Config JSON">
|
||||
{/* <pre>{jsonFormat(gostConfig!)}</pre> */}
|
||||
<MonacoEditor
|
||||
<CodeEditor
|
||||
className={"g-boder"}
|
||||
value={jsonFormat(gostConfig!)}
|
||||
height={"500"}
|
||||
height={500}
|
||||
language="json"
|
||||
options={{
|
||||
// selectOnLineNumbers: true,
|
||||
minimap: { enabled: false },
|
||||
readOnly: true,
|
||||
}}
|
||||
></MonacoEditor>
|
||||
></CodeEditor>
|
||||
</ProCard>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -3,12 +3,11 @@ import ReactDOM from "react-dom/client";
|
||||
import { Button, Dropdown, Form, FormInstance, Space } from "antd";
|
||||
import { DownOutlined } from "@ant-design/icons";
|
||||
import { jsonFormat, jsonStringFormat, jsonParse, jsonEdit } from "../../uitls";
|
||||
import * as monaco from "monaco-editor";
|
||||
import { MonacoEditor, getModel, model, modelUri } from "../../uitls/userMonacoWorker";
|
||||
import { Template } from "../../templates";
|
||||
// import { render } from "react-dom";
|
||||
// import { useServerConfig } from "../../uitls/server";
|
||||
import ModalForm, { ModalFormProps } from "../ModalForm";
|
||||
import { CodeEditor } from "../../uitls/useMonacoEdit";
|
||||
|
||||
const template2menu: any = (template: Template) => {
|
||||
const { children, ...other } = template;
|
||||
@@ -180,21 +179,20 @@ const JsonForm: React.FC<JsonFromProps> = (props) => {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<MonacoEditor
|
||||
<CodeEditor
|
||||
className={"g-boder"}
|
||||
height={300}
|
||||
language="json"
|
||||
options={{
|
||||
// selectOnLineNumbers: true,
|
||||
minimap: { enabled: false },
|
||||
// readOnly: readOnly,
|
||||
// json 数据格式测试
|
||||
// model: monaco.editor.createModel('', "json", modelUri)
|
||||
// model: getModel('')
|
||||
// model: model
|
||||
}}
|
||||
|
||||
></MonacoEditor>
|
||||
}} />
|
||||
{/* <MonacoEditor
|
||||
className={"g-boder"}
|
||||
height={300}
|
||||
language="json"
|
||||
options={{
|
||||
minimap: { enabled: false },
|
||||
}} /> */}
|
||||
</Form.Item>
|
||||
</ModalForm>
|
||||
</>
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
namespace globalThis {
|
||||
const monacoIsReady: Promise<any>;
|
||||
const monaco: any;
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { useBindValue } from "./use";
|
||||
import type * as Monaco from "monaco-editor";
|
||||
import classnames from "classnames";
|
||||
|
||||
(function () {
|
||||
const require = (window as any).require;
|
||||
let monacoURL;
|
||||
const MONACO_URL = import.meta.env.VITE_MONACO_URL || '/monaco-editor';
|
||||
if(/^(http[s]:)?\/\//.test(MONACO_URL)){
|
||||
monacoURL = MONACO_URL + '/min/vs'
|
||||
}else{
|
||||
const baseURL = new URL(import.meta.env.BASE_URL, location.href).href;
|
||||
monacoURL = new URL(`${MONACO_URL}/min/vs`, baseURL).href;
|
||||
}
|
||||
|
||||
// if(import.meta.env.PROD && import.meta.env.VITE_MONACO_URL){
|
||||
// monacoURL = import.meta.env.VITE_MONACO_URL + '/min/vs';
|
||||
// }else{
|
||||
// const baseURL = new URL(import.meta.env.BASE_URL, location.href).href;
|
||||
// monacoURL = new URL("./monaco-editor/min/vs", baseURL).href;
|
||||
// }
|
||||
|
||||
// console.log(`import_meta_env_BASE_URL`, import.meta.env.BASE_URL);
|
||||
// console.log("baseURL", baseURL);
|
||||
// const monacoURL = `//unpkg.com/monaco-editor@0.47.0/min/vs`
|
||||
require.config({ paths: { vs: `${monacoURL}` } });
|
||||
require.config({
|
||||
"vs/nls": {
|
||||
availableLanguages: {
|
||||
"*": "zh-cn",
|
||||
},
|
||||
},
|
||||
});
|
||||
(window as any).monacoIsReady = new Promise((resolve, reject) => {
|
||||
require(["vs/editor/editor.main"], function () {
|
||||
resolve(monaco);
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
monacoIsReady.then(() => {
|
||||
// monacoPython.register(); //注册 关键字,内置函数 代码提示 ;
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
allowComments: true,
|
||||
trailingCommas: "warning",
|
||||
validate: true,
|
||||
});
|
||||
// monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
|
||||
});
|
||||
|
||||
type CodeEditorProps = {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
language?: string;
|
||||
value?: string;
|
||||
theme?: string;
|
||||
height?: string | number;
|
||||
defaultValue?: string;
|
||||
onChange?: (value: string) => void;
|
||||
options?: Monaco.editor.IStandaloneEditorConstructionOptions;
|
||||
};
|
||||
|
||||
const defOptions: Monaco.editor.IStandaloneEditorConstructionOptions = {
|
||||
minimap: { enabled: false },
|
||||
automaticLayout: true,
|
||||
};
|
||||
|
||||
const CodeEditor_: React.ForwardRefRenderFunction<
|
||||
Monaco.editor.IStandaloneCodeEditor,
|
||||
CodeEditorProps
|
||||
> = (props, ref) => {
|
||||
const { onChange, options, height, className, theme = "vs", style } = props;
|
||||
const [language, setLanguage] = useBindValue(props.language, "javascript");
|
||||
const [value, setValue] = useBindValue(props.value, props.defaultValue, "");
|
||||
const [isReady, setReady] = useState(false);
|
||||
const divEl = useRef<HTMLDivElement>(null);
|
||||
const editor = useRef<any>(null);
|
||||
const self = useRef<any>({});
|
||||
|
||||
React.useImperativeHandle(ref, () => {
|
||||
return editor.current!;
|
||||
});
|
||||
|
||||
React.useImperativeHandle(
|
||||
self,
|
||||
() => {
|
||||
return {
|
||||
onChange,
|
||||
};
|
||||
},
|
||||
[onChange]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// let editor: any;
|
||||
if (divEl.current) {
|
||||
const el = divEl.current;
|
||||
let _editor: Monaco.editor.IStandaloneCodeEditor;
|
||||
monacoIsReady.then(() => {
|
||||
_editor = editor.current = monaco.editor.create(el, {
|
||||
value: value,
|
||||
language: language,
|
||||
theme,
|
||||
...defOptions,
|
||||
...options,
|
||||
});
|
||||
console.log("editor.current", editor.current.getDomNode());
|
||||
_editor.onDidChangeModelContent(function (event: any) {
|
||||
const _value = _editor.getValue();
|
||||
setValue(_value);
|
||||
self.current?.onChange?.(_value);
|
||||
});
|
||||
|
||||
_editor.addCommand(monaco.KeyMod.Alt | monaco.KeyCode.KeyX, (e) => {
|
||||
_editor.getAction("my-autoWrap-toggle")?.run();
|
||||
});
|
||||
|
||||
_editor.addAction({
|
||||
id: "my-autoWrap-toggle",
|
||||
label: "切换自动换行",
|
||||
keybindings: [
|
||||
monaco.KeyMod.Alt | monaco.KeyCode.KeyZ,
|
||||
// monaco.KeyMod.chord(
|
||||
// monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyK,
|
||||
// monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyM
|
||||
// ),
|
||||
],
|
||||
|
||||
// A precondition for this action.
|
||||
// precondition: null,
|
||||
|
||||
// A rule to evaluate on top of the precondition in order to dispatch the keybindings.
|
||||
// keybindingContext: null,
|
||||
|
||||
// contextMenuGroupId: "navigation",
|
||||
// contextMenuOrder: 1.5,
|
||||
|
||||
// Method that will be executed when the action is triggered.
|
||||
// @param editor The editor instance is passed in as a convenience
|
||||
run: function (ed, arg) {
|
||||
// alert("i'm running => " + ed.getPosition());
|
||||
// console.log("my-autoWrap-toggle", arg);
|
||||
const workWrap = ed.getOption(monaco.editor.EditorOption.wordWrap);
|
||||
ed.updateOptions({
|
||||
wordWrap: workWrap === "on" ? "off" : "on",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
setReady(true);
|
||||
});
|
||||
// let xc: any;
|
||||
// const resizeObserver = new ResizeObserver((entries) => {
|
||||
// // _editor?.layout();
|
||||
// // console.log("resizeObserver");
|
||||
// if (xc) clearTimeout(xc);
|
||||
// xc = setTimeout(() => {
|
||||
// _editor?.layout();
|
||||
// }, 100);
|
||||
// });
|
||||
// resizeObserver.observe(el);
|
||||
return () => {
|
||||
_editor?.dispose?.();
|
||||
// resizeObserver.unobserve(el);
|
||||
// resizeObserver.disconnect();
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (editor.current) {
|
||||
if (value != editor.current.getValue()) {
|
||||
editor.current.setValue(value);
|
||||
}
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames(className)}
|
||||
style={{
|
||||
height: height || "100%",
|
||||
minHeight: 0,
|
||||
minWidth: 0,
|
||||
boxSizing: "border-box",
|
||||
...style,
|
||||
}}
|
||||
ref={divEl}
|
||||
></div>
|
||||
);
|
||||
};
|
||||
|
||||
export const CodeEditor = React.forwardRef(CodeEditor_);
|
||||
@@ -1,8 +1,9 @@
|
||||
/* eslint-disable */
|
||||
import MonacoEditor from "react-monaco-editor";
|
||||
// import { monaco } from "react-monaco-editor";
|
||||
import * as monaco from "monaco-editor";
|
||||
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
|
||||
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
|
||||
import MonacoEditor from "react-monaco-editor";
|
||||
// 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 tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
|
||||
@@ -31,46 +32,47 @@ self.MonacoEnvironment = {
|
||||
},
|
||||
};
|
||||
|
||||
var modelUri = monaco.Uri.parse("a://b/foo.json"); // a made up unique URI for our model
|
||||
var getModel = (value: string) => {
|
||||
return monaco.editor.createModel(value, "json", modelUri);
|
||||
};
|
||||
var model = getModel('');
|
||||
// var modelUri = monaco.Uri.parse("a://b/foo.json"); // a made up unique URI for our model
|
||||
// var getModel = (value: string) => {
|
||||
// return monaco.editor.createModel(value, "json", modelUri);
|
||||
// };
|
||||
// var model = getModel("");
|
||||
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
allowComments: true,
|
||||
trailingCommas: "warning",
|
||||
validate: true,
|
||||
// json 数据格式测试
|
||||
schemas: [
|
||||
{
|
||||
uri: "http://gost/config.json", // id of the first schema
|
||||
fileMatch: [modelUri.toString()], // associate with our model
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
p1: {
|
||||
enum: ["v1", "v2"],
|
||||
},
|
||||
p2: {
|
||||
$ref: "http://myserver/bar-schema.json", // reference the second schema
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
uri: "http://myserver/bar-schema.json", // id of the second schema
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
q1: {
|
||||
enum: ["x1", "x2"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
// schemas: [
|
||||
// {
|
||||
// uri: "http://gost/config.json", // id of the first schema
|
||||
// fileMatch: [modelUri.toString()], // associate with our model
|
||||
// schema: {
|
||||
// type: "object",
|
||||
// properties: {
|
||||
// p1: {
|
||||
// enum: ["v1", "v2"],
|
||||
// },
|
||||
// p2: {
|
||||
// $ref: "http://myserver/bar-schema.json", // reference the second schema
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// uri: "http://myserver/bar-schema.json", // id of the second schema
|
||||
// schema: {
|
||||
// type: "object",
|
||||
// properties: {
|
||||
// q1: {
|
||||
// enum: ["x1", "x2"],
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
});
|
||||
|
||||
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
|
||||
|
||||
export { MonacoEditor, modelUri, getModel, model };
|
||||
export { MonacoEditor };
|
||||
+1
-1
@@ -21,7 +21,7 @@ export default defineConfig(({ command, mode }) => {
|
||||
output: {
|
||||
// manualChunks 配置
|
||||
manualChunks: {
|
||||
monaco: ["monaco-editor"],
|
||||
// monaco: ["monaco-editor"],
|
||||
antd: ["antd"],
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user