intools-cli 1.0.7 → 1.0.8

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.
Files changed (2) hide show
  1. package/PLUGIN_API.md +140 -24
  2. package/package.json +1 -1
package/PLUGIN_API.md CHANGED
@@ -141,56 +141,172 @@
141
141
  "icon": { "type": "svg", "value": "<svg>...</svg>" }
142
142
  ```
143
143
 
144
- ## Preload 配置(自定义 Node.js 能力)
144
+ ## Preload 预加载脚本 核心概念
145
145
 
146
- 配置自定义 preload 脚本,可在渲染进程中直接使用 Node.js 能力。
146
+ > [!IMPORTANT]
147
+ > **Preload 是 InTools 插件访问 Node.js 能力的核心机制。** 对于需要在渲染进程(UI)中使用 Node.js API、第三方 npm 模块或 Electron 渲染进程 API 的插件来说,Preload 是**必不可少**的。
148
+
149
+ ### 什么是 Preload?
150
+
151
+ Preload 脚本是一个特殊的 JavaScript 文件,在**渲染进程加载之前**执行,具有以下特点:
152
+
153
+ | 特性 | 说明 |
154
+ |------|------|
155
+ | 🔧 **Node.js 完整支持** | 可以使用 `require()` 导入任何 Node.js 原生模块和 npm 包 |
156
+ | 🖥️ **Electron API 访问** | 可以调用 Electron 渲染进程 API |
157
+ | 🌉 **桥接能力** | 通过 `window.xxx` 将原生能力暴露给前端 React/Vue 组件 |
158
+ | ⚡ **同步执行** | 在页面 DOM 加载前执行,确保 API 可用 |
159
+
160
+ ### 适用场景
161
+
162
+ 以下场景**需要使用** Preload:
163
+
164
+ - 📂 使用 `pdf-lib`、`sharp`、`ffmpeg` 等需要 Node.js 环境的 npm 包
165
+ - 🔐 调用 Node.js 加密模块 (`crypto`)、子进程 (`child_process`)
166
+ - 📁 需要比 `window.intools.filesystem` 更底层的文件操作
167
+ - 🔗 与本地数据库交互 (SQLite、LevelDB 等)
168
+ - 🎯 任何需要原生能力但又想在前端统一调用的场景
169
+
170
+ ---
147
171
 
148
172
  ### 配置方式
149
173
 
174
+ 在 `manifest.json` 中添加 `preload` 字段,指定预加载脚本路径:
175
+
150
176
  ```json
151
177
  {
152
- "preload": "preload.js"
178
+ "name": "my-plugin",
179
+ "version": "1.0.0",
180
+ "displayName": "我的插件",
181
+ "main": "dist/main.js",
182
+ "ui": "ui/index.html",
183
+ "preload": "preload.js", // 👈 指定预加载脚本
184
+ "features": [...]
153
185
  }
154
186
  ```
155
187
 
156
- ### preload.js 示例
188
+ ---
189
+
190
+ ### preload.js 编写规范
157
191
 
158
192
  ```javascript
159
- // preload.js - 遵循 CommonJS 规范
193
+ // preload.js - 必须使用 CommonJS 规范
160
194
  const fs = require('fs')
161
195
  const os = require('os')
162
196
  const path = require('path')
163
-
164
- // 通过 window 暴露给前端
165
- window.myApi = {
197
+ const { PDFDocument } = require('pdf-lib') // 可使用 npm 包
198
+
199
+ /**
200
+ * 通过 window 对象暴露 API 给前端
201
+ * 命名建议:window.{插件名}Api 或 window.{功能名}Api
202
+ */
203
+ window.myPluginApi = {
204
+ // 同步方法
166
205
  getHomeDir: () => os.homedir(),
167
- readFile: (filePath) => fs.readFileSync(filePath, 'utf-8'),
168
- platform: process.platform
206
+ getPlatform: () => process.platform,
207
+
208
+ // 异步方法
209
+ readFile: async (filePath) => {
210
+ return fs.promises.readFile(filePath, 'utf-8')
211
+ },
212
+
213
+ // 复杂功能封装
214
+ mergePDFs: async (pdfPaths, outputPath) => {
215
+ const mergedPdf = await PDFDocument.create()
216
+ for (const pdfPath of pdfPaths) {
217
+ const pdfBytes = fs.readFileSync(pdfPath)
218
+ const pdf = await PDFDocument.load(pdfBytes)
219
+ const pages = await mergedPdf.copyPages(pdf, pdf.getPageIndices())
220
+ pages.forEach(page => mergedPdf.addPage(page))
221
+ }
222
+ const bytes = await mergedPdf.save()
223
+ fs.writeFileSync(outputPath, bytes)
224
+ return outputPath
225
+ }
169
226
  }
227
+
228
+ console.log('[Preload] API 已挂载到 window.myPluginApi')
170
229
  ```
171
230
 
172
- ### 前端调用
231
+ ---
232
+
233
+ ### 前端调用示例
173
234
 
174
- ```typescript
175
- // 在 UI 组件中使用
176
- const homeDir = window.myApi?.getHomeDir()
177
- const content = window.myApi?.readFile('/path/to/file.txt')
235
+ ```tsx
236
+ // 在 React 组件中调用
237
+ import { useEffect, useState } from 'react'
178
238
 
179
- // 核心 API 仍然可用
180
- const text = await window.intools.clipboard.readText()
239
+ // 类型声明(推荐单独放在 types.d.ts)
240
+ declare global {
241
+ interface Window {
242
+ myPluginApi?: {
243
+ getHomeDir: () => string
244
+ getPlatform: () => string
245
+ readFile: (path: string) => Promise<string>
246
+ mergePDFs: (paths: string[], output: string) => Promise<string>
247
+ }
248
+ }
249
+ }
250
+
251
+ export function MyComponent() {
252
+ const [homeDir, setHomeDir] = useState('')
253
+
254
+ useEffect(() => {
255
+ // 使用可选链确保安全访问
256
+ if (window.myPluginApi) {
257
+ setHomeDir(window.myPluginApi.getHomeDir())
258
+ }
259
+ }, [])
260
+
261
+ const handleMerge = async () => {
262
+ const result = await window.myPluginApi?.mergePDFs(
263
+ ['/path/to/1.pdf', '/path/to/2.pdf'],
264
+ '/path/to/merged.pdf'
265
+ )
266
+ console.log('合并完成:', result)
267
+ }
268
+
269
+ // 核心 API 仍然可用
270
+ const handleCopy = async () => {
271
+ const text = await window.intools.clipboard.readText()
272
+ console.log('剪贴板内容:', text)
273
+ }
274
+
275
+ return <div>Home: {homeDir}</div>
276
+ }
181
277
  ```
182
278
 
279
+ ---
280
+
281
+ ### 与 Main 后端的区别
282
+
283
+ | 对比项 | Preload 脚本 | Main 后端 (main.js) |
284
+ |--------|--------------|---------------------|
285
+ | 执行环境 | 渲染进程(带 Node.js 权限) | 独立 Worker 进程 |
286
+ | 调用方式 | `window.xxxApi.method()` | `window.intools.host.invoke()` |
287
+ | 适合场景 | 同步操作、UI 紧密相关的原生功能 | 后台任务、长时间运行的操作 |
288
+ | 进程通信 | 无需 IPC,直接调用 | 需要 IPC,异步调用 |
289
+ | 生命周期 | 随 UI 窗口创建/销毁 | 独立管理,可持久化 |
290
+
291
+ > [!TIP]
292
+ > **选择建议**:如果功能与 UI 紧密相关且需要快速响应,使用 **Preload**;如果是后台任务或需要在无 UI 时运行,使用 **Main 后端**。
293
+
294
+ ---
295
+
183
296
  ### 注意事项
184
297
 
185
298
  | 项目 | 说明 |
186
299
  |------|------|
187
- | 文件格式 | CommonJS 格式,使用 `require()` 导入模块 |
188
- | 代码规范 | 必须是清晰可读的源码,**不能压缩/混淆** |
189
- | 可用模块 | Node.js 原生模块 + 第三方 npm 模块 |
190
- | API 暴露 | 通过 `window.xxx` 暴露自定义 API |
191
- | 核心 API | `window.intools` 核心 API 仍然可用 |
192
- | 安全性 | 有完整 Node.js 权限,需注意安全风险 |
193
- | 打包 | 运行 `intools pack` 会自动包含 preload 文件 |
300
+ | 📝 文件格式 | **必须是 CommonJS** 格式,使用 `require()` 导入模块 |
301
+ | 🔍 代码规范 | 必须是清晰可读的源码,**禁止压缩/混淆**(安全审查需要) |
302
+ | 📦 可用模块 | Node.js 原生模块 + 已安装的 npm |
303
+ | 🌐 API 暴露 | 通过 `window.xxx` 暴露,建议使用 `window.{插件名}Api` 命名 |
304
+ | 🔧 核心 API | `window.intools` 核心 API Preload 环境中**仍然可用** |
305
+ | ⚠️ 安全性 | 拥有完整 Node.js 权限,**请谨慎处理用户输入** |
306
+ | 📦 打包 | `intools pack` 会自动包含 preload 及其依赖 |
307
+
308
+ > [!CAUTION]
309
+ > Preload 脚本拥有完整的 Node.js 权限,可以访问文件系统、网络等敏感资源。请确保代码安全,避免执行不可信的用户输入。
194
310
 
195
311
  ---
196
312
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "intools-cli",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "InTools 插件开发 CLI 工具",
5
5
  "main": "dist/index.js",
6
6
  "files": [