# 葡萄城渲染组件库接入说明
> 本文件说明 `yudao-ui-admin-vue3` 如何通过本地 `file:` 方式引用仓库内 `葡萄城渲染/` 下的两个前端组件库。
> 最后更新:2026-07-07
---
## 1. 背景
主前端项目 `yudao-admin/yudao-ui-admin-vue3/` 引用了同仓库下两个本地组件库:
| 包名 | 本地路径 | 用途 |
|------|----------|------|
| `@synboy/image-editor` | `葡萄城渲染/image-editor/` | 基于 Fabric.js 的 Vue 3 图片编辑器组件 |
| `@synboy/spreadjs-custom-render` | `葡萄城渲染/spreadjs-custom-render/` | 基于 SpreadJS 数据结构的 Vue 3 模板渲染组件(依赖 image-editor) |
引用方式:在 [package.json](package.json) 中以 `file:` 相对路径声明,pnpm 会把对应目录的 `dist/` 安装到主项目 `node_modules/@synboy/` 下。
```json
"@synboy/image-editor": "file:../../葡萄城渲染/image-editor",
"@synboy/spreadjs-custom-render": "file:../../葡萄城渲染/spreadjs-custom-render"
```
> 另:image-editor 构建时把 `fabric` 设为 external,宿主必须提供 fabric。主项目已新增 `"fabric": "5.3.0"` 直接依赖(**版本必须与组件库一致,勿升到 7.x**)。
---
## 2. 首次拉取代码后的初始化步骤(重要)
组件库发布的是构建产物(`dist/`),`dist/` 不一定入库。**克隆代码后必须先构建两个组件库**,否则主项目 `pnpm dev` 会报找不到 `@synboy/.../dist/index.mjs`。
### 2.1 构建 image-editor
```bash
cd d:\xzc_work\tjy\code\葡萄城渲染\image-editor
pnpm install
pnpm build
```
产物:`葡萄城渲染/image-editor/dist/`(`index.mjs`、`index.cjs`、`style.css`、`index.d.ts`)。
### 2.2 构建 spreadjs-custom-render
```bash
cd d:\xzc_work\tjy\code\葡萄城渲染\spreadjs-custom-render
pnpm install
pnpm build
```
产物:`葡萄城渲染/spreadjs-custom-render/dist/`(`index.mjs`、`index.cjs`、`style.css`、`index.d.ts`)。
> 两个组件库的 `pnpm install` 均要求 Node ≥ 18 + pnpm ≥ 8。若 Node 17+ 报「消息加密失败」之类的 OpenSSL 错误,按 `AGENTS.md` 第 7 章给 `node --openssl-legacy-provider`。
### 2.3 主项目安装依赖
```bash
cd d:\xzc_work\tjy\code\yudao-admin\yudao-ui-admin-vue3
pnpm install --no-frozen-lockfile
```
⚠️ **必须加 `--no-frozen-lockfile`**。本项目 CI/默认配置启用了 `frozen-lockfile`,新增 `file:` 依赖后 lockfile 需要更新,不加该参数会报 `ERR_PNPM_OUTDATED_LOCKFILE`。
### 2.4 启动验证
```bash
pnpm dev
```
访问示例页验证:`http://localhost:8086/#/synboy-demo`(路由在 [src/router/modules/remaining.ts](src/router/modules/remaining.ts) 末尾,hidden 路由,需手输 URL)。
---
## 3. 日常开发流程
### 3.1 只使用组件库(不改动组件库源码)
直接在主项目开发即可,无需重复构建。
### 3.2 改动组件库源码后
`file:` 引用的是构建产物,**源码改动不会热更新**,必须重新构建:
```bash
# 改了 image-editor
cd d:\xzc_work\tjy\code\葡萄城渲染\image-editor
pnpm build
# 改了 spreadjs-custom-render
cd d:\xzc_work\tjy\code\葡萄城渲染\spreadjs-custom-render
pnpm build
```
构建完成后回到主项目,**重启 `pnpm dev`**(vite 对 `node_modules` 内文件变化不会自动重载库本身)。
> 如果频繁改组件库源码,建议改用 `pnpm link --global` 软链方式,或把两个库纳入 pnpm workspace,可避免反复 build。当前接入方式以稳定优先。
---
## 4. 使用示例
### 4.1 示例页
- 文件:[src/views/synboy-demo/index.vue](src/views/synboy-demo/index.vue)
- 路由:`/synboy-demo`(hidden,需手输 URL)
- 内容:两个 Tab,分别演示 `ImageEditor` 和 `OptimizedTemplatePreview`
- 模板数据:`public/synboy-demo/template-config.json`(从组件库 `__mock__/config.json` 复制,1.3MB,运行时 fetch 加载)
### 4.2 在业务代码中使用
```vue
```
注意点:
1. **样式必须手动引入**:两个库都导出 `dist/style.css`,不引入会没有样式。
2. **OptimizedTemplatePreview 通过 ref 调 `register()` 注入配置**,不接受 props 传 config。示例:
```ts
const spreadRef = ref>()
spreadRef.value?.register({
config, // SpreadWorkbookConfig,来自后端或 mock
formData: {}, // 表单初始数据
showToolbar: true,
readonly: false
})
```
3. **ImageEditor 的 fabric 由宿主提供**:主项目已安装 `fabric@5.3.0`,业务代码无需再 import fabric,除非要手动操作画布(此时从 `fabric` 包直接 import 即可)。
---
## 5. 常见问题
### Q1:`pnpm dev` 报 `ERR_PNPM_IGNORED_BUILDS`
这是 pnpm 的安全机制警告,提示部分依赖(canvas、esbuild、@synboy/* 等)的安装脚本被忽略。**不影响组件库使用**(组件库已构建好 dist,不需要 postinstall)。
- 如果 `pnpm dev` 因此退出码 1 而启动失败(本项目 dev 脚本会先跑 deps check),执行:
```bash
pnpm approve-builds
```
按提示选择允许的包(一般选 esbuild 即可,其余可不动),或直接:
```bash
vite --mode dev
```
跳过 deps check 直接起服务。
### Q2:`Cannot find module '@synboy/.../dist/index.mjs'`
组件库未构建。回到第 2.1 / 2.2 节执行 `pnpm build`。
### Q3:`ERR_PNPM_OUTDATED_LOCKFILE`
主项目用了 frozen-lockfile。安装时加 `--no-frozen-lockfile`:
```bash
pnpm install --no-frozen-lockfile
```
### Q4:image-editor 报 `fabric is not defined` / `Cannot find module 'fabric'`
主项目 `package.json` 必须有 `"fabric": "5.3.0"`。若误删,恢复后重新 `pnpm install --no-frozen-lockfile`。
### Q5:组件库改了代码但主项目看不到变化
`file:` 引用的是 `dist/` 产物,源码改动需重新 `pnpm build` 组件库,再重启主项目 dev server。详见第 3.2 节。
### Q6:`pnpm install` 报 OpenSSL「消息加密失败」
Node 17+ 的 OpenSSL 3 与 dmdb/旧版加密算法不兼容。该问题主要出现在 `mcp-menu-server`,组件库本身一般无此问题。如遇到,给 node 加 `--openssl-legacy-provider` 标志。
---
## 6. 目录关系示意
```
d:\xzc_work\tjy\code\
├── 葡萄城渲染\
│ ├── image-editor\ # @synboy/image-editor 源码
│ │ ├── dist\ # 构建产物(被主项目引用)
│ │ ├── src\
│ │ └── package.json
│ └── spreadjs-custom-render\ # @synboy/spreadjs-custom-render 源码
│ ├── dist\
│ ├── src\
│ └── package.json
└── yudao-admin\
└── yudao-ui-admin-vue3\ # 主前端项目
├── package.json # 声明 file: 依赖 + fabric@5.3.0
├── public\synboy-demo\ # 示例页用的 mock 模板配置
└── src\
├── router\modules\remaining.ts # /synboy-demo 路由
└── views\synboy-demo\index.vue # 示例页
```
---
## 7. 相关文件速查
| 用途 | 路径 |
|------|------|
| 主项目 package.json(file: 依赖声明) | `yudao-admin/yudao-ui-admin-vue3/package.json` |
| 示例页 | `yudao-admin/yudao-ui-admin-vue3/src/views/synboy-demo/index.vue` |
| 示例路由 | `yudao-admin/yudao-ui-admin-vue3/src/router/modules/remaining.ts`(末尾 `/synboy-demo`) |
| 示例模板数据 | `yudao-admin/yudao-ui-admin-vue3/public/synboy-demo/template-config.json` |
| image-editor 源码 | `葡萄城渲染/image-editor/` |
| spreadjs-custom-render 源码 | `葡萄城渲染/spreadjs-custom-render/` |
| 组件库 API 文档 | 各自 `README.md` |