mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
feat: load vditor dep from local (#4190)
* feat: load vditor dep from local * fix: plugin-field-markdown-vditor build config * Revert "fix: plugin-field-markdown-vditor build config" This reverts commit 60d344d3402e0da916c918f65c81b1cd734fa3ce. * feat: plugin-field-markdown-vditor: use NODE_ENV * fix: plugin-field-markdown-vdtor dep preload * fix: plugin-field-markdown-vdtor dep preload * fix: plugin-field-markdown-vdtor dep preload * feat: plugin-field-markdown-vditor set default valut for edit * fix: cdn * fix: set vditor editor value after create * fix: cdn --------- Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
132f626fa3
commit
0d9b43206c
@ -0,0 +1,15 @@
|
|||||||
|
import { defineConfig } from '@nocobase/build';
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
const vditor = path.dirname(require.resolve('vditor'));
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
afterBuild: async (log) => {
|
||||||
|
log('coping vditor dist');
|
||||||
|
await fs.cp(vditor, path.resolve(__dirname, 'dist/client/vditor/dist'), {
|
||||||
|
recursive: true,
|
||||||
|
force: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
@ -21,7 +21,7 @@
|
|||||||
"@formily/react": "2.x",
|
"@formily/react": "2.x",
|
||||||
"@formily/shared": "2.x",
|
"@formily/shared": "2.x",
|
||||||
"antd": "5.x",
|
"antd": "5.x",
|
||||||
"katex": "^0.16.10",
|
"koa-send": "^5.0.1",
|
||||||
"vditor": "^3.10.3"
|
"vditor": "^3.10.3"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { Field } from '@formily/core';
|
import { Field } from '@formily/core';
|
||||||
import { useField } from '@formily/react';
|
import { useField } from '@formily/react';
|
||||||
|
import { withDynamicSchemaProps } from '@nocobase/client';
|
||||||
import { Popover } from 'antd';
|
import { Popover } from 'antd';
|
||||||
import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react';
|
import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import Vditor from 'vditor';
|
import Vditor from 'vditor';
|
||||||
|
import { useCDN } from './const';
|
||||||
import useStyle from './style';
|
import useStyle from './style';
|
||||||
|
|
||||||
function convertToText(markdownText: string) {
|
function convertToText(markdownText: string) {
|
||||||
@ -26,10 +28,14 @@ const getContentWidth = (element) => {
|
|||||||
function DisplayInner(props: { value: string; style?: CSSProperties }) {
|
function DisplayInner(props: { value: string; style?: CSSProperties }) {
|
||||||
const containerRef = useRef<HTMLDivElement>();
|
const containerRef = useRef<HTMLDivElement>();
|
||||||
const { wrapSSR, componentCls, hashId } = useStyle();
|
const { wrapSSR, componentCls, hashId } = useStyle();
|
||||||
|
const cdn = useCDN();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!props.value) return;
|
if (!props.value) return;
|
||||||
Vditor.preview(containerRef.current, props.value, { mode: 'light' });
|
Vditor.preview(containerRef.current, props.value, {
|
||||||
|
mode: 'light',
|
||||||
|
cdn,
|
||||||
|
});
|
||||||
}, [props.value]);
|
}, [props.value]);
|
||||||
|
|
||||||
return wrapSSR(
|
return wrapSSR(
|
||||||
@ -39,9 +45,10 @@ function DisplayInner(props: { value: string; style?: CSSProperties }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Display = (props) => {
|
export const Display = withDynamicSchemaProps((props) => {
|
||||||
const field = useField<Field>();
|
const field = useField<Field>();
|
||||||
const value = props.value ?? field.value;
|
const value = props.value ?? field.value;
|
||||||
|
const cdn = useCDN();
|
||||||
|
|
||||||
const containerRef = useRef<HTMLDivElement>();
|
const containerRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
@ -55,7 +62,10 @@ export const Display = (props) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!props.value || !field.value) return;
|
if (!props.value || !field.value) return;
|
||||||
if (props.ellipsis) {
|
if (props.ellipsis) {
|
||||||
Vditor.md2html(props.value, { mode: 'light' })
|
Vditor.md2html(props.value, {
|
||||||
|
mode: 'light',
|
||||||
|
cdn,
|
||||||
|
})
|
||||||
.then((html) => {
|
.then((html) => {
|
||||||
setText(convertToText(html));
|
setText(convertToText(html));
|
||||||
})
|
})
|
||||||
@ -63,6 +73,7 @@ export const Display = (props) => {
|
|||||||
} else {
|
} else {
|
||||||
Vditor.preview(containerRef.current, props.value ?? field.value, {
|
Vditor.preview(containerRef.current, props.value ?? field.value, {
|
||||||
mode: 'light',
|
mode: 'light',
|
||||||
|
cdn,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [props.value, props.ellipsis, field.value]);
|
}, [props.value, props.ellipsis, field.value]);
|
||||||
@ -107,4 +118,4 @@ export const Display = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return <DisplayInner value={value} />;
|
return <DisplayInner value={value} />;
|
||||||
};
|
});
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React, { useRef, useEffect, useLayoutEffect } from 'react';
|
import { useAPIClient, useApp, withDynamicSchemaProps } from '@nocobase/client';
|
||||||
|
import React, { useEffect, useLayoutEffect, useRef } from 'react';
|
||||||
import Vditor from 'vditor';
|
import Vditor from 'vditor';
|
||||||
import { useAPIClient, withDynamicSchemaProps, useApp } from '@nocobase/client';
|
|
||||||
import useStyle from './style';
|
|
||||||
import { defaultToolbar } from '../interfaces/markdown-vditor';
|
import { defaultToolbar } from '../interfaces/markdown-vditor';
|
||||||
|
import { useCDN } from './const';
|
||||||
|
import useStyle from './style';
|
||||||
|
|
||||||
export const Edit = withDynamicSchemaProps((props) => {
|
export const Edit = withDynamicSchemaProps((props) => {
|
||||||
const { disabled, onChange, value, fileCollection, toolbar } = props;
|
const { disabled, onChange, value, fileCollection, toolbar } = props;
|
||||||
@ -13,13 +14,14 @@ export const Edit = withDynamicSchemaProps((props) => {
|
|||||||
const containerParentRef = useRef<HTMLDivElement>();
|
const containerParentRef = useRef<HTMLDivElement>();
|
||||||
const app = useApp();
|
const app = useApp();
|
||||||
const apiClient = useAPIClient();
|
const apiClient = useAPIClient();
|
||||||
|
const cdn = useCDN();
|
||||||
const { wrapSSR, hashId, componentCls: containerClassName } = useStyle();
|
const { wrapSSR, hashId, componentCls: containerClassName } = useStyle();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const uploadFileCollection = fileCollection ?? 'attachments';
|
const uploadFileCollection = fileCollection ?? 'attachments';
|
||||||
const toolbarConfig = toolbar ?? defaultToolbar;
|
const toolbarConfig = toolbar ?? defaultToolbar;
|
||||||
const vditor = new Vditor(containerRef.current, {
|
const vditor = new Vditor(containerRef.current, {
|
||||||
value,
|
value: value ?? '',
|
||||||
lang: apiClient.auth.locale.replaceAll('-', '_') as any,
|
lang: apiClient.auth.locale.replaceAll('-', '_') as any,
|
||||||
cache: {
|
cache: {
|
||||||
enable: false,
|
enable: false,
|
||||||
@ -34,9 +36,11 @@ export const Edit = withDynamicSchemaProps((props) => {
|
|||||||
fullscreen: {
|
fullscreen: {
|
||||||
index: 1200,
|
index: 1200,
|
||||||
},
|
},
|
||||||
|
cdn,
|
||||||
minHeight: 200,
|
minHeight: 200,
|
||||||
after: () => {
|
after: () => {
|
||||||
vdRef.current = vditor;
|
vdRef.current = vditor;
|
||||||
|
vditor.setValue(value ?? '');
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
vditor.disabled();
|
vditor.disabled();
|
||||||
} else {
|
} else {
|
||||||
@ -71,7 +75,7 @@ export const Edit = withDynamicSchemaProps((props) => {
|
|||||||
vdRef.current?.destroy();
|
vdRef.current?.destroy();
|
||||||
vdRef.current = undefined;
|
vdRef.current = undefined;
|
||||||
};
|
};
|
||||||
}, [fileCollection, toolbar]);
|
}, [fileCollection, toolbar?.join(',')]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (value === vdRef?.current?.getValue()) {
|
if (value === vdRef?.current?.getValue()) {
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
import { usePlugin } from '@nocobase/client';
|
||||||
|
import { PluginFieldMarkdownVditorClient } from '../';
|
||||||
|
|
||||||
|
export const useCDN = () => {
|
||||||
|
const plugin = usePlugin(PluginFieldMarkdownVditorClient);
|
||||||
|
return plugin.getCDN();
|
||||||
|
};
|
@ -1,8 +1,7 @@
|
|||||||
import { Plugin } from '@nocobase/client';
|
import { Plugin } from '@nocobase/client';
|
||||||
|
import 'vditor/dist/index.css';
|
||||||
import { MarkdownVditor } from './components';
|
import { MarkdownVditor } from './components';
|
||||||
import { MarkdownVditorFieldInterface } from './interfaces/markdown-vditor';
|
import { MarkdownVditorFieldInterface } from './interfaces/markdown-vditor';
|
||||||
import 'vditor/dist/index.css';
|
|
||||||
import katex from 'katex';
|
|
||||||
export class PluginFieldMarkdownVditorClient extends Plugin {
|
export class PluginFieldMarkdownVditorClient extends Plugin {
|
||||||
async afterAdd() {}
|
async afterAdd() {}
|
||||||
|
|
||||||
@ -10,12 +9,44 @@ export class PluginFieldMarkdownVditorClient extends Plugin {
|
|||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
this.app.addComponents({ MarkdownVditor });
|
this.app.addComponents({ MarkdownVditor });
|
||||||
this.initKatexDependency();
|
this.initVditorDependency();
|
||||||
this.app.dataSourceManager.addFieldInterfaces([MarkdownVditorFieldInterface]);
|
this.app.dataSourceManager.addFieldInterfaces([MarkdownVditorFieldInterface]);
|
||||||
}
|
}
|
||||||
|
|
||||||
initKatexDependency() {
|
getCDN() {
|
||||||
window['katex'] = katex;
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
// 开发模式下使用远程 cdn
|
||||||
|
return 'https://cdn.jsdelivr.net/npm/vditor@3.10.4';
|
||||||
|
}
|
||||||
|
// 生产环境,使用本地链接,支持内网
|
||||||
|
// 需要支持子目录,比如应用部署在 /xxx/ 目录下
|
||||||
|
return this.app.getPublicPath() + 'static/plugins/@nocobase/plugin-field-markdown-vditor/dist/client/vditor';
|
||||||
|
}
|
||||||
|
|
||||||
|
initVditorDependency() {
|
||||||
|
const cdn = this.getCDN();
|
||||||
|
try {
|
||||||
|
const vditorDepdencePrefix = 'plugin-field-markdown-vditor-dep';
|
||||||
|
const vditorDepdence = {
|
||||||
|
[`${vditorDepdencePrefix}.katex`]: `${cdn}/dist/js/katex/katex.min.js?v=0.16.9`,
|
||||||
|
[`${vditorDepdencePrefix}.ABCJS`]: `${cdn}/dist/js/abcjs/abcjs_basic.min`,
|
||||||
|
[`${vditorDepdencePrefix}.plantumlEncoder`]: `${cdn}/dist/js/plantuml/plantuml-encoder.min`,
|
||||||
|
[`${vditorDepdencePrefix}.echarts`]: `${cdn}/dist/js/echarts/echarts.min`,
|
||||||
|
[`${vditorDepdencePrefix}.flowchart`]: `${cdn}/dist/js/flowchart.js/flowchart.min`,
|
||||||
|
[`${vditorDepdencePrefix}.Viz`]: `${cdn}/dist/js/graphviz/viz`,
|
||||||
|
[`${vditorDepdencePrefix}.mermaid`]: `${cdn}/dist/js/mermaid/mermaid.min`,
|
||||||
|
};
|
||||||
|
this.app.requirejs.require.config({
|
||||||
|
paths: vditorDepdence,
|
||||||
|
});
|
||||||
|
Object.keys(vditorDepdence).forEach((key) => {
|
||||||
|
this.app.requirejs.require([key], (m) => {
|
||||||
|
window[key.split('.')[1]] = m;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log('initVditorDependency failed', e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user