
為 Super Productivity 開發 Solid.js 插件官方樣板工程完整實戰指南【免費下載鏈接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.項目地址: https://gitcode.com/GitHub_Trending/su/super-productivity本篇指南圍繞 Super Productivity 官方倉庫中隨附的Solid.js 插件樣板工程位于packages/plugin-dev/boilerplate-solid-js系統講解如何用 Solid.js TypeScript Vite 從零搭建一個可直接運行、可打包、可分發到 Super Productivity 的插件。讀完本文你將掌握插件目錄結構、manifest.json元數據編寫、Plugin API 的注冊與數據操作、事件鉤子、插件 UI 與宿主應用的消息通信以及完整的開發—構建—打包—安裝流水線。一、這個樣板工程能做什么樣板工程定位清晰為創建 Super Productivity 插件提供開箱即用的現代 TypeScript 基座核心特性如下對應 README 的 Features 章節Solid.js—— 快速、響應式的 UI 框架細粒度響應式信號 組件化開發TypeScript—— 借助super-productivity/plugin-api獲得完整的插件 API 類型安全現代 UI—— 干凈、響應式、自帶暗色模式支持的界面樣式Vite—— 閃電般快速的開發與構建工具鏈開箱即用—— 已內置覆蓋各類插件功能的完整示例代碼。一句話總結樣板工程把插件開發基礎設施構建、打包、內聯、類型、i18n全部配好開發者只需專注于自己的業務邏輯。二、環境準備與快速開始2.1 環境要求依賴項版本要求Node.js16包管理器npm 或 yarnSuper Productivity8.0.0與manifest.json中minSupVersion: 8.0.0對應2.2 初始化插件工程Super Productivity 的插件開發目錄位于倉庫的packages/plugin-dev/其中已包含多個插件示例automations、doc-mode、todoist-import 等和樣板工程boilerplate-solid-js。復制樣板即可生成你自己的插件cd packages/plugin-dev cp -r boilerplate-solid-js my-plugin cd my-plugin2.3 安裝依賴npm install安裝完成后node_modules中會以file:協議鏈接倉庫內的兩個關鍵包見 package.jsonsuper-productivity/plugin-api→../../plugin-api官方 TypeScript 類型定義super-productivity/vite-plugin→../../vite-plugin為插件量身定制的 Vite 插件負責構建產物整理、HTML 資產內聯。2.4 更新插件元數據編輯src/manifest.json按自己的插件進行定制將id改為全局唯一的標識符更新name、description、author按需調整permissions與hooks。注意id是插件的唯一標識打包文件名也會以${id}-v${version}.zip命名見下文打包章節務必確保唯一。三、manifest.json 插件清單詳解manifest.json是插件與 Super Productivity 宿主之間最重要的契約文件。樣板默認內容如下源碼{ id: boilerplate-solid-js, name: Solid.js Boilerplate Plugin, version: 1.0.0, manifestVersion: 1, minSupVersion: 8.0.0, description: A boilerplate plugin demonstrating Solid.js integration with Super Productivity, author: Your Name, homepage: https://github.com/yourusername/your-plugin, repository: { type: git, url: https://github.com/yourusername/your-plugin.git }, permissions: [], hooks: [taskComplete, taskUpdate, contextChange], iFrame: true, sidePanel: false, isSkipMenuEntry: false, icon: icon.svg, i18n: { languages: [en, de] } }對照 Plugin API 中定義的PluginManifest接口types.ts各字段含義如下字段類型說明idstring插件唯一標識同時用于打包產物命名namestring插件顯示名稱manifestVersionnumber清單格式版本號當前為1versionstring插件版本號語義化版本minSupVersionstring兼容的最低 Super Productivity 版本descriptionstring插件簡介hooksHooks[]插件訂閱的宿主事件列表詳見下文事件鉤子permissionsstring[]插件申請的能力清單例如網絡請求需要聲明httpiFrameboolean為true時插件 UI 以 iframe 形式加載index.html被渲染為視圖sidePanelboolean為true時插件加載到右側面板而非路由視圖isSkipMenuEntryboolean是否跳過默認生成的菜單入口iconstring插件圖標 SVG 路徑相對插件根目錄i18n.languagesstring[]支持的界面語言代碼列表如[en, de]另外PluginManifest還支持allowedHosts精確聲明插件可訪問的域名白名單配合http權限生效未聲明則request默認拒絕、type: standard | issueProvider、nodeScriptConfig、uiKit、jsonSchemaCfg等高級字段開發者可根據需要擴展。四、開發、構建、打包與部署的完整命令鏈路樣板工程的package.json提供了完整的腳本集源碼scripts: { dev: vite, build: vite build, preview: vite preview, lint: eslint ., format: prettier --write ., typecheck: tsc --noEmit, package: node scripts/build-plugin.js, deploy: npm run build }4.1 開發npm run dev啟動 Vite 開發服務器進入 watch 模式源碼修改后插件會實時重建配合瀏覽器 HMR 可以快速迭代 UI。開發調試時可將 Super Productivity 的插件目錄指向構建產物進行即時驗證。4.2 構建npm run build調用vite build生成生產構建產物輸出到dist/目錄。關鍵點在于vite.config.ts源碼同時掛載了vite-plugin-solid和官方提供的superProductivityPlugin()import { defineConfig } from vite; import solidPlugin from vite-plugin-solid; import { superProductivityPlugin } from super-productivity/vite-plugin; export default defineConfig({ plugins: [solidPlugin(), superProductivityPlugin()], test: { environment: jsdom, globals: true, transformMode: { web: [/\.[jt]sx?$/] }, }, resolve: { conditions: [development, browser] }, });superProductivityPlugin()實現見 vite-plugin/src/index.ts在closeBundle鉤子中替你做完了三類收尾工作復制產物把src/manifest.json、src/assets/icon.svg復制到dist/并把i18n/目錄下的.json翻譯文件一并復制過去處理 HTML將 Vite 生成的index.js含 modulepreload 移除與index.css通過字符串替換內聯進index.htmlinlineAssets默認true可選自動同步配置copyTo選項后構建完成會把dist/遞歸復制到指定目錄便于構建即熱更新到正在運行的宿主應用。4.3 打包npm run package執行 scripts/build-plugin.js流程為先執行npm run build確保產物最新讀取src/manifest.json以${manifest.id}-v${manifest.version}.zip作為輸出文件名如boilerplate-solid-js-v1.0.0.zip使用archiverzlib壓縮級別 9把dist/整個目錄打成 ZIP輸出 ZIP 到插件工程根目錄并打印文件大小。npm run package4.4 帶 HTML UI 的插件必須使用內聯npm run deploy如果插件帶有index.htmlUI 組件、側邊面板等推薦使用 deploy 命令npm run deploy從倉庫實際腳本看deploy等價于npm run build內聯邏輯由super-productivity/vite-plugin在構建期完成。為什么必須內聯這是本項目插件機制的關鍵約束Super Productivity 以data:URL 的方式加載插件 HTML因此index.html無法引用任何外部文件。superProductivityPlugin默認開啟的inlineAssets會把所有 JS 與 CSS 直接嵌進 HTML確保插件在data:URL 環境下能完整運行。若你的插件包含 UI 卻跳過這一步會出現腳本、樣式全部失效的詭異問題。4.5 其他輔助命令npm run typechecktsc --noEmit靜態類型檢查排查構建錯誤的首選工具npm run lint/npm run formatESLint Prettier 代碼規范檢查與格式化npm run preview本地預覽構建產物。五、項目結構解析樣板工程的目錄結構如下src/ ├── assets/ # 靜態資源圖標、圖片 │ └── icon.svg # 插件圖標 ├── app/ # Solid.js 應用 │ ├── App.tsx # 主應用組件 │ └── App.css # 應用樣式 ├── index.html # 插件 UI 入口 ├── index.tsx # UI 初始化掛載 Solid 根組件 ├── plugin.ts # 插件邏輯與 API 集成 └── manifest.json # 插件元數據 scripts/ └── build-plugin.js # 插件打包腳本 dist/ # 構建產物已被 .gitignore 忽略 ├── assets/ ├── index.html # 已內聯所有 JS/CSS ├── index.js ├── plugin.js └── manifest.json各入口文件的職責src/index.tsx源碼找到#root節點并用render()掛載 Solid 根組件Appsrc/plugin.ts源碼運行在宿主渲染進程中的主腳本負責注冊 UI 入口、事件鉤子和消息處理器——這是插件的大腦src/app/App.tsx源碼Solid.js 編寫的插件界面通過window.parent.postMessage與plugin.ts通信dist/最終被打包分發的完整產物。六、Plugin API 實戰6.1 基礎接入插件 API 通過全局對象plugin暴露在plugin.ts中聲明即可獲得類型支持import { PluginInterface } from super-productivity/plugin-api; declare const plugin: PluginInterface;與樣板實際代碼對照當前版本從super-productivity/plugin-api導出的是PluginAPI類型見 plugin.tsplugin為宿主注入的全局實例。無論接口名如何演進全局對象 聲明式注冊的接入模式不變。PluginAPI接口types.ts還提供了cfg主題、平臺、應用版本等基礎配置、Hooks枚舉常量以及完整的日志對象plugin.loginfo/debug/warn/error等。6.2 UI 注冊header 按鈕、菜單項與快捷鍵文檔中給出的經典示例注冊三種入口// 注冊頭部按鈕 plugin.registerHeaderButton({ icon: rocket, tooltip: Open Plugin, action: () plugin.showIndexHtmlAsView(), }); // 注冊菜單項 plugin.registerMenuEntry({ label: My Plugin, icon: rocket, action: () plugin.showIndexHtmlAsView(), }); // 注冊鍵盤快捷鍵 plugin.registerShortcut({ keys: ctrlshiftm, label: Open My Plugin, action: () plugin.showIndexHtmlAsView(), });三個入口統一通過plugin.showIndexHtmlAsView()把插件 UI 渲染為應用視圖。樣板實際實現plugin.ts與文檔略有出入注意當前簽名為registerHeaderButton({ icon, label, onClick })registerMenuEntry({ label, icon, onClick })registerShortcut({ id, label, onExec })id用于后續unregisterShortcut精確移除。此外 API 還提供registerSidePanelButton側邊面板按鈕和registerWorkContextHeaderButton僅在特定工作上下文——項目/標簽/Today 下顯示的按鈕擴展 UI 場景很靈活。6.3 數據操作任務、項目與標簽// 獲取任務 const tasks await plugin.getTasks(); const archivedTasks await plugin.getArchivedTasks(); // 創建任務 const newTask await plugin.addTask({ title: New Task, projectId: project-id, }); // 更新任務 await plugin.updateTask(task-id, { title: Updated Title, isDone: true, }); // 獲取項目和標簽 const projects await plugin.getAllProjects(); const tags await plugin.getAllTags();從PluginAPI接口看數據操作能力遠不止于此types.ts任務getCurrentContextTasks()、getSelectedTask()、getFocusedTask()、getAppState()任務/項目/標簽/筆記/重復任務/計數器的全量只讀快照、deleteTask()、batchUpdateForProject()、reorderTasks()、selectTask()項目addProject()、updateProject()、deleteProject()級聯刪除項目內任務Inbox 不可刪標簽addTag()、updateTag()數據模型Tasktypes.ts包含timeEstimate、timeSpent、tagIds、subTaskIds、repeatCfgId、issueId等字段插件可直接讀寫Project與Tag類型同樣開放。6.4 事件鉤子訂閱宿主事件// 任務完成 plugin.on(taskComplete, (task) { console.log(Task completed:, task.title); }); // 任務更新 plugin.on(taskUpdate, (task) { console.log(Task updated:, task); }); // 上下文切換 plugin.on(contextChange, (context) { console.log(Context changed:, context); });與倉庫實現對照當前版本使用plugin.registerHook(PluginHooks.X, handler)注冊鉤子且鉤子名稱以PluginHooks枚舉為準types.ts。完整枚舉如下枚舉值字符串觸發時機TASK_CREATEDtaskCreated任務創建TASK_COMPLETEtaskComplete任務完成TASK_UPDATEtaskUpdate任務更新含changesTASK_DELETEtaskDelete任務刪除CURRENT_TASK_CHANGEcurrentTaskChange當前計時任務切換FINISH_DAYfinishDay結束一天LANGUAGE_CHANGElanguageChange界面語言切換PERSISTED_DATA_CHANGEDpersistedDataChanged持久化數據變化ACTIONaction自定義動作ANY_TASK_UPDATEanyTaskUpdate任意任務更新統一載荷PROJECT_LIST_UPDATEprojectListUpdate項目列表更新WORK_CONTEXT_CHANGEworkContextChange工作上下文切換樣板manifest.json中聲明的contextChange屬于文檔化舊寫法當前枚舉的標準值是workContextChange。聲明hooks時建議與PluginHooks枚舉保持一致避免鉤子不生效。每個鉤子的載荷類型TaskCompletePayload、TaskUpdatePayload、WorkContextChangePayload等也都在 types.ts 中有明確定義。樣板實際代碼示范了registerHook的完整用法包括任務完成時的成功通知、項目切換時的日志記錄以及語言切換時向 iframe 廣播languageChanged消息plugin.ts。6.5 插件與 UI 的通信postMessage 消息橋plugin.ts宿主進程側與 Solid.js UIiframe 內無法直接調用彼此函數兩者通過window.postMessage通信。宿主側注冊消息處理器// 在 plugin.ts 中 plugin.onMessage(myCommand, async (data) { // 處理來自 UI 的消息 return { result: success }; });UI 側發送帶messageId的消息并等待響應這是樣板 App.tsx 中sendMessage的完整實現const sendMessage async (type: string, payload?: any) { return new Promise((resolve) { const messageId Math.random().toString(36).substr(2, 9); const handler (event: MessageEvent) { if (event.data.messageId messageId) { window.removeEventListener(message, handler); resolve(event.data.response); } }; window.addEventListener(message, handler); window.parent.postMessage({ type, payload, messageId }, *); }); }; // 用法示例 const result await sendMessage(myCommand, { foo: bar });在樣板工程中這套協議被進一步規范化useTranslate工具useTranslate.ts以type: PLUGIN_MESSAGEmessageId發送監聽type: PLUGIN_MESSAGE_RESPONSE的響應。plugin.ts側則用plugin.onMessage處理各種message.type樣板已內置getStats、createTask、getTasks、getAllProjects、saveSettings、loadSettings、translate、getCurrentLanguage等命令plugin.ts。這套請求—響應橋接模式是所有帶 UI 的 Super Productivity 插件都要復用的核心通信范式。6.6 i18n 國際化樣板支持多語言插件界面在manifest.json的i18n.languages聲明語言如[en, de]在工程根目錄i18n/下按語言放置 JSON 文件如 en.json、de.json構建時由 vite 插件自動復制到dist/i18n/UI 中通過sendMessage(translate, { key, params })取值useTranslate鉤子還封裝了響應式翻譯能力t(APP.TITLE)并自動監聽languageChanged事件實時刷新界面文案宿主語言切換時plugin.ts通過PluginHooks.LANGUAGE_CHANGE鉤子向 iframe 廣播新的語言plugin.ts。七、定制你的插件7.1 樣式定制樣板已內置 CSS 自定義屬性theming、暗色模式與響應式設計。修改src/app/App.css即可調整外觀App 組件中還通過settings().theme切換data-theme屬性來應用明暗主題App.tsx與 Super Productivity 自身的主題體系一致。7.2 新增功能想做的事操作位置新增 UI 組件在src/app/下新建.tsx文件新增 API 端點/命令在src/plugin.ts中通過plugin.onMessage增加case分支新增事件鉤子在manifest.json的hooks聲明并在plugin.ts用registerHook處理新增權限在manifest.json的permissions中追加聲明八、最佳實踐類型安全始終使用super-productivity/plugin-api導出的 TypeScript 類型Task、Project、PluginAPI、PluginHooks等充分利用編譯期檢查錯誤處理所有異步操作包裹在 try-catch 中避免未捕獲異常影響宿主應用可參考 App.tsx 中onMount/refreshData的模式性能高效使用 Solid.js 的 signals 與 effects避免不必要的重渲染大數據量渲染優先使用For/Show等內置控制流安全絕不暴露敏感數據或危險操作發起網絡請求前在manifest.json中聲明http權限并精確配置allowedHosts白名單用戶體驗為異步操作提供 loading 狀態與錯誤反饋樣板已在App.tsx中示范isLoading信號 加載提示。九、將插件部署到 Super Productivity完整分發流程npm run build # 1. 構建若帶 HTML UI內聯資產已在此步完成 npm run package # 2. 打包生成 id-vversion.zip然后在 Super Productivity 中安裝打開 Super Productivity進入Settings → Plugins點擊Upload Plugin選擇生成的 ZIP 文件。安裝后插件即出現在菜單/頭部按鈕中可立即驗證功能。迭代開發時可結合 vite 插件的copyTo選項把構建產物自動同步到本地調試目錄實現改代碼—構建—熱更新的快速閉環。十、常見問題排查插件無法加載查看瀏覽器控制臺錯誤信息驗證manifest.json是否為合法 JSON確認minSupVersion與當前 Super Productivity 版本匹配樣板要求 8.0.0。API 調用失敗檢查manifest.json中是否聲明了所需permissions如網絡請求的http確認 Super Productivity 運行的是正確版本查看控制臺中的錯誤日志可使用plugin.log輸出調試信息。構建錯誤運行npm run typecheck檢查 TypeScript 類型錯誤確保所有依賴已安裝必要時清空node_modules后重新npm install。十一、進一步探索倉庫內的同類實現樣板工程不是孤立示例packages/plugin-dev/目錄下還有大量基于同一技術棧與 API 的真實插件是絕佳的進階學習素材automations完整的自動化規則插件觸發條件 執行動作 規則編輯器 UI展示了復雜插件如何組織src/core、src/app等模塊并自帶全套 vitest 單測*.spec.tsdoc-mode、todoist-import、sync-md覆蓋文檔模式、數據導入、Markdown 同步等真實業務場景plugin-api 類型定義插件 API 的唯一事實來源含詳盡的 JSDoc 注釋vite-plugin 實現理解構建與內聯細節的最佳入口。從復制boilerplate-solid-js、跑通npm run dev開始對照 插件開發文檔 與 開發指南如存在你就能快速進入 Super Productivity 插件開發的正軌。【免費下載鏈接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.項目地址: https://gitcode.com/GitHub_Trending/su/super-productivity創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考