obsidian-plugin
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseobsidian-plugin — Obsidian Plugin Development Skill
obsidian-plugin — Obsidian插件开发技能
Keyword:·obsidian plugin·create obsidian plugin·obsidian eslintobsidian submissionBuild high-quality Obsidian plugins that pass community review on first attempt. Covers all 27 rules fromv0.1.9, boilerplate generation, vault API patterns, accessibility requirements, and submission validation.eslint-plugin-obsidianmd
关键词:·obsidian plugin·create obsidian plugin·obsidian eslintobsidian submission打造首次提交即可通过社区审核的高质量Obsidian插件,覆盖v0.1.9的全部27条规则、样板代码生成、vault API使用模式、可访问性要求以及提交校验功能。eslint-plugin-obsidianmd
When to use this skill
什么时候使用这个技能
- Generate a new Obsidian plugin project with clean boilerplate (no sample code bloat)
- Review and fix ESLint violations from
eslint-plugin-obsidianmd - Prepare a plugin for Obsidian community directory submission
- Apply memory-safe lifecycle patterns (, no view reference storage)
registerEvent - Implement proper type safety (no unsafe casts, no
as TFile)any - Enforce accessibility requirements (keyboard navigation, ARIA labels, focus management)
- Apply Obsidian CSS variables for theme-compatible styling
- Validate plugin metadata (manifest.json, plugin ID/name/description rules)
- 生成无冗余示例代码的干净Obsidian插件新项目样板
- 审查并修复抛出的ESLint违规问题
eslint-plugin-obsidianmd - 准备提交Obsidian插件到社区目录
- 应用内存安全的生命周期模式(,不存储视图引用)
registerEvent - 实现规范的类型安全(无不安全的类型转换,不使用
as TFile)any - 落实可访问性要求(键盘导航、ARIA标签、焦点管理)
- 使用Obsidian CSS变量实现兼容主题的样式
- 校验插件元数据(manifest.json、插件ID/名称/描述规则)
Instructions
使用说明
Step 1: Generate a new plugin project
步骤1:生成新的插件项目
bash
undefinedbash
undefinedInteractive boilerplate generator — validates metadata against submission rules
Interactive boilerplate generator — validates metadata against submission rules
node scripts/create-plugin.js
node scripts/create-plugin.js
Or use npx directly from the source repo
Or use npx directly from the source repo
npx github:gapmiss/obsidian-plugin-skill create-plugin
The generator produces:
- `src/main.ts` — Plugin class with settings integration
- `src/settings.ts` — Settings interface and PluginSettingTab
- `manifest.json` — Validated plugin metadata
- `styles.css` — CSS scaffold with Obsidian variables comment
- `tsconfig.json`, `package.json`, `esbuild.config.mjs` — Build toolchain
- `version-bump.mjs`, `versions.json` — Version management
- `LICENSE` — MIT with auto-populated year/authornpx github:gapmiss/obsidian-plugin-skill create-plugin
生成器会输出以下内容:
- `src/main.ts` — 集成了设置功能的插件类
- `src/settings.ts` — 设置接口与PluginSettingTab
- `manifest.json` — 经过校验的插件元数据
- `styles.css` — 带有Obsidian变量注释的CSS脚手架
- `tsconfig.json`、`package.json`、`esbuild.config.mjs` — 构建工具链配置
- `version-bump.mjs`、`versions.json` — 版本管理文件
- `LICENSE` — 自动填充年份/作者的MIT许可证Step 2: Install ESLint validation
步骤2:安装ESLint校验工具
bash
npm install --save-dev eslint eslint-plugin-obsidianmdjson
// eslint.config.mjs
import pluginObsidianmd from "eslint-plugin-obsidianmd";
export default [
pluginObsidianmd.configs.recommended,
// For locale string checking:
// pluginObsidianmd.configs.recommendedWithLocalesEn,
];Run validation:
bash
npx eslint src/
npx eslint src/ --fix # auto-fix where possiblebash
npm install --save-dev eslint eslint-plugin-obsidianmdjson
// eslint.config.mjs
import pluginObsidianmd from "eslint-plugin-obsidianmd";
export default [
pluginObsidianmd.configs.recommended,
// For locale string checking:
// pluginObsidianmd.configs.recommendedWithLocalesEn,
];运行校验:
bash
npx eslint src/
npx eslint src/ --fix # 可自动修复的问题会自动修复Step 3: Follow the submission validation workflow
步骤3:遵循提交流程校验
- Run to set up the development environment
bash scripts/install.sh - Validate plugin ID and name against naming rules (see below)
- Run ESLint — all 27 rules must pass
- Complete the Code Review Checklist (see References)
- Submit PR to obsidianmd/obsidian-releases
- 运行搭建开发环境
bash scripts/install.sh - 对照命名规则校验插件ID和名称(见下文)
- 运行ESLint — 必须全部通过27条规则校验
- 完成代码审核清单(见参考资料)
- 提交PR到obsidianmd/obsidian-releases
Plugin Naming Rules
插件命名规则
| Field | Rule |
|---|---|
| Plugin ID | Lowercase, alphanumeric + dashes/underscores; no "obsidian"; no "plugin" suffix |
| Plugin Name | No "Obsidian" word; no "Plugin" suffix; no "Obsi" prefix or "dian" suffix |
| Description | No "Obsidian" word; no "This plugin"; must end with |
bash
undefined| 字段 | 规则 |
|---|---|
| 插件ID | 小写,仅允许字母数字+短横线/下划线;不能包含"obsidian";不能带"plugin"后缀 |
| 插件名称 | 不能包含"Obsidian"字样;不能带"Plugin"后缀;不能使用"Obsi"前缀或"dian"后缀 |
| 插件描述 | 不能包含"Obsidian"字样;不能以"This plugin"开头;必须以 |
bash
undefinedValidate your manifest.json
校验你的manifest.json
node scripts/create-plugin.js --validate-only
---node scripts/create-plugin.js --validate-only
---ESLint Rules Summary (27 rules)
ESLint规则汇总(27条规则)
Submission & Naming
提交与命名
| Rule | Auto-fix | Description |
|---|---|---|
| No | Plugin ID must not contain "obsidian" |
| No | Plugin ID must not end with "-plugin" |
| No | Plugin name must not contain "Obsidian" |
| No | Plugin name must not end with "Plugin" |
| No | Description format validation |
| 规则 | 可自动修复 | 描述 |
|---|---|---|
| 否 | 插件ID不能包含"obsidian" |
| 否 | 插件ID不能以"-plugin"结尾 |
| 否 | 插件名称不能包含"Obsidian" |
| 否 | 插件名称不能以"Plugin"结尾 |
| 否 | 描述格式校验 |
Memory & Lifecycle
内存与生命周期
| Rule | Auto-fix | Description |
|---|---|---|
| No | Use |
| No | Never store direct view references (causes memory leaks) |
| 规则 | 可自动修复 | 描述 |
|---|---|---|
| 否 | 使用 |
| 否 | 禁止直接存储视图引用(会导致内存泄漏) |
Type Safety
类型安全
| Rule | Auto-fix | Description |
|---|---|---|
| No | Avoid |
| 规则 | 可自动修复 | 描述 |
|---|---|---|
| 否 | 避免使用 |
UI/UX (sentence-case rules — mostly auto-fixable)
UI/UX(句首大写规则 — 大多支持自动修复)
| Rule | Auto-fix | Description |
|---|---|---|
| Yes | All UI text in sentence case |
| No | Commands must not repeat plugin name |
| No | Commands must not include the word "command" |
| No | Do not define default hotkeys |
| No | Settings UI: use |
| 规则 | 可自动修复 | 描述 |
|---|---|---|
| 是 | 所有UI文本使用句首大写格式 |
| 否 | 命令名称不能重复插件名称 |
| 否 | 命令名称不能包含"command"字样 |
| 否 | 不要定义默认快捷键 |
| 否 | 设置界面请使用 |
API Best Practices
API最佳实践
| Rule | Auto-fix | Description |
|---|---|---|
| No | Use |
| No | Use |
| No | Remove |
| No | Use |
| 规则 | 可自动修复 | 描述 |
|---|---|---|
| 否 | 使用 |
| 否 | 使用 |
| 否 | 提交前请移除 |
| 否 | 建议功能请使用 |
Styling
样式规范
| Rule | Auto-fix | Description |
|---|---|---|
| No | Use CSS classes; no inline |
| No | Use Obsidian CSS variables, not hardcoded colors |
| No | Scope all CSS to plugin ID selector |
| 规则 | 可自动修复 | 描述 |
|---|---|---|
| 否 | 使用CSS类,不要使用行内 |
| 否 | 使用Obsidian CSS变量,不要写死颜色值 |
| 否 | 所有CSS样式作用域限定到插件ID选择器 |
Accessibility (MANDATORY)
可访问性(强制要求)
| Rule | Auto-fix | Description |
|---|---|---|
| No | Icon buttons must have |
| No | All interactions must be keyboard accessible |
| No | Use |
| 规则 | 可自动修复 | 描述 |
|---|---|---|
| 否 | 图标按钮必须设置 |
| 否 | 所有交互操作必须支持键盘访问 |
| 否 | 使用 |
Key Code Patterns
核心代码模式
Memory-safe event registration
内存安全的事件注册
typescript
// ✅ Correct — auto-cleaned on plugin unload
this.registerEvent(
this.app.vault.on('create', (file) => this.handleCreate(file))
);
// ❌ Wrong — leaks memory
this.app.vault.on('create', (file) => this.handleCreate(file));typescript
// ✅ 正确写法 — 插件卸载时自动清理
this.registerEvent(
this.app.vault.on('create', (file) => this.handleCreate(file))
);
// ❌ 错误写法 — 会造成内存泄漏
this.app.vault.on('create', (file) => this.handleCreate(file));Type-safe file access
类型安全的文件访问
typescript
// ✅ Correct — instanceof narrowing
const file = this.app.workspace.getActiveFile();
if (file instanceof TFile) {
await this.app.vault.read(file);
}
// ❌ Wrong — unsafe cast
const file = this.app.workspace.getActiveFile() as TFile;typescript
// ✅ 正确写法 — instanceof类型收窄
const file = this.app.workspace.getActiveFile();
if (file instanceof TFile) {
await this.app.vault.read(file);
}
// ❌ 错误写法 — 不安全的类型转换
const file = this.app.workspace.getActiveFile() as TFile;Accessibility — ARIA on icon buttons
可访问性 — 图标按钮的ARIA设置
typescript
// ✅ Correct
const btn = containerEl.createEl('button', { cls: 'clickable-icon' });
btn.setAttribute('aria-label', 'Delete note');
setIcon(btn, 'trash');
// ❌ Wrong — no aria-label
const btn = containerEl.createEl('button', { cls: 'clickable-icon' });
setIcon(btn, 'trash');typescript
// ✅ 正确写法
const btn = containerEl.createEl('button', { cls: 'clickable-icon' });
btn.setAttribute('aria-label', 'Delete note');
setIcon(btn, 'trash');
// ❌ 错误写法 — 未设置aria-label
const btn = containerEl.createEl('button', { cls: 'clickable-icon' });
setIcon(btn, 'trash');CSS with Obsidian variables
使用Obsidian变量的CSS样式
css
/* ✅ Correct — theme-compatible */
.my-plugin-button {
background-color: var(--interactive-accent);
color: var(--text-on-accent);
border-radius: var(--radius-m);
}
/* ❌ Wrong — hardcoded colors */
.my-plugin-button {
background-color: #7c3aed;
color: white;
}css
/* ✅ 正确写法 — 兼容不同主题 */
.my-plugin-button {
background-color: var(--interactive-accent);
color: var(--text-on-accent);
border-radius: var(--radius-m);
}
/* ❌ 错误写法 — 写死颜色值 */
.my-plugin-button {
background-color: #7c3aed;
color: white;
}Quick Reference
快速参考
| Task | Command |
|---|---|
| Generate boilerplate | |
| Install ESLint | |
| Run ESLint | |
| Auto-fix ESLint | |
| Build plugin | |
| Dev watch mode | |
| Bump version | |
| 任务 | 命令 |
|---|---|
| 生成样板代码 | |
| 安装ESLint | |
| 运行ESLint校验 | |
| 自动修复ESLint问题 | |
| 构建插件 | |
| 开发监听模式 | |
| 升级版本 | |
References
参考资料
- Accessibility Guide — Keyboard nav, ARIA, focus management (MANDATORY)
- Code Quality Guide — Security, platform compat, API usage
- CSS Styling Guide — Obsidian variables, scoped styles, dark/light mode
- File Operations Guide — Vault API, editor vs vault, atomic ops
- Memory Management Guide — registerEvent, lifecycle patterns
- Submission Guide — Repository structure, naming, submission process
- Type Safety Guide — instanceof narrowing, no , const/let
any - UI/UX Guide — Sentence case, commands, settings structure
- eslint-plugin-obsidianmd — Official ESLint rules
- Obsidian Plugin Developer Docs
- Source Skill Repository — MIT License
- 可访问性指南 — 键盘导航、ARIA、焦点管理(强制要求)
- 代码质量指南 — 安全性、平台兼容性、API使用
- CSS样式指南 — Obsidian变量、样式作用域、明暗模式适配
- 文件操作指南 — Vault API、编辑器与vault差异、原子操作
- 内存管理指南 — registerEvent、生命周期模式
- 提交指南 — 仓库结构、命名规范、提交流程
- 类型安全指南 — instanceof类型收窄、禁用、const/let使用规范
any - UI/UX指南 — 句首大写、命令规范、设置结构
- eslint-plugin-obsidianmd — 官方ESLint规则
- Obsidian插件开发者文档
- 技能源仓库 — MIT许可证