ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Joplin 插件开发快速上手指南:基于 generator-joplin 从脚手架到发布全流程

Joplin 插件开发快速上手指南:基于 generator-joplin 从脚手架到发布全流程 Joplin 插件开发快速上手指南基于 generator-joplin 从脚手架到发布全流程【免费下载链接】joplinJoplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.项目地址: https://gitcode.com/GitHub_Trending/jo/joplinJoplin 是主打隐私保护的开源笔记应用其插件机制让开发者能够通过官方 API 扩展编辑器、内容脚本、Webview 面板等能力。本指南以 Joplin 仓库内置的 Yeoman 生成器generator-joplin对应生成器文档 packages/generator-joplin/generators/app/templates/GENERATOR_DOC.md为核心完整讲解环境安装 → 脚手架生成 → 项目结构 → 构建打包 → 版本管理 → 发布上架 → 框架升级 → 外部脚本编译的插件全生命周期并结合仓库源码逐层剖析npm run dist、plugin.config.json、webpack.config.js等关键文件的底层实现帮助你从零开始产出可分发、可发布的 Joplin 插件。环境准备与项目脚手架生成1. 安装 Yeoman 与 generator-joplin生成器依赖 Node.js 与 npm官方文档假定你已预先安装。先全局安装 Yeoman 与生成器本体npm install -g yo4.3.1 npm install -g generator-joplin生成器模板文档中给出的版本为yo4.3.1这是与当前生成器generator-joplin3.7.2见 packages/generator-joplin/package.json配套验证过的版本。生成器本身依赖yeoman-generator5.10.0并额外使用chalk、slugify、yosay三个库完成交互提示与包名处理。2. 生成一个新插件项目安装完成后在希望创建插件的目录下运行yo --node-package-manager npm joplin与早期写法yo joplin相比--node-package-manager npm显式指定包管理器为 npm避免 Yeoman 因环境差异推断出错。运行后会进入交互式问答流程。对照生成器源码 packages/generator-joplin/generators/app/index.js 中的prompting()方法需要依次填写以下信息提问字段含义示例pluginId插件唯一 ID必须是全局唯一值如反向域名或 UUIDcom.example.MyPluginpluginName插件名称将显示在 UI 中My TOC PluginpluginDescription插件描述Adds a table of contentspluginAuthor作者名称Your NamepluginRepositoryUrl源码仓库地址https://example.com/repopluginHomepageUrl插件主页地址https://example.compackageNamenpm 包名默认由插件名推导见下文其中packageName不会直接询问而是由生成器根据pluginName自动推导出默认值后再让你确认。推导逻辑位于 packages/generator-joplin/generators/app/utils.js 的packageNameFromPluginName()将*~.()!:[]等特殊字符替换为-用slugify(..., { lower: true })将非字母字符转为小写字母去掉首尾多余的-统一加上joplin-plugin-前缀截断到 214 字符以内npm 包名长度上限。例如插件名My TOC会被推导为joplin-plugin-my-toc。这一步很重要包名是否符合joplin-plugin-前缀直接决定插件能否被官方插件仓库收录详见下文发布插件小节。生成器在writing()阶段会通过copyTpl把所有模板文件渲染到目标目录其中.gitignore与package.json因 npm 的历史 bugnpm/npm#3763在模板中命名为.gitignore_TEMPLATE、package_TEMPLATE.json安装时再重命名还原。生成后的项目结构解析新生成的项目中最关键的两个文件是src/index.ts插件源码入口。生成器给出的默认实现只有几行——通过api别名导入 Joplin 插件 API并注册一个在启动时打印日志的插件import joplin from api; joplin.plugins.register({ onStart: async function() { // eslint-disable-next-line no-console console.info(Hello world. Test plugin started!); }, });src/manifest.json插件清单文件声明插件 ID、版本、名称、描述、作者、主页、仓库地址、分类与截图等元信息。生成器模板packages/generator-joplin/generators/app/templates/src/manifest.json默认结构如下{ manifest_version: 1, id: com.example.MyPlugin, app_min_version: 3.7, version: 1.0.0, name: My TOC Plugin, description: Adds a table of contents, author: Your Name, homepage_url: https://example.com, repository_url: https://example.com/repo, keywords: [], categories: [], screenshots: [], icons: {}, promo_tile: {} }其中id即前面填写的pluginIdversion与package.json中的版本号保持一致updateVersion脚本负责同步见后文。app_min_version为生成器当前支持的 Joplin 最低版本 3.7。模板同时会复制整套api/目录Joplin.d.ts、JoplinViews.d.ts、JoplinSettings.d.ts等 TypeScript 类型声明覆盖编辑器、视图面板、菜单、工具栏、对话框、数据访问等全部 API 面以及script/publish/发布辅助脚本。此外plugin.config.json值得注意——它默认只包含一个空的extraScripts数组用于声明需要额外编译的外部脚本内容脚本、Webview 脚本详见外部脚本文件一节。构建插件npm run dist的完整工作流1. 三条 Webpack 配置链生成器模板的package.jsonpackages/generator-joplin/generators/app/templates/package_TEMPLATE.json把构建命令定义为一串依次执行的三阶段 Webpack 调用dist: webpack --env joplin-plugin-configbuildMain webpack --env joplin-plugin-configbuildExtraScripts webpack --env joplin-plugin-configcreateArchive之所以要拆成三次串行调用而不是并行原因写在 webpack.config.js 的注释里各阶段存在先后依赖Webpack 并行运行会破坏顺序因此通过--env joplin-plugin-config参数切换配置。具体三个阶段是buildMain编译主入口src/index.ts并通过copy-webpack-plugin把src/下其余资源非.ts/.tsx文件原样复制到dist/。此阶段开始时还会清空dist/与publish/目录并重建publish/。buildExtraScripts按plugin.config.json中的extraScripts列表逐个编译外部脚本编译产物会覆盖第一阶段复制过来的同名 JS 文件——这是有意为之的设计不需要编译的 JS 直接复制需要编译的则被替换为编译结果。createArchive以dist/index.js为占位入口触发onBuildCompleted钩子用tar把整个dist/打成 JPL 压缩包并生成配套的插件信息 JSON。构建完成后你会得到两类产物dist/编译后的代码目录publish/插件ID.jplJPL 插件压缩包可直接在 Joplin 中安装分发以及publish/插件ID.json插件信息文件。2. JPL 打包与校验的底层逻辑打包与校验逻辑全部集中在 webpack.config.js 中createPluginArchive()用glob枚举dist/下所有文件dist为空会直接报错然后通过tar.create以portable: true、strict: true模式打成.jplcreatePluginInfo()会读取manifest.json追加_publish_hashJPL 文件的 sha256 哈希格式为sha256:...与_publish_commit当前 git 分支与 commit若不在 git 仓库中则为空字符串后写入publish/ID.jsonvalidatePackageJson()对package.json做发布前校验包名必须以joplin-plugin-开头、keywords 必须包含joplin-plugin同时警告不要使用postinstall脚本建议改用prepare确保发布前一定执行构建readManifest()校验 manifest 中id必须存在categories不得重复且必须属于allPossibleCategoriesappearance、developer tools、productivity、themes、integrations、viewer、search、tags、editor、files、personal knowledge management 之一且必须为小写screenshots的src类型必须属于 jpg/jpeg/png/gif/webp 且本地截图文件不超过 1MB。3. 关于 TypeScript 与 Webpack 配置模板项目默认使用 TypeScriptts-loader处理.ts/.tsx但文档明确说明你可以改配置改用纯 JavaScript。Webpack 配置中还有一个细节由于插件运行在 Electron 的 Node 环境中模板把 Node 内建模块的fallback全部设为false避免 Webpack 5 因不再默认 polyfill 而弹出警告。版本号管理npm run updateVersion插件开发中经常需要递增版本号。直接手工同步package.json与manifest.json容易出错因此生成器内置了updateVersion脚本updateVersion: webpack --env joplin-plugin-configupdateVersion其实现updateVersion()同样在 webpack.config.js 中会把package.json与manifest.json中的版本号patch 位 1如 1.0.3 → 1.0.4保持两者同步若发现两者版本不一致会打印警告提示手工对齐。发布新版本前先跑这个命令可以避免插件版本号没变导致插件仓库不更新的常见问题。发布插件到 Joplin 插件仓库1. 通过 npm publish 发布构建完成后把插件发布到 npmjs.comnpm publish之后 Joplin 的插件仓库脚本会自动拾取你的插件并收录前提是包满足以下全部条件package.json的name以joplin-plugin-开头例如joplin-plugin-tocpackage.json的keywords包含joplin-pluginpublish/目录下同时存在.jpl与.json两个文件它们由npm run dist自动生成。正常情况下生成器已自动设置好包名与 keywords并把正确的文件放进publish/。如果插件迟迟没有出现在插件仓库中优先复查上述三个条件——这是文档特别强调的排错路径对应validatePackageJson()中的警告逻辑。2. 生成器自带的 submit 一键发布流程除了手工npm publish新版生成器还随模板附赠了一套script/publish/自动化发布脚本通过npm run submit触发。入口 script/publish/index.ts 将发布拆成四个阶段verifyBuild校验构建产物与元数据verifyGitState校验 git 状态确保基于干净的提交发布authenticateGitHub OAuth 设备流认证依赖octokit/auth-oauth-devicesubmitPayload向 Joplin 插件仓库提交 payload。整套流程对版本号同步、构建产物存在性、git 干净度做了前置把关适合希望把发布固化为标准流水线的开发者。升级插件框架npm run updateJoplin 插件 API 会随版本演进生成器提供了框架升级命令update: npm install -g generator-joplin yo joplin --node-package-manager npm --update --force执行前它会先全局更新generator-joplin然后以--update模式重新运行生成器。对照 generators/app/index.js 的writing()实现更新模式下的行为要点如下不会动你的业务代码src/index.ts、src/manifest.json、README.md在更新时被跳过保证已有插件逻辑不受影响package.json 走智能合并调用mergePackageKey()见 utils.js——以你现有的package.json为基础框架新出现的键会被补进来keywords强制确保包含joplin-plugindevDependencies一律以框架版本为准覆盖scripts中的dist、prepare、update三个键也强制采用框架版本否则插件可能构建失败其余键尽量保留你的自定义值.gitignore/.npmignore 走行级合并mergeIgnoreFile()将框架模板与你现有文件的规则按行去重合并而不是整体覆盖plugin.config.json 保留原内容更新时不改动避免丢失你配置的extraScripts其余配置文件如 webpack.config.js会被覆盖。正因为webpack.config.js每次升级都会被覆盖文档给出的最佳实践是不要直接改 webpack.config.js而是另建一个独立 JS 文件在 webpack.config.js 中用一行require引入。这样升级后只需恢复那一行引入语句你的自定义配置就能原样回归。外部脚本文件内容脚本与 Webview 脚本的编译1. 何时需要额外编译默认情况下Webpack 只编译src/index.ts及其 import 的模块其余文件只是被原样复制进插件包。这对简单插件已经够用但遇到以下两类脚本时就必须编译TypeScript 脚本.ts无法直接被 Joplin 执行必须编译为 JavaScript依赖了 package.json 中第三方模块的脚本无论 JS 还是 TS都必须编译把依赖打包进 JPL 文件否则运行时找不到模块。典型场景就是文档中提到的content scripts内容脚本用于在笔记编辑器内注入自定义行为与webview scripts面板 Webview 中运行的脚本。2. 通过 extraScripts 声明并引用要让某个外部脚本参与编译把它加入plugin.config.json的extraScripts数组路径相对于src/目录。例如源码位于src/webviews/index.ts则配置为{ extraScripts: [webviews/index.ts] }编译后脚本永远以.js扩展名输出类型后缀会被剥离上例最终产物为插件包内的webviews/index.js——引用脚本时例如通过joplin.views.panels.addScript()必须使用这个编译后的路径而不是原始.ts路径。底层实现见webpack.config.js的resolveExtraScriptPath()与buildExtraScriptConfigs()每个 extra script 都会生成一个独立的 Webpack 配置入口为./src/name输出文件名去掉扩展名后补.js并以commonjs库模式导出默认值。同时模板还为 extra script 预置了一组 CodeMirror 相关库codemirror/*、lezer/*的externals声明——如果你的内容脚本通过require()或joplin.require()引用这些库它们不会被重复打进 JPL而是直接复用 Joplin 运行时自带的版本。总结插件开发的完整命令流阶段命令作用初始化yo --node-package-manager npm joplin交互式生成插件项目开发编辑src/index.ts与src/manifest.json编写插件逻辑与元信息构建npm run dist编译代码、打出dist/与publish/*.jpl、publish/*.json升级版本npm run updateVersion同步递增 package.json 与 manifest.json 的 patch 版本发布npm publish或npm run submit发布到 npm等待官方仓库自动收录框架升级npm run update合并更新框架文件保留业务代码围绕这条流程本文涉及的模板与实现均可在仓库中继续深挖生成器模板目录、生成器交互与文件写入逻辑、包名推导与合并工具、Webpack 构建配置 以及 生成器自身说明。从脚手架到发布generator-joplin把模板生成、构建打包、校验、发布、升级各环节串成了一条自动化流水线开发者只需专注于src/下的业务代码即可。【免费下载链接】joplinJoplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.项目地址: https://gitcode.com/GitHub_Trending/jo/joplin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表