capacitor-plugin-development

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Capacitor Plugin Development

Capacitor 插件开发

Create and maintain Capacitor plugins — scaffolding, native API bridging (iOS/Android), type definitions, testing, and publishing.
创建并维护Capacitor插件 —— 脚手架搭建、原生API桥接(iOS/Android)、类型定义、测试与发布。

Prerequisites

前置要求

RequirementVersion
Node.jsLTS (18+)
npm6+
Xcode15+ (for iOS)
Android StudioHedgehog 2023.1.1+ (for Android)
Capacitor6+
要求版本
Node.jsLTS (18+)
npm6+
Xcode15+(用于iOS开发)
Android StudioHedgehog 2023.1.1+(用于Android开发)
Capacitor6+

Agent Behavior

Agent 行为规范

  • Auto-detect before asking. Read
    package.json
    , inspect the directory structure, and infer the plugin's current state before prompting the user.
  • Guide step-by-step. Walk the user through one phase at a time. Do not present multiple unrelated tasks simultaneously.
  • Skip what exists. If the plugin is already scaffolded, skip scaffolding. If the iOS implementation already exists, skip to the next platform.
  • Ask which platforms to target. If the user does not specify, implement all three (iOS, Android, Web).
  • 先自动检测再询问:在提示用户之前,先读取
    package.json
    、检查目录结构并推断插件的当前状态。
  • 分步引导:一次引导用户完成一个阶段的任务,不要同时呈现多个无关任务。
  • 跳过已完成部分:如果插件已完成脚手架搭建,则跳过该步骤;如果iOS实现已存在,则直接进入下一平台的开发步骤。
  • 询问目标平台:如果用户未指定,则默认实现三个平台(iOS、Android、Web)。

Procedures

开发流程

Step 1: Determine the Task

步骤1:确定任务

Ask the user what they want to do. Common tasks:
  1. Create a new plugin from scratch — proceed to Step 2.
  2. Add a new method to an existing plugin — skip to Step 5.
  3. Add a new platform implementation — skip to the relevant platform step (Step 6, 7, or 8).
  4. Set up plugin configuration — read
    references/plugin-configuration.md
    and apply.
  5. Set up plugin hooks — read
    references/testing-and-workflow.md
    (Plugin Hooks section) and apply.
  6. Publish the plugin — skip to Step 10.
If the user's intent is clear from context, skip this question and proceed directly.
询问用户想要执行的操作,常见任务包括:
  1. 从头创建新插件 —— 进入步骤2。
  2. 为现有插件添加新方法 —— 跳至步骤5。
  3. 添加新平台实现 —— 跳至对应平台的步骤(步骤6、7或8)。
  4. 配置插件参数 —— 阅读
    references/plugin-configuration.md
    并执行配置。
  5. 设置插件钩子 —— 阅读
    references/testing-and-workflow.md
    (插件钩子章节)并执行设置。
  6. 发布插件 —— 跳至步骤10。
如果从上下文可明确用户意图,则跳过此问题直接执行对应步骤。

Step 2: Scaffold the Plugin

步骤2:搭建插件脚手架

Read
references/scaffolding.md
and guide the user through generating a new plugin project using the Capacitor plugin generator.
Gather the following from the user (or infer from context):
  • Plugin npm package name
  • Android package ID
  • Plugin class name
  • Repository URL
  • License
  • Description
Run the generator and verify the scaffold with
npm run verify
.
阅读
references/scaffolding.md
并引导用户使用Capacitor插件生成器创建新插件项目。
从用户处收集以下信息(或从上下文推断):
  • 插件的npm包名称
  • Android包ID
  • 插件类名称
  • 仓库URL
  • 许可证
  • 描述信息
运行生成器并通过
npm run verify
验证脚手架是否正确。

Step 3: Design the TypeScript API

步骤3:设计TypeScript API

Read
references/designing-api.md
and guide the user through defining the plugin interface.
  1. Ask the user what methods the plugin should expose and what data each method accepts/returns.
  2. Define the plugin interface and all supporting types in
    src/definitions.ts
    .
  3. Register the plugin in
    src/index.ts
    using
    registerPlugin()
    .
Ensure:
  • Every method and property has JSDoc comments with
    @since
    tags.
  • Options and result types are defined as separate interfaces.
  • String union types are used instead of TypeScript enums.
阅读
references/designing-api.md
并引导用户定义插件接口。
  1. 询问用户插件需要暴露哪些方法,以及每个方法接收和返回的数据类型。
  2. src/definitions.ts
    中定义插件接口及所有配套类型。
  3. src/index.ts
    中使用
    registerPlugin()
    注册插件。
需确保:
  • 每个方法和属性都带有包含
    @since
    标签的JSDoc注释。
  • 选项和结果类型定义为独立接口。
  • 使用字符串联合类型替代TypeScript枚举。

Step 4: Implement the Web Layer

步骤4:实现Web层

Read
references/web-guide.md
and implement the web layer in
src/web.ts
.
  1. Extend
    WebPlugin
    and implement the plugin interface.
  2. For methods that use Web APIs, implement the browser-based logic.
  3. For methods that have no web equivalent, throw
    this.unimplemented()
    .
  4. For methods that require a web API not available in all browsers, check for the API's existence and throw
    this.unavailable()
    if missing.
After implementation, build and verify:
bash
npm run build
npm run verify:web
阅读
references/web-guide.md
并在
src/web.ts
中实现Web层。
  1. 继承
    WebPlugin
    并实现插件接口。
  2. 对于使用Web API的方法,实现基于浏览器的逻辑。
  3. 对于无Web端等效实现的方法,抛出
    this.unimplemented()
  4. 对于需要特定Web API(并非所有浏览器都支持)的方法,检查API是否存在,若缺失则抛出
    this.unavailable()
实现完成后,构建并验证:
bash
npm run build
npm run verify:web

Step 5: Define Method Signatures Across Platforms

步骤5:跨平台定义方法签名

Before implementing native code, determine the method types for each plugin method:
TypeTypeScriptiOSAndroid
Returns a value
Promise<T>
CAPPluginReturnPromise
@PluginMethod()
Returns void
Promise<void>
CAPPluginReturnNone
@PluginMethod(returnType = PluginMethod.RETURN_NONE)
Callback (repeated)
Promise<string>
CAPPluginReturnCallback
@PluginMethod(returnType = PluginMethod.RETURN_CALLBACK)
Most methods use the "returns a value" type. Use "callback" only for continuous data streams (e.g., geolocation watching).
在实现原生代码前,确定每个插件方法的类型:
类型TypeScriptiOSAndroid
返回值
Promise<T>
CAPPluginReturnPromise
@PluginMethod()
返回空值
Promise<void>
CAPPluginReturnNone
@PluginMethod(returnType = PluginMethod.RETURN_NONE)
回调(重复调用)
Promise<string>
CAPPluginReturnCallback
@PluginMethod(returnType = PluginMethod.RETURN_CALLBACK)
大多数方法使用“返回值”类型。仅在处理持续数据流(如地理位置监控)时使用“回调”类型。

Step 6: Implement the iOS Plugin

步骤6:实现iOS插件

Read
references/ios-guide.md
and implement the iOS layer.
  1. Create or update the implementation class (e.g.,
    ios/Sources/<ClassName>Plugin/Example.swift
    ) with the platform logic. Extend
    NSObject
    and mark methods with
    @objc
    .
  2. Create or update the plugin class (e.g.,
    ios/Sources/<ClassName>Plugin/ExamplePlugin.swift
    ):
    • Extend
      CAPPlugin
      and conform to
      CAPBridgedPlugin
      .
    • Set
      identifier
      ,
      jsName
      , and
      pluginMethods
      properties.
    • Implement each
      @objc func
      method, reading data from
      CAPPluginCall
      and calling
      resolve()
      ,
      reject()
      ,
      unavailable()
      , or
      unimplemented()
      .
  3. If the plugin requires third-party iOS dependencies, add them to the
    .podspec
    file.
  4. If the plugin requires permissions, implement
    checkPermissions()
    and
    requestPermissions()
    , and document the required
    Info.plist
    keys.
After implementation, verify:
bash
npm run verify:ios
阅读
references/ios-guide.md
并实现iOS层。
  1. 创建或更新实现类(例如
    ios/Sources/<ClassName>Plugin/Example.swift
    ),编写平台逻辑。继承
    NSObject
    并为方法添加
    @objc
    标记。
  2. 创建或更新插件类(例如
    ios/Sources/<ClassName>Plugin/ExamplePlugin.swift
    ):
    • 继承
      CAPPlugin
      并遵循
      CAPBridgedPlugin
      协议。
    • 设置
      identifier
      jsName
      pluginMethods
      属性。
    • 实现每个
      @objc func
      方法,从
      CAPPluginCall
      读取数据并调用
      resolve()
      reject()
      unavailable()
      unimplemented()
  3. 如果插件依赖第三方iOS库,将其添加至
    .podspec
    文件。
  4. 如果插件需要权限,实现
    checkPermissions()
    requestPermissions()
    方法,并记录所需的
    Info.plist
    键。
实现完成后,验证:
bash
npm run verify:ios

Step 7: Implement the Android Plugin

步骤7:实现Android插件

Read
references/android-guide.md
and implement the Android layer.
  1. Create or update the implementation class (e.g.,
    android/src/main/java/<package-path>/Example.java
    ) with the platform logic.
  2. Create or update the plugin class (e.g.,
    android/src/main/java/<package-path>/ExamplePlugin.java
    ):
    • Extend
      Plugin
      and add
      @CapacitorPlugin(name = "<JSName>")
      .
    • Implement each
      @PluginMethod
      method, reading data from
      PluginCall
      and calling
      resolve()
      ,
      reject()
      ,
      unavailable()
      , or
      unimplemented()
      .
  3. If the plugin requires third-party Android dependencies, add them to
    android/build.gradle
    .
  4. If the plugin requires permissions:
    • Define permission aliases in the
      @CapacitorPlugin
      annotation.
    • Implement
      checkPermissions()
      and
      requestPermissions()
      .
    • Document which permissions the app developer must add to
      AndroidManifest.xml
      .
After implementation, verify:
bash
npm run verify:android
阅读
references/android-guide.md
并实现Android层。
  1. 创建或更新实现类(例如
    android/src/main/java/<package-path>/Example.java
    ),编写平台逻辑。
  2. 创建或更新插件类(例如
    android/src/main/java/<package-path>/ExamplePlugin.java
    ):
    • 继承
      Plugin
      并添加
      @CapacitorPlugin(name = "<JSName>")
      注解。
    • 实现每个
      @PluginMethod
      方法,从
      PluginCall
      读取数据并调用
      resolve()
      reject()
      unavailable()
      unimplemented()
  3. 如果插件依赖第三方Android库,将其添加至
    android/build.gradle
  4. 如果插件需要权限:
    • @CapacitorPlugin
      注解中定义权限别名。
    • 实现
      checkPermissions()
      requestPermissions()
      方法。
    • 记录应用开发者需添加至
      AndroidManifest.xml
      的权限。
实现完成后,验证:
bash
npm run verify:android

Step 8: Add Events (If Needed)

步骤8:添加事件(如有需要)

If the plugin emits events to JavaScript:
  1. TypeScript: Add
    addListener()
    and
    removeAllListeners()
    methods to the plugin interface in
    src/definitions.ts
    . Define an event interface for each event type.
  2. Web: Call
    this.notifyListeners('eventName', data)
    when the event occurs.
  3. iOS: Call
    self.notifyListeners("eventName", data: [...])
    when the event occurs. Register observers in
    load()
    if listening to system notifications.
  4. Android: Call
    notifyListeners("eventName", jsObject)
    when the event occurs. Override
    handleOnConfigurationChanged()
    or register broadcast receivers as needed.
Ensure the event name string is identical across all platforms and matches the
eventName
parameter in
addListener()
.
如果插件需向JavaScript发送事件:
  1. TypeScript:在
    src/definitions.ts
    的插件接口中添加
    addListener()
    removeAllListeners()
    方法。为每个事件类型定义事件接口。
  2. Web:事件触发时调用
    this.notifyListeners('eventName', data)
  3. iOS:事件触发时调用
    self.notifyListeners("eventName", data: [...])
    。若需监听系统通知,在
    load()
    中注册观察者。
  4. Android:事件触发时调用
    notifyListeners("eventName", jsObject)
    。根据需要重写
    handleOnConfigurationChanged()
    或注册广播接收器。
确保所有平台的事件名称字符串完全一致,且与
addListener()
中的
eventName
参数匹配。

Step 9: Generate Documentation and Verify

步骤9:生成文档并验证

  1. Add JSDoc comments to all methods and interfaces in
    src/definitions.ts
    if not already present.
  2. Generate documentation:
bash
npm run docgen
  1. Run the full verification:
bash
npm run verify
  1. Lint and format:
bash
npm run lint
npm run fmt
  1. src/definitions.ts
    中的方法和接口未添加JSDoc注释,补充完整。
  2. 生成文档:
bash
npm run docgen
  1. 执行完整验证:
bash
npm run verify
  1. 代码检查与格式化:
bash
npm run lint
npm run fmt

Step 10: Publish

步骤10:发布插件

Read
references/publishing.md
and guide the user through the publishing process.
  1. Verify
    package.json
    fields are correct (name, version, description, files, capacitor).
  2. Run the pre-publish checklist.
  3. Publish to npm:
bash
npm publish --access public
阅读
references/publishing.md
并引导用户完成发布流程。
  1. 验证
    package.json
    字段是否正确(名称、版本、描述、文件、capacitor配置)。
  2. 执行发布前检查清单。
  3. 发布至npm:
bash
npm publish --access public

Error Handling

错误处理

  • npm init @capacitor/plugin@latest
    fails
    : Ensure Node.js LTS and npm 6+ are installed. Run
    node -v
    and
    npm -v
    to check.
  • npm run verify:ios
    fails with "module not found"
    : Run
    cd ios && pod install --repo-update && cd ..
    to install CocoaPods dependencies.
  • npm run verify:android
    fails with build errors
    : Open
    android/
    in Android Studio, sync Gradle, and check for missing dependencies or SDK version mismatches.
  • npm run build
    fails with TypeScript errors
    : Check
    src/definitions.ts
    for type mismatches. Ensure the web implementation in
    src/web.ts
    correctly implements the plugin interface.
  • registerPlugin()
    name mismatch
    : The first argument to
    registerPlugin()
    in
    src/index.ts
    must exactly match the
    jsName
    property on iOS and the
    @CapacitorPlugin(name = "...")
    value on Android. A mismatch causes the plugin to not load.
  • iOS: Methods not callable from JavaScript: Ensure all plugin methods are marked with
    @objc
    and listed in the
    pluginMethods
    array of
    CAPBridgedPlugin
    .
  • Android: Methods not callable from JavaScript: Ensure all plugin methods have the
    @PluginMethod()
    annotation and are
    public
    .
  • Events not received in JavaScript: Verify the event name string is identical in the native
    notifyListeners()
    call and the TypeScript
    addListener()
    definition. Verify
    addListener()
    is called before the event fires.
  • Plugin configuration values not reading: Verify the key names in
    getConfig().getString("key")
    match the keys in the Capacitor config file under
    plugins.<PluginJSName>
    .
  • npm run docgen
    produces empty output
    : Ensure JSDoc comments are present on the plugin interface methods in
    src/definitions.ts
    , not on the implementation classes.
  • npm init @capacitor/plugin@latest
    执行失败
    :确保已安装Node.js LTS和npm 6+版本。运行
    node -v
    npm -v
    检查版本。
  • npm run verify:ios
    提示“module not found”
    :运行
    cd ios && pod install --repo-update && cd ..
    安装CocoaPods依赖。
  • npm run verify:android
    出现构建错误
    :在Android Studio中打开
    android/
    目录,同步Gradle并检查是否缺少依赖或SDK版本不匹配。
  • npm run build
    出现TypeScript错误
    :检查
    src/definitions.ts
    中的类型不匹配问题。确保
    src/web.ts
    中的Web实现正确遵循插件接口。
  • registerPlugin()
    名称不匹配
    src/index.ts
    registerPlugin()
    的第一个参数必须与iOS的
    jsName
    属性和Android的
    @CapacitorPlugin(name = "...")
    值完全一致。名称不匹配会导致插件无法加载。
  • iOS:方法无法从JavaScript调用:确保所有插件方法都标记了
    @objc
    并在
    CAPBridgedPlugin
    pluginMethods
    数组中列出。
  • Android:方法无法从JavaScript调用:确保所有插件方法都带有
    @PluginMethod()
    注解且为
    public
    修饰。
  • JavaScript未接收到事件:验证原生
    notifyListeners()
    调用中的事件名称与TypeScript
    addListener()
    定义的名称完全一致。确保
    addListener()
    在事件触发前已调用。
  • 无法读取插件配置值:验证
    getConfig().getString("key")
    中的键名与Capacitor配置文件中
    plugins.<PluginJSName>
    下的键名一致。
  • npm run docgen
    生成空输出
    :确保JSDoc注释添加在
    src/definitions.ts
    的插件接口方法上,而非实现类中。

Related Skills

相关技能

  • capacitor-plugin-spm-support
    — Add Swift Package Manager support to a Capacitor plugin.
  • capacitor-plugin-upgrades
    — Upgrade a Capacitor plugin to a newer Capacitor major version.
  • capacitor-plugins
    — Install and configure existing Capacitor plugins in an app project.
  • capacitor-plugin-spm-support
    —— 为Capacitor插件添加Swift Package Manager支持。
  • capacitor-plugin-upgrades
    —— 将Capacitor插件升级至更新的Capacitor主版本。
  • capacitor-plugins
    —— 在应用项目中安装并配置现有Capacitor插件。",