@chatbi-v/cli 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/dist/bench-ACSHVGHE.mjs +77 -0
- package/dist/build-UB4D3WNI.mjs +11 -0
- package/dist/chunk-4OD6C56P.mjs +89 -0
- package/dist/chunk-7A54IJI5.mjs +6368 -0
- package/dist/chunk-LJFX6MNO.mjs +255 -0
- package/dist/chunk-SBGVKO4C.mjs +2255 -0
- package/dist/chunk-TX5M36S5.mjs +55 -0
- package/dist/chunk-V7IEPMC4.mjs +52 -0
- package/dist/chunk-WCPZB47I.mjs +262 -0
- package/dist/chunk-WIVHOK75.mjs +5292 -0
- package/dist/chunk-Y24V4GQG.mjs +9577 -0
- package/dist/commands/add.js +182 -0
- package/dist/commands/bench.js +100 -0
- package/dist/commands/build.js +290 -0
- package/dist/commands/dev.js +8 -0
- package/dist/commands/discover.js +25 -0
- package/dist/commands/doctor.js +231 -0
- package/dist/commands/fetch.js +41 -0
- package/dist/commands/gl.js +151 -0
- package/dist/commands/init.js +253 -0
- package/dist/commands/install.js +85 -0
- package/dist/commands/ls.js +46 -0
- package/dist/commands/sync.js +78 -0
- package/dist/commands/use.js +31 -0
- package/dist/config.js +70 -0
- package/dist/corekit.js +370 -0
- package/dist/execa-METROS6Z.mjs +17 -0
- package/dist/fetch-7X2UFWIV.mjs +10 -0
- package/dist/index.cjs +27278 -0
- package/dist/index.js +193 -23981
- package/dist/index.mjs +2769 -0
- package/dist/init-QFRFYEA5.mjs +12 -0
- package/dist/sandbox.js +522 -0
- package/dist/sync-7HPKGVFY.mjs +11 -0
- package/dist/utils.js +99 -0
- package/package.json +4 -3
- package/templates/app/.env.hbs +2 -2
- package/templates/app/README.md.hbs +29 -11
- package/templates/app/chatbi.config.ts.hbs +10 -33
- package/templates/app/index.html.hbs +1 -1
- package/templates/app/package.json.hbs +12 -14
- package/templates/app/postcss.config.cjs.hbs +5 -1
- package/templates/app/src/App.tsx.hbs +66 -36
- package/templates/app/src/components/GlobalSettingsModal.tsx.hbs +11 -1
- package/templates/app/src/hooks/useAppRoutes.ts.hbs +3 -6
- package/templates/app/src/hooks/usePluginLoader.ts.hbs +54 -7
- package/templates/app/src/hooks/usePluginStateSync.ts.hbs +81 -0
- package/templates/app/src/hooks/useThemeSync.ts.hbs +25 -74
- package/templates/app/src/layouts/MainContent.tsx.hbs +1 -1
- package/templates/app/src/layouts/SidebarNav.tsx.hbs +15 -14
- package/templates/app/src/main.tsx.hbs +2 -9
- package/templates/app/src/providers/AppProviders.tsx.hbs +2 -0
- package/templates/app/src/stores/useSessionStore.ts.hbs +1 -1
- package/templates/app/src/stores/useUIStore.ts.hbs +22 -3
- package/templates/app/src/vite-env.d.ts.hbs +1 -0
- package/templates/app/tailwind.config.cjs.hbs +26 -7
- package/templates/app/tsconfig.json.hbs +2 -5
- package/templates/app/vite.config.ts.hbs +67 -52
- package/templates/monorepo/package.json.hbs +1 -1
- package/templates/plugin/README.md.hbs +36 -0
- package/templates/plugin/package.json.hbs +26 -21
- package/templates/plugin/src/api/index.ts.hbs +3 -0
- package/templates/plugin/src/components/MainView.tsx.hbs +12 -0
- package/templates/plugin/src/index.tsx.hbs +39 -72
- package/templates/plugin/tsconfig.json.hbs +4 -15
- package/templates/app/src/services/api/modules/auth.ts.hbs +0 -18
|
@@ -2,13 +2,11 @@ import {
|
|
|
2
2
|
MenuFoldOutlined,
|
|
3
3
|
MenuUnfoldOutlined,
|
|
4
4
|
SettingOutlined,
|
|
5
|
-
ThunderboltOutlined,
|
|
6
5
|
} from '@ant-design/icons';
|
|
7
6
|
import { AvatarSkeleton,type PluginExtension, pluginManager, PluginSlot, SidebarIconSkeleton, Slot } from '@chatbi-v/core';
|
|
8
7
|
import React from 'react';
|
|
9
8
|
import { useNavigate } from 'react-router-dom';
|
|
10
9
|
|
|
11
|
-
import { chatbiConfig } from '../../chatbi.config';
|
|
12
10
|
import { NavSkeleton } from '../components/LayoutSkeletons';
|
|
13
11
|
import { useUIStore } from '../stores/useUIStore';
|
|
14
12
|
|
|
@@ -32,21 +30,21 @@ export const NavIcon = React.memo(({
|
|
|
32
30
|
onClick={onClick}
|
|
33
31
|
title={title}
|
|
34
32
|
className={`flex items-center cursor-pointer transition-all duration-300 relative group
|
|
35
|
-
${expanded ? 'w-full' : 'w-
|
|
33
|
+
${expanded ? 'w-full px-3' : 'w-10 justify-center'} h-10 rounded-xl
|
|
36
34
|
${
|
|
37
35
|
active
|
|
38
36
|
? 'bg-primary/15 text-primary font-semibold shadow-sm ring-1 ring-primary/20 dark:bg-primary/20'
|
|
39
37
|
: 'text-slate-500 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-white/10 hover:text-slate-900 dark:hover:text-white hover:scale-105 active:scale-95'
|
|
40
38
|
}`}
|
|
41
39
|
>
|
|
42
|
-
<div className="w-
|
|
43
|
-
<div className={`text-
|
|
40
|
+
<div className="w-5 h-5 flex items-center justify-center shrink-0">
|
|
41
|
+
<div className={`text-lg transition-transform duration-300 ${!expanded && active ? 'scale-110' : ''}`}>{icon}</div>
|
|
44
42
|
</div>
|
|
45
43
|
|
|
46
44
|
<div className={`overflow-hidden whitespace-nowrap transition-all duration-300 ease-in-out ${
|
|
47
|
-
expanded ? 'w-auto opacity-100 ml-
|
|
45
|
+
expanded ? 'w-auto opacity-100 ml-2' : 'w-0 opacity-0 ml-0'
|
|
48
46
|
}`}>
|
|
49
|
-
<span className="text-
|
|
47
|
+
<span className="text-[13px] font-medium block">
|
|
50
48
|
{label}
|
|
51
49
|
</span>
|
|
52
50
|
</div>
|
|
@@ -66,9 +64,12 @@ export const SidebarNav: React.FC<SidebarNavProps> = React.memo(({
|
|
|
66
64
|
const navigate = useNavigate();
|
|
67
65
|
const {
|
|
68
66
|
collapsed, setCollapsed,
|
|
69
|
-
setIsSettingsOpen, isMaximized
|
|
67
|
+
setIsSettingsOpen, isMaximized,
|
|
68
|
+
currentLayoutId
|
|
70
69
|
} = useUIStore();
|
|
71
70
|
|
|
71
|
+
const isTopLayout = currentLayoutId === 'top-bottom';
|
|
72
|
+
|
|
72
73
|
const renderSidebarBottomItem = React.useCallback(({ key, extension }: { key: string, extension: PluginExtension }) => {
|
|
73
74
|
const Component = extension.component;
|
|
74
75
|
return (
|
|
@@ -79,8 +80,8 @@ export const SidebarNav: React.FC<SidebarNavProps> = React.memo(({
|
|
|
79
80
|
const renderSidebarSystemItem = React.useCallback(({ key, extension }: { key: string, extension: PluginExtension }) => {
|
|
80
81
|
const Component = extension.component;
|
|
81
82
|
return (
|
|
82
|
-
<div key={key} className={`flex items-center
|
|
83
|
-
${collapsed ? 'w-
|
|
83
|
+
<div key={key} className={`flex items-center transition-all duration-300 relative group
|
|
84
|
+
${collapsed ? 'w-10 justify-center' : 'w-full'} rounded-xl`}
|
|
84
85
|
>
|
|
85
86
|
{Component ? <Component collapsed={collapsed} /> : null}
|
|
86
87
|
</div>
|
|
@@ -99,12 +100,12 @@ export const SidebarNav: React.FC<SidebarNavProps> = React.memo(({
|
|
|
99
100
|
<>
|
|
100
101
|
{/* 品牌标识 */}
|
|
101
102
|
<div className={`flex items-center gap-3 mb-6 transition-all duration-300 ${!collapsed ? 'w-full px-5' : 'justify-center'}`}>
|
|
102
|
-
<div className="w-
|
|
103
|
-
<
|
|
103
|
+
<div className="w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center shrink-0 group cursor-pointer hover:scale-105 transition-transform duration-300">
|
|
104
|
+
<div className="w-6 h-6 bg-primary rounded-md" />
|
|
104
105
|
</div>
|
|
105
106
|
{!collapsed && (
|
|
106
107
|
<div className="flex flex-col animate-in fade-in slide-in-from-left-4 duration-500">
|
|
107
|
-
<span className="font-bold text-
|
|
108
|
+
<span className="font-bold text-lg leading-tight tracking-tight text-slate-800 dark:text-slate-100">{{projectTitle}}</span>
|
|
108
109
|
</div>
|
|
109
110
|
)}
|
|
110
111
|
</div>
|
|
@@ -126,7 +127,7 @@ export const SidebarNav: React.FC<SidebarNavProps> = React.memo(({
|
|
|
126
127
|
label={extension.meta?.label}
|
|
127
128
|
active={
|
|
128
129
|
// Support multi-level route matching
|
|
129
|
-
// e.g., activeTab='
|
|
130
|
+
// e.g., activeTab='feature/10/sub' should match path='/feature'
|
|
130
131
|
// Remove leading slash for consistency
|
|
131
132
|
activeTab === (extension.meta?.path || extension.meta?.key)?.replace(/^\//, '') ||
|
|
132
133
|
activeTab.startsWith(((extension.meta?.path || extension.meta?.key)?.replace(/^\//, '') || '') + '/')
|
|
@@ -10,7 +10,6 @@ import { GlobalErrorBoundary } from './components'
|
|
|
10
10
|
import { api } from './services/api'
|
|
11
11
|
|
|
12
12
|
// 挂载全局 API 实例供插件使用
|
|
13
|
-
// 插件可以通过 window.chatbi.api 访问核心请求实例
|
|
14
13
|
declare global {
|
|
15
14
|
interface Window {
|
|
16
15
|
chatbi: {
|
|
@@ -23,18 +22,12 @@ window.chatbi = {
|
|
|
23
22
|
api
|
|
24
23
|
};
|
|
25
24
|
|
|
26
|
-
// API Mock
|
|
27
|
-
//
|
|
28
|
-
// 开启方式:
|
|
29
|
-
// 1. URL 参数: ?mock=true (优先级最高)
|
|
30
|
-
// 2. 环境变量: VITE_USE_MOCK=true (在 .env.development 中配置)
|
|
25
|
+
// 注意:API Mock 模式的初始化逻辑已移至 services/api/index.ts
|
|
26
|
+
// 采用策略:URL参数(mock=true/false) > 环境变量(VITE_USE_MOCK)
|
|
31
27
|
|
|
32
|
-
// 应用启动
|
|
33
28
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
34
29
|
<React.StrictMode>
|
|
35
|
-
{/* 全局错误边界,捕获渲染过程中的未处理异常 */}
|
|
36
30
|
<GlobalErrorBoundary>
|
|
37
|
-
{/* 路由模式:默认使用 HashRouter,如果需要 history 模式请改为 BrowserRouter */}
|
|
38
31
|
<HashRouter>
|
|
39
32
|
<App />
|
|
40
33
|
</HashRouter>
|
|
@@ -4,6 +4,7 @@ import { App as AntdApp, ConfigProvider } from 'antd';
|
|
|
4
4
|
import React, { ReactNode } from 'react';
|
|
5
5
|
|
|
6
6
|
import { useThemeSync } from '../hooks/useThemeSync';
|
|
7
|
+
import { usePluginStateSync } from '../hooks/usePluginStateSync';
|
|
7
8
|
import { api } from '../services/api';
|
|
8
9
|
|
|
9
10
|
interface AppProvidersProps {
|
|
@@ -17,6 +18,7 @@ interface AppProvidersProps {
|
|
|
17
18
|
*/
|
|
18
19
|
export const AppProviders: React.FC<AppProvidersProps> = ({ children }) => {
|
|
19
20
|
const themeConfig = useThemeSync();
|
|
21
|
+
usePluginStateSync();
|
|
20
22
|
|
|
21
23
|
// 定义 Provider 列表,顺序从外到内
|
|
22
24
|
const providers: Array<[React.ComponentType<any>, Record<string, any>]> = [
|
|
@@ -15,7 +15,7 @@ export const useSessionStore = create<SessionState>()(
|
|
|
15
15
|
setActiveSession: (id) => set({ activeSession: id }),
|
|
16
16
|
}),
|
|
17
17
|
{
|
|
18
|
-
name: '
|
|
18
|
+
name: '{{projectName}}-session-storage',
|
|
19
19
|
storage: createJSONStorage(() => createZustandStorage('system')),
|
|
20
20
|
}
|
|
21
21
|
)
|
|
@@ -24,6 +24,12 @@ export interface UIState {
|
|
|
24
24
|
setThemeId: (id: string) => void;
|
|
25
25
|
setThemeMode: (mode: 'dark' | 'light') => void;
|
|
26
26
|
toggleThemeMode: () => void;
|
|
27
|
+
|
|
28
|
+
currentLayoutId: string;
|
|
29
|
+
setLayoutId: (id: string) => void;
|
|
30
|
+
|
|
31
|
+
/** 通用状态更新 */
|
|
32
|
+
updateState: (key: string, value: any) => void;
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
export const useUIStore = create<UIState>()(
|
|
@@ -48,16 +54,29 @@ export const useUIStore = create<UIState>()(
|
|
|
48
54
|
themeMode: 'dark',
|
|
49
55
|
setThemeId: (id) => set({ currentThemeId: id }),
|
|
50
56
|
setThemeMode: (mode) => set({ themeMode: mode }),
|
|
51
|
-
toggleThemeMode: () => set((state) => ({ themeMode: state.themeMode === '
|
|
57
|
+
toggleThemeMode: () => set((state) => ({ themeMode: state.themeMode === 'dark' ? 'light' : 'dark' })),
|
|
58
|
+
|
|
59
|
+
currentLayoutId: 'left-right',
|
|
60
|
+
setLayoutId: (id) => set({ currentLayoutId: id }),
|
|
61
|
+
|
|
62
|
+
updateState: (key, value) => set((state) => {
|
|
63
|
+
// 简单的映射逻辑,或者直接 set({ [key]: value })
|
|
64
|
+
// 为了安全起见,可以检查 key 是否存在
|
|
65
|
+
if (key in state) {
|
|
66
|
+
return { [key]: value };
|
|
67
|
+
}
|
|
68
|
+
return {};
|
|
69
|
+
}),
|
|
52
70
|
}),
|
|
53
71
|
{
|
|
54
|
-
name: '
|
|
72
|
+
name: '{{projectName}}-ui-storage',
|
|
55
73
|
storage: createJSONStorage(() => createZustandStorage('system')),
|
|
56
74
|
partialize: (state) => ({
|
|
57
75
|
currentThemeId: state.currentThemeId,
|
|
58
76
|
themeMode: state.themeMode,
|
|
59
77
|
collapsed: state.collapsed,
|
|
60
|
-
isRightPanelOpen: state.isRightPanelOpen
|
|
78
|
+
isRightPanelOpen: state.isRightPanelOpen,
|
|
79
|
+
currentLayoutId: state.currentLayoutId
|
|
61
80
|
}),
|
|
62
81
|
}
|
|
63
82
|
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -1,14 +1,33 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
1
3
|
/** @type {import('tailwindcss').Config} */
|
|
2
4
|
module.exports = {
|
|
3
|
-
presets: [
|
|
4
|
-
require('@chatbi-v/tailwind-config')
|
|
5
|
-
],
|
|
6
5
|
darkMode: 'class',
|
|
7
6
|
content: [
|
|
8
|
-
'./index.html',
|
|
9
|
-
'./src/**/*.{ts,tsx}',
|
|
10
|
-
'
|
|
11
|
-
'
|
|
7
|
+
path.resolve(__dirname, './index.html'),
|
|
8
|
+
path.resolve(__dirname, './src/**/*.{js,ts,jsx,tsx}'),
|
|
9
|
+
path.resolve(__dirname, '../../plugins/*/src/**/*.{js,ts,jsx,tsx}'),
|
|
10
|
+
path.resolve(__dirname, '../../apps/*/src/**/*.{js,ts,jsx,tsx}'),
|
|
12
11
|
],
|
|
12
|
+
theme: {
|
|
13
|
+
extend: {
|
|
14
|
+
colors: {
|
|
15
|
+
background: 'rgb(var(--color-background) / <alpha-value>)',
|
|
16
|
+
surface: 'rgb(var(--color-surface) / <alpha-value>)',
|
|
17
|
+
primary: {
|
|
18
|
+
DEFAULT: 'rgb(var(--color-primary) / <alpha-value>)',
|
|
19
|
+
},
|
|
20
|
+
secondary: {
|
|
21
|
+
DEFAULT: 'rgb(var(--color-secondary) / <alpha-value>)',
|
|
22
|
+
},
|
|
23
|
+
accent: {
|
|
24
|
+
DEFAULT: 'rgb(var(--color-accent) / <alpha-value>)',
|
|
25
|
+
},
|
|
26
|
+
'text-main': 'rgb(var(--color-text-main) / <alpha-value>)',
|
|
27
|
+
'text-muted': 'rgb(var(--color-text-muted) / <alpha-value>)',
|
|
28
|
+
border: 'rgb(var(--color-border) / <alpha-value>)',
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
13
32
|
plugins: []
|
|
14
33
|
}
|
|
@@ -2,17 +2,51 @@ import react from '@vitejs/plugin-react';
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { defineConfig, loadEnv } from 'vite';
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 动态获取 Workspace 中的包,用于 exclude
|
|
8
|
+
*/
|
|
9
|
+
function getWorkspacePackages() {
|
|
10
|
+
try {
|
|
11
|
+
const pkgPath = path.resolve(__dirname, 'package.json');
|
|
12
|
+
if (!fs.existsSync(pkgPath)) return [];
|
|
13
|
+
|
|
14
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
15
|
+
const dependencies = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
16
|
+
|
|
17
|
+
return Object.keys(dependencies).filter((key) => {
|
|
18
|
+
const version = dependencies[key];
|
|
19
|
+
return version.startsWith('workspace:');
|
|
20
|
+
});
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.error('解析 package.json 获取工作区包失败', e);
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
6
26
|
|
|
7
27
|
/**
|
|
8
28
|
* 分包策略函数
|
|
9
|
-
* 用于将依赖打包成独立的 chunk,利用浏览器缓存优化加载性能
|
|
10
29
|
*/
|
|
11
30
|
function manualChunks(id: string) {
|
|
12
|
-
// 1. ChatBI
|
|
13
|
-
if (id.includes('@chatbi-
|
|
31
|
+
// 1. ChatBI X (XCML) 核心包
|
|
32
|
+
if (id.includes('@chatbi-x/xcml') || id.includes('chatbi-x/packages/xcml')) {
|
|
33
|
+
return 'chatbi-xcml';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 2. ChatBI 插件 (Workspace)
|
|
37
|
+
if (id.includes('/plugins/')) {
|
|
38
|
+
const matches = id.match(/\/plugins\/([^/]+)\//);
|
|
39
|
+
if (matches && matches[1]) {
|
|
40
|
+
const pluginName = matches[1];
|
|
41
|
+
// 统一分包名称格式为 plugin-{name}
|
|
42
|
+
return pluginName.startsWith('plugin-') ? pluginName : `plugin-${pluginName}`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 3. ChatBI 核心层 (Workspace)
|
|
47
|
+
if (id.includes('/packages/core/') || id.includes('@chatbi-v/core')) return 'chatbi-core';
|
|
14
48
|
|
|
15
|
-
//
|
|
49
|
+
// 4. 第三方依赖 (Node Modules)
|
|
16
50
|
if (id.includes('node_modules')) {
|
|
17
51
|
// React 核心 (将 React 相关包分组)
|
|
18
52
|
if (
|
|
@@ -23,12 +57,19 @@ function manualChunks(id: string) {
|
|
|
23
57
|
return 'react-vendor';
|
|
24
58
|
}
|
|
25
59
|
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
60
|
+
// Node Modules 通用拆分
|
|
61
|
+
// 自动根据包名处理 antd, @ant-design, utils 等依赖
|
|
62
|
+
const parts = id.split('/node_modules/');
|
|
63
|
+
if (parts.length > 1) {
|
|
64
|
+
const pkgPath = parts[parts.length - 1];
|
|
65
|
+
// 处理 Scoped 包 (例如 @scope/pkg)
|
|
66
|
+
const match = pkgPath.match(/^((?:@[^/]+\/)?[^/]+)/);
|
|
67
|
+
if (match) {
|
|
68
|
+
const pkgName = match[1].replace('@', '').replace('/', '-');
|
|
69
|
+
return `vendor-${pkgName}`;
|
|
70
|
+
}
|
|
29
71
|
}
|
|
30
|
-
|
|
31
|
-
// 其他通用依赖
|
|
72
|
+
|
|
32
73
|
return 'vendor';
|
|
33
74
|
}
|
|
34
75
|
}
|
|
@@ -36,66 +77,40 @@ function manualChunks(id: string) {
|
|
|
36
77
|
// https://vitejs.dev/config/
|
|
37
78
|
export default defineConfig(({ mode }) => {
|
|
38
79
|
const env = loadEnv(mode, process.cwd(), '');
|
|
39
|
-
|
|
40
|
-
// 加载内核生成的虚拟别名
|
|
41
|
-
let coreAlias = {};
|
|
42
|
-
const aliasPath = path.resolve(__dirname, './.chatbi/vite.alias.json');
|
|
43
|
-
if (fs.existsSync(aliasPath)) {
|
|
44
|
-
try {
|
|
45
|
-
coreAlias = JSON.parse(fs.readFileSync(aliasPath, 'utf-8'));
|
|
46
|
-
} catch (e) {
|
|
47
|
-
console.error('Failed to load core aliases:', e);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
80
|
|
|
51
81
|
return {
|
|
52
82
|
base: env.VITE_APP_BASE_URL || '/',
|
|
53
|
-
|
|
54
83
|
plugins: [
|
|
55
84
|
react(),
|
|
56
|
-
// 自动读取 tsconfig.json 中的 paths 配置,实现别名映射
|
|
57
|
-
tsconfigPaths(),
|
|
58
85
|
],
|
|
59
|
-
|
|
60
86
|
resolve: {
|
|
61
87
|
alias: {
|
|
62
88
|
'@': path.resolve(__dirname, './src'),
|
|
63
|
-
|
|
89
|
+
'@chatbi-plugins': path.resolve(__dirname, '../../plugins'),
|
|
90
|
+
'@chatbi-apps': path.resolve(__dirname, '../../apps'),
|
|
64
91
|
},
|
|
65
|
-
//
|
|
66
|
-
dedupe: [
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
'antd',
|
|
72
|
-
'@ant-design/icons',
|
|
73
|
-
'@ant-design/x',
|
|
74
|
-
'@chatbi-v/core'
|
|
75
|
-
],
|
|
92
|
+
// 强制统一核心依赖实例
|
|
93
|
+
dedupe: ['react', 'react-dom', 'antd', '@ant-design/x', '@chatbi-v/core'],
|
|
94
|
+
},
|
|
95
|
+
optimizeDeps: {
|
|
96
|
+
// 动态排除 workspace 包,避免开发时重复构建
|
|
97
|
+
exclude: getWorkspacePackages(),
|
|
76
98
|
},
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// proxy: {
|
|
84
|
-
// '/api': {
|
|
85
|
-
// target: 'http://localhost:8080',
|
|
86
|
-
// changeOrigin: true,
|
|
87
|
-
// rewrite: (path) => path.replace(/^\/api/, '')
|
|
88
|
-
// }
|
|
89
|
-
// }
|
|
99
|
+
css: {
|
|
100
|
+
preprocessorOptions: {
|
|
101
|
+
less: {
|
|
102
|
+
javascriptEnabled: true, // antd 需要
|
|
103
|
+
},
|
|
104
|
+
},
|
|
90
105
|
},
|
|
91
|
-
|
|
92
106
|
build: {
|
|
107
|
+
sourcemap: true,
|
|
108
|
+
chunkSizeLimit: 2000,
|
|
93
109
|
rollupOptions: {
|
|
94
110
|
output: {
|
|
95
111
|
manualChunks,
|
|
96
112
|
},
|
|
97
113
|
},
|
|
98
|
-
chunkSizeWarningLimit: 1000,
|
|
99
114
|
},
|
|
100
115
|
};
|
|
101
116
|
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# {{pluginDisplayName}}
|
|
2
|
+
|
|
3
|
+
{{pluginDescription}}
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
作为 Monorepo 插件,在主应用中通过 `pnpm add {{pluginPackageName}}` 安装。
|
|
8
|
+
|
|
9
|
+
## 开发
|
|
10
|
+
|
|
11
|
+
1. **进入插件目录**
|
|
12
|
+
```bash
|
|
13
|
+
cd packages/plugins/{{pluginFolderName}}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
2. **启动开发模式**
|
|
17
|
+
```bash
|
|
18
|
+
pnpm dev
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
3. **构建插件**
|
|
22
|
+
```bash
|
|
23
|
+
pnpm build
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 插件配置
|
|
27
|
+
|
|
28
|
+
在主应用的 `chatbi.config.ts` 中进行配置:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
plugins: {
|
|
32
|
+
'{{pluginPackageName}}': {
|
|
33
|
+
// 配置项
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
@@ -1,30 +1,35 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "{{
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"
|
|
2
|
+
"name": "{{pluginPackageName}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "{{pluginVersion}}",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist"
|
|
7
|
+
],
|
|
8
|
+
"main": "dist/index.cjs",
|
|
9
|
+
"module": "dist/index.mjs",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
9
11
|
"exports": {
|
|
10
|
-
".":
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
}
|
|
11
17
|
},
|
|
12
18
|
"scripts": {
|
|
13
|
-
"
|
|
14
|
-
"
|
|
19
|
+
"build": "chatbi-cli build",
|
|
20
|
+
"dev": "chatbi-cli build --watch"
|
|
15
21
|
},
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
"@
|
|
19
|
-
"@types/react-dom": "^18.3.1",
|
|
20
|
-
"react": "^18.3.1",
|
|
21
|
-
"react-dom": "^18.3.1",
|
|
22
|
+
"plugin": true,
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@chatbi-v/core": "^2.0.2",
|
|
22
25
|
"antd": "^5.20.0",
|
|
23
|
-
"
|
|
26
|
+
"react": "^18.3.1",
|
|
27
|
+
"react-dom": "^18.3.1"
|
|
24
28
|
},
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@chatbi-v/core": "^2.0.2",
|
|
31
|
+
"@chatbi-v/tsconfig": "^2.0.2",
|
|
32
|
+
"tsup": "^8.5.1",
|
|
33
|
+
"vite": "^5.0.0"
|
|
29
34
|
}
|
|
30
35
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const MainView: React.FC = () => {
|
|
4
|
+
return (
|
|
5
|
+
<div className="p-6">
|
|
6
|
+
<h1 className="text-2xl font-bold mb-4">{{pluginDisplayName}}</h1>
|
|
7
|
+
<p className="text-slate-500">欢迎使用 {{pluginDisplayName}} 插件。</p>
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default MainView;
|