import typescript from '@rollup/plugin-typescript'; import terser from '@rollup/plugin-terser'; import { nodeResolve } from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import replace from '@rollup/plugin-replace'; import { copyFileSync, existsSync, mkdirSync } from 'fs'; import { dirname, resolve } from 'path'; const ROOT = process.cwd(); const DIST_DIR = resolve(ROOT, 'dist'); const BACKEND_DIR = resolve(ROOT, '../src/main/resources/static/sdk'); const ASSETS = [ { src: resolve(ROOT, 'assets/launcher-logo.png'), name: 'launcher-logo.png' }, ]; const BUNDLE_FILES = ['chatbot-sdk.js', 'chatbot-sdk.min.js']; /** 将构建产物与静态资源复制到指定目录 */ function copyFiles(srcFiles, targetDir, label) { if (!existsSync(targetDir)) mkdirSync(targetDir, { recursive: true }); for (const { src, name } of srcFiles) { if (!existsSync(src)) { console.warn(`[copy-assets] 未找到 ${src},跳过`); continue; } copyFileSync(src, resolve(targetDir, name)); } console.log(`[copy-assets] 已复制 ${label} 到 ${targetDir}`); } /** Rollup 插件:构建结束后同步产物与 logo 到后端静态资源目录 */ function copyAssets() { return { name: 'copy-assets', closeBundle() { // 1. 复制 logo 到 dist(便于独立分发) copyFiles( ASSETS.map(a => ({ src: a.src, name: a.name })), DIST_DIR, 'logo 到 dist' ); // 2. 复制 logo + JS 产物到后端 static/sdk/ const backendAssets = [ ...ASSETS.map(a => ({ src: a.src, name: a.name })), ...BUNDLE_FILES.map(name => ({ src: resolve(DIST_DIR, name), name })), ]; copyFiles(backendAssets, BACKEND_DIR, 'SDK 产物与 logo 到后端 static/sdk'); }, }; } export default { input: 'src/index.ts', output: [ { file: 'dist/chatbot-sdk.js', format: 'iife', name: 'ChatbotSDK', sourcemap: false, inlineDynamicImports: true, }, { file: 'dist/chatbot-sdk.min.js', format: 'iife', name: 'ChatbotSDK', sourcemap: false, inlineDynamicImports: true, plugins: [terser()], }, ], plugins: [ // mermaid 不打包(省约 1.2MB gzip),用本地 stub 替换,避免 markdown-content 模块顶层 // Cherry.usePlugin 注册 mermaid 插件时因缺少 mermaid 抛异常导致 IIFE 加载失败 { name: 'mermaid-stub', resolveId(source) { if (source === 'mermaid') return resolve(ROOT, 'src/mermaid-stub.ts'); return null; }, }, replace({ preventAssignment: true, 'process.env.NODE_ENV': JSON.stringify('production'), }), nodeResolve({ browser: true, preferBuiltins: false, }), commonjs(), typescript({ tsconfig: './tsconfig.json', declaration: false, declarationDir: undefined, sourceMap: false, }), copyAssets(), ], };