mcpField
C
cordova-plugin-migrator

cordova-plugin-migrator

github.com/ionic-team开发28207 次安装13 周前更新
代码仓库

关于 cordova-plugin-migrator

面向将现有 Cordova 插件迁移到 Capacitor 的团队的编排技能。它分析源代码并生成结构化 YAML 交接计划,经用户确认后调用 capacitor-plugin-generator 生成插件,再整理迁移文档。

主要功能

  1. 01分析 Cordova 源码和依赖
  2. 02生成结构化 YAML 迁移计划
  3. 03生成前设置用户确认环节
  4. 04委托 capacitor-plugin-generator
  5. 05汇总 MIGRATION.md 文档
  6. 06检查钩子和平台差异

适用场景

  1. 01承诺迁移前评估工作量和阻碍
  2. 02为 Cordova 插件准备生成器计划
  3. 03审查钩子及原生依赖的可移植性
  4. 04比较 Cordova 与 Capacitor API

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ionic-team/capacitor-skills --skill cordova-plugin-migrator

安装后在 Claude Code 中输入/cordova-plugin-migrator确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
api-mappings.md
complexity-assessment.md
dependency-migration.md
example-analysis.md
hooks-migration.md
migration-patterns.md
output-modes.md
post-migration-cleanup.md
unsupported-patterns.md
using-plugin-generator.md

详细介绍

Cordova 插件迁移器

端到端协调器,只需调用一次技能,即可接收 Cordova 插件源代码树,并生成候选 Capacitor 插件及整合后的 MIGRATION.md。它会先分析 Cordova 插件,生成符合 capacitor-plugin-generator/references/input-contract.md 的结构化 YAML 计划,等待用户确认,然后以结构化模式将该计划交给 capacitor-plugin-generator 技能。此技能不会重新实现生成器已有的功能;脚手架搭建和原生代码生成由生成器负责。

何时使用此技能

✅ 在以下情况下使用此技能:

  • 将现有 Cordova 插件迁移到 Capacitor。
  • 在做出决定前评估迁移的复杂度、工作量和阻碍因素。
  • 为 capacitor-plugin-generator 生成结构化交接 YAML。
  • 将官方 Cordova API 与现有或计划中的 Capacitor API 进行比较。
  • 审查 Cordova 插件的钩子、原生依赖项或 <config-file> 修改,评估其可移植性。

❌ 请勿在以下情况下使用此技能:

  • 生成 Capacitor 插件脚手架或实现;请将计划交给 capacitor-plugin-generator。
  • 在没有 Cordova 源代码的情况下设计全新插件。
  • 迁移整个 Cordova 应用。此技能的范围仅限插件。
  • 调试已迁移插件的运行时问题。
  • 发布或发行生成的 Capacitor 插件。

前置条件

要求用途
Cordova 插件源代码(本地克隆或可访问的仓库)读取 plugin.xml、原生源代码和 JS 桥接代码。
Node.js LTS 和 npm检查依赖项,并运行钩子引用的脚本。
capacitor-plugin-generator 技能接收此技能生成的 YAML 计划。
capacitor-plugin-generator/references/input-contract.md规定交接 YAML 的权威格式。
对官方 Capacitor 等效实现(如有)的读取权限移植已有 Capacitor 实现的插件时,复用其线格式名称和类型。
Xcode 和 Android Studio(可选)确认检测到的原生依赖项所需的 SDK 是否可用。

Agent 行为

  • 作为编排器运行。阶段 1–10 分析 Cordova 源码并生成 YAML 计划;阶段 11 通过 Skill 工具调用 capacitor-plugin-generator,以结构化模式传入计划;阶段 12 整合文档。不要通过此技能输出原生 Capacitor 代码。该生成器负责此项工作。
  • 生成 YAML 前,先阅读 capacitor-plugin-generator/references/input-contract.md。生成器的契约具有权威性;不要臆造字段或重命名现有字段。
  • 首先从 plugin.xml 确定插件身份:id、name、version、声明的平台、声明的框架、hooks 和 config-file 目标。
  • 在断言平台支持情况前,检查所有原生依赖声明。应反映 plugin.xml 的实际内容,而非 README 中的说法。
  • 根据 references/hooks-migration.md 中的规则,将每个 <hook> 分类为 Tier 1(Capacitor hooks)、Tier 2(npm 脚本/手动步骤)或 Tier 3(阻断项)。一个 Tier 3 hook 就足以阻止移交给生成器。
  • 如果存在官方 Capacitor 等效实现(@capacitor/<name> 或 Capawesome/社区移植版本),请阅读其 definitions.ts 和原生源码。原样复用其中的 wire-format 字符串、枚举值、方法名和事件名。不要臆造“看起来相似”的平行 API。
  • 检测混合插件。如果 package.json 已声明 scripts.capacitor:* hooks,则该插件已部分支持 Capacitor。将现有 hooks 记录为 Tier 1“已转换”,并询问用户是要复用、重写还是合并。不要悄悄丢弃它们。
  • 如果某个 JS 方法在 Cordova 端接收的参数是字符串化 JSON 数据块(原生处理程序中出现 JSON.parse / Gson.fromJson / JSONObject(args.getString(0))),必须将其映射为 api.types 中强类型的 TypeScript 接口,而不是 string 参数。根据原生解析位置记录接口结构。
  • 如果 Cordova 原生源码使用运行时权限 API(cordova.requestPermission、requestPermissions(...)、AVCaptureDevice.requestAccess、PHPhotoLibrary.requestAuthorization、CLLocationManager 代理、CNContactStore.requestAccess 等),请在 YAML 中添加 checkPermissions() 和 requestPermissions() 方法,即使 Cordova JS 接口未公开这些方法也一样。Capacitor 的惯例是显式权限方法,而且官方等效实现(如有)几乎总会公开这些方法。
  • 如果 Cordova 原生源码通过辅助类(ExifHelper、MimeTypeHelper、ImageMetadata 等)提取元数据,并将其纳入响应负载,则应在相应的 api.types 接口中记录这些字段,即使 Cordova JS 文档未说明它们也一样。应阅读原生代码,而非 README。
  • 镜像官方 Capacitor 等效实现时,请核对该官方实现的原生 LOC 与 Cordova 源码的原生 LOC。如果官方实现的 LOC 超过后者的 3 倍,请在 migration.notes 中添加一条说明,提醒审阅者:直接移植会遗漏官方实现涵盖的行为(例如,用于精确控制振动时长的 iOS CHHapticEngine,或用于冲击/通知效果的 Android VibrationEffect 模式)。生成器的 SDK 适配器规则不一定能发现这一点。
  • 添加设置说明时,请区分三个下游目标:
    1. 插件自身的打包配置。 Gradle implementation '...' 行、CocoaPods s.dependency '...' 行、自定义 Maven 仓库 URL、s.weak_framework、s.vendored_frameworks、AndroidManifest <uses-permission> / <meta-data> / <queries> 条目,以及 @CapacitorPlugin(permissions = [...]) 声明,都应放在插件自身的 android/build.gradle、.podspec、android/src/main/AndroidManifest.xml 或注解中。Gradle 清单合并和 CocoaPods 会将这些配置传递给使用方,因此无需宿主应用步骤,也无需在 MIGRATION.md 中添加条目。
    2. 宿主应用的构建配置。 不能放在插件包中、必须由使用方应用配置的项目:Info.plist 隐私说明(NSCameraUsageDescription、NSLocationWhenInUseUsageDescription 等)、iOS 功能和授权(Apple Pay 商家 ID、aps-environment、com.apple.security.application-groups),以及其他必须在宿主应用中而非插件中完成的清单修改。记录在 migration.notes 中,并在 MIGRATION.md 中按平台提供可直接复制粘贴的代码片段。
    3. 使用方的运行时配置/代码。 Apple Developer 端的凭据配置、由宿主应用提供的 JSON 配置值(商家编号、API 密钥),以及使用方 JS 调用点的迁移(回调 → Promise、位置参数 → 命名参数)。由于这些输入属于使用方自己的数据,没有工具可以自动完成这些工作。 在 migration.notes 中,将每条 plugin.xml 指令归入这三类之一。切勿编写要求使用者为插件应打包的依赖添加 implementation '...' 的 MIGRATION.md 步骤。有关依赖项的具体表格,请参阅 references/dependency-migration.md 中的“所有权模型”。
  • 当 Cordova 插件使用 <preference name="VAR" default="...">,并在 <config-file target="*-Info.plist"> 条目中包含安装时占位值(Apple Pay 商户配置、OAuth 客户端 ID、分析密钥等)时,请检测这一情况,并在 migration.warnings 中建议采用运行时配置 JSON 文件模式:由混合 capacitor:sync:after 脚本使用 PluginConfig.json,在构建时将文件复制到原生项目中。Cordova 插件可能已经提供了此脚本(请在 hooks/capacitor*.js 中查找);如果有,请重复使用。否则,请提供一个单屏模板。此模式可完全避免将使用方的值写入静态 plist / manifest 条目。
  • 检测 plugin.xml 中的 SPM 标记:<platform name="ios" package="swift"> 和 <pod ... nospm="true"> 表明 Cordova 插件已附带同级的 Package.swift。如果存在:(a) 读取该 Package.swift,并将其依赖项填入 YAML 的 dependencies.ios.spm;(b) 将所有未带 nospm="true" 的 pod 移至 dependencies.ios.cocoapods;(c) 在 migration.notes 中添加说明:生成的 Capacitor 插件必须同时附带 Package.swift 和 .podspec(Capacitor 8 同时支持两者,且 SPM 是新插件的默认方式)。架构请参阅 references/dependency-migration.md 中的 "Swift Package Manager (SPM)"。
  • 默认输出模式为 Mode B(并列目录)。仅当用户明确要求且源文件位于可写工作副本中时,才切换到 Mode A(在原位置操作并使用 .cordova-archive/)。
  • 如果阻塞项、Tier 3 钩子、无法解决的专有 SDK 或缺失的源文件会迫使你猜测,请暂停并要求用户输入。不要输出掩盖缺失信息的 YAML 计划。
  • 区分可解决的警告(有文档记录的手动步骤)和阻塞项(无法自动迁移)。两者都要写入计划;只有阻塞项会阻止移交。
  • 在 Cordova 插件目录中检入的随附二进制文件(例如 src/ios/frameworks/Foo.xcframework)本身不是阻塞项。保留该二进制文件,并在 migration.source_files.ios(或 .android)下记录其路径。只有当该二进制文件需要用户不具备的运行时凭据,或不满足 AndroidX / 64 位 / 模拟器要求时,才将其视为阻塞项。
  • 报告实际检查过的内容。标记阻塞项或不受支持的模式时,请注明文件路径和行号。
  • 在宣布 Phase 9 前,对照 iOS 和 Android 的检查结果。如果某个平台提供了另一平台没有的方法,请在 migration.warnings 中指出不匹配,以便生成器选择策略(两端都实现、有条件地公开,或删除)。不要悄然生成只有一个平台能够实现的契约。
  • 默认响应形式是架构和计划,而不是代码。除非用户明确要求“展示代码”或“深入分析”,否则不要包含完整的迁移前后代码块。migration.cordova_to_capacitor_map 中逐方法的一行映射不算“代码”,它们属于计划的一部分。
  • 对 migration.cordova_to_capacitor_map 中的每个值,以及其他包含 JS 语法((、)、{、}、:、[、])的 YAML 字符串,都加上引号。未加引号的 JS 表达式(如 Foo.bar({ x: 1 }))是无法解析的 YAML,生成器会在加载计划时拒绝它。
  • 只有在 Phase 10 的用户检查点获批后,才能调用生成器。如果用户拒绝、暂停或仍有未解决的阻塞项,就停止。绝不要使用 migration.blockers 非空或 migration.hooks.tier_3 非空的 YAML 调用生成器。
  • 当 odc_target: true 时,Phase 11 分为两个按顺序执行的子阶段(11a 和 11b)。Phase 11a 调用 build-actions-generator;Phase 11b 调用 capacitor-plugin-generator。完整流程请参阅 references/using-plugin-generator.md 中的 "ODC Path"。构建操作写入 Capacitor 插件文件夹。对于由构建操作完全覆盖的钩子和迁移说明,必须从传给生成器的 YAML(Phase 11b)中排除,以免生成器为构建操作已处理的配置级工作重复生成 Capacitor 钩子脚本。

流程

阶段 1:确定任务和输出模式

确认用户有一个要迁移的 Cordova 插件。如果用户想从头开始创建全新的 Capacitor 插件,且没有 Cordova 源代码可供转换,请在此处停止,并直接引导用户使用 capacitor-plugin-generator;此技能无法提供帮助。

否则,选择输出模式:

  • 模式 B(默认,旁置),生成器在 Cordova 仓库的同级目录中搭建新的 Capacitor 插件。绝不触碰 Cordova 仓库。
  • 模式 A(选择加入,原位),生成器在临时 目录中搭建插件。阶段 11 成功后,阶段 12 会将生成器的 输出移至 Cordova 仓库根目录,并将原始 Cordova 源代码移至 .cordova-archive/。保留原始仓库的 npm 包名称和 git 历史记录。需要用户明确选择加入,并确保 git 工作副本干净且可写。

请参阅 references/output-modes.md,了解目录布局、预检和 确切的迁移顺序。

**ODC 确认:**检查用户是否在请求中的任何位置提到了 ODC 或 OutSystems Developer Cloud。如果提到了,设置 odc_target: true 并继续。如果没有,请询问:"这个 Capacitor 插件是否会供 ODC (OutSystems Developer Cloud)应用使用?如果会,我们会在 Capacitor 插件旁生成构建操作,以便在 MABS 中处理原生配置。" 将回答记录为 odc_target: true/false,以供阶段 11 使用。

阶段 2:读取 plugin.xml

典型的 Cordova 插件目录结构:

my-plugin/
├── plugin.xml           # Plugin manifest and configuration
├── package.json         # NPM metadata (and any capacitor:* scripts)
├── www/                 # JavaScript bridge
├── src/
│   ├── ios/             # CDVPlugin subclasses (.h/.m/.swift)
│   └── android/         # CordovaPlugin subclasses (.java/.kt)
└── hooks/               # Optional lifecycle scripts

打开 plugin.xml。提取:插件 ID、名称、版本、声明的平台 (<platform name="...">)、<source-file>/<header-file> 映射、 <framework> 条目、<podspec> 块、<config-file> 目标、 <edit-config> 目标、<hook> 声明、<dependency> 条目、 <preference> 标签,以及 <js-module> 暴露方式(clobbers / merges / runs)。记录每个潜在阻塞项的文件路径和行号。

阶段 3:分析原生依赖

按照 references/dependency-migration.md 操作。针对每个 <framework> 和 <podspec> pod,判定其属于:直接迁移、版本更新、替代库或阻塞项。针对每个 Android Gradle 坐标,检查其使用的是 AndroidX 还是 Support Library,以及是否符合 Capacitor 的最低 compile SDK 要求。记录迁移后所需的手动安装步骤。

阶段 4:分析钩子

按照 references/hooks-migration.md 中的三级规则操作:

  • 第 1 级,可转换为 Capacitor 插件 npm 钩子 (capacitor:{sync,copy,update}:{before,after}、 capacitor:{android,ios}:add:{before,after})。
  • 第 2 级,可转换为 npm 生命周期脚本(postinstall、 preuninstall)或记录为手动步骤。
  • 第 3 级,交互式提示、修改 plugin.xml/config.xml、Cordova CLI 内部功能,或任何没有 Capacitor 对应项的内容。

阅读每个引用的脚本。不要仅根据文件名进行分类。

阶段 5:分析 JavaScript 桥接

按照 references/api-mappings.md 操作。根据 www/*.js 列出每个公共方法、 其位置参数结构、使用成功/错误回调还是返回 Promise,以及 exec() 是否与 cordova.exec() 操作名称配对。将每个方法映射为 Capacitor 的 methodName(options): Promise<R> 签名。

阶段 6:分析 iOS 实现

按照 references/api-mappings.md 操作。根据 src/ios/*.{h,m,swift},识别 CDVPlugin 子类、每个与 JS 操作对应的方法、从 command.arguments 中提取参数的方式、响应构造(CDVPluginResult)、权限流程,以及使用的任何系统框架或 SDK 适配器。指出需要将 Objective-C 现代化为 Swift 的位置。

阶段 7:分析 Android 实现

按照 references/api-mappings.md 操作。根据 src/android/**/*.{java,kt},识别 CordovaPlugin 子类、execute() 路由器、操作字符串、参数提取方式(args.getString(i))、响应路径(CallbackContext.success/error)、权限流程,以及任何 Activity Result 模式。指出需要将 Java 现代化为 Kotlin 的位置。

阶段 8:评估复杂度

应用 references/complexity-assessment.md。根据方法数量、 代码行数、依赖规模、钩子层级组合、语言现代化程度、阻碍项数量以及 Capacitor 等效复用情况为插件评分。输出以下其中一项:simple、moderate、 complex、blocked。blocked 表示用户必须先解决问题,才能交接给 生成器。

阶段 9:生成迁移 YAML

应用 references/using-plugin-generator.md。依据生成器的 references/input-contract.md 构建 YAML,包含基础区块(plugin、 platforms、api、permissions、dependencies)以及可选的 migration: 区块(source、complexity、output_mode、blockers、 warnings、language_modernization、source_files、hooks、 cordova_to_capacitor_map)。若存在官方 Capacitor 等效项,则将线级格式字符串 固定为其对应值。

阶段 10:用户确认点

在 YAML 旁附上简短的人类可读摘要:复杂度、阻碍项、警告、手动设置、 建议的输出模式,以及所参照的任何 Capacitor 等效项。如果存在阻碍项或 Tier 3 钩子,则停止并等待确认。

阶段 11:调用下游技能

下游调用路径取决于阶段 1 中是否确认了 ODC。

非 ODC 路径:应用 references/using-plugin-generator.md。通过 Skill 工具以结构化模式调用 capacitor-plugin-generator,并传入阶段 9 的 YAML。生成器会运行自己的操作流程; 本技能不会重新检查 Cordova 源代码。对于 Complex 插件,使用增量模式 (每次处理一个平台,并在每个平台后等待用户确认)。如果生成器拒绝 YAML,则返回阶段 9 并修正; 切勿手动编辑生成器的输出。

**ODC 路径:**按照 references/using-plugin-generator.md“ODC Path”中的两个子阶段顺序执行:

  • 阶段 11a — 使用阶段 9 的 YAML 和 Cordova 插件路径调用 build-actions-generator; 等待其生成 build-actions/。记录其覆盖了哪些钩子/元素。
  • 阶段 11b — 从 migration.hooks.tier_1 中移除已由构建操作覆盖的项目 (或将其标记为 status: handled_by_build_actions);添加一条 migration.notes 记录说明这一点。然后使用带注释的 YAML 调用 capacitor-plugin-generator(根据复杂度选择标准模式或增量模式)。
阶段 12:迁移后清理

应用 references/post-migration-cleanup.md。生成器生成可用脚手架后,将中间备注 整合到插件根目录中的单个 MIGRATION.md 文件中,根据所选输出模式归档或移除 原始 Cordova 源代码,并更新 README,说明面向使用者的破坏性变更 (回调 → Promise、位置参数 → 命名参数、手动原生设置)。

根据 Agent Behavior 规则,交叉检查每条 migration.notes 和 migration.warnings 条目是否已归类(插件打包 / 宿主应用构建配置 / 使用者运行时配置)。MIGRATION.md 只应列出归入类别 2 或 3 的项目。 插件打包项目对使用者透明,不应纳入迁移记录。

最佳实践

应当做
  • ✅ 首先阅读 plugin.xml,并以实际 XML、源文件路径或钩子脚本内容为依据支持每项结论。对阻碍项标注行号。
  • ✅ 将生成器的输入契约视为权威依据。根据 capacitor-plugin-generator/references/input-contract.md 构建 YAML。
  • ✅ 如果存在官方 Capacitor 等效项,则复用其线级格式字符串。枚举大小写、事件名称和方法名称必须完全一致。
  • ✅ 阅读钩子引用的脚本来对钩子分类,不要仅凭文件名判断。
  • ✅ 默认使用模式 B(并行放置)。只有在用户明确选择加入且有可写工作副本时,才切换到模式 A。
  • ✅ 如果存在阻碍项或 Tier 3 钩子,则在阶段 10 的确认点停止。
  • ✅ 同时记录阻碍项和警告;只有阻碍项会阻止交接。
  • ✅ 记录迁移后使用者需要执行的手动原生设置步骤(Info.plist 键、AndroidManifest 条目、Podfile / Gradle 添加项)。
不要
  • ❌ 不要通过此技能生成原生 Capacitor 代码(Swift、Kotlin、Java、TypeScript)。代码生成由生成器负责。
  • ❌ 不要臆造 YAML 字段,也不要重命名生成器已定义的字段。
  • ❌ 如果存在官方的 Capacitor 等效项,不要根据便于理解的名称重新推导线缆格式字符串。请查看其 definitions.ts。
  • ❌ 不要在未打开引用脚本的情况下,将钩子归类为 Tier 1/2。
  • ❌ 不要输出一份 YAML 计划,其中将 complexity: simple 列为简单,却隐瞒了专有 AAR 或交互式设置钩子。
  • ❌ 不要在此处添加特定于 Capacitor 版本的说明;生成器技能负责生成器端的规则(名称一致性、Java 文件名、notifyListeners 可见性等)。请引用,不要重复。
  • ❌ 不要静默调用生成器。阶段 10 是用户必须确认的检查点,不得跳过。
  • ❌ 存在未解决的阻塞项或 Tier 3 钩子时,不要调用生成器。
  • ❌ 不要通过此技能提交、推送或发布生成器输出。

错误处理

症状修复方法
缺少 plugin.xml 或文件格式错误停止。请用户提供规范的插件源文件。不要根据 README 中的宣传文案推断契约。
plugin.xml 引用的源文件在磁盘上不存在停止。按路径报告缺失文件。缺少这些文件,计划就不完整;不要继续到 Phase 9。
Hook 引用的脚本无法打开或经过混淆归类为 Tier 3,并将脚本路径添加到 migration.blockers。不要根据 Hook 类型猜测。
插件为需要用户不具备的运行时凭据的私有/专有 AAR 或 .framework 声明了 <framework>记录为阻碍项。注明需要联系供应商。不要悄悄换成公开替代项。
插件在仓库中携带二进制文件(例如 src/ios/frameworks/Foo.xcframework、src/android/libs/Foo.aar),且该文件公开分发不属于阻碍项。保留该二进制文件,并在 migration.source_files.{ios,android} 下记录其路径。生成器会将其复制到 Capacitor 插件的 ios/ 或 android/libs/ 目录。
插件从自定义 Maven 仓库(Azure DevOps、JFrog 等)拉取 Android 依赖项在 migration.dependencies.android.maven_repos 下记录 URL。无需身份验证即可访问时,作为警告而非阻碍项。需要身份验证但未提供凭据时,作为阻碍项。
插件使用 Support Library(android.support.*)坐标除非用户确认接受 Jetifier,否则记录为阻碍项。Capacitor 需要 AndroidX。
Cordova 插件有官方 Capacitor 等效插件(@capacitor/<name>)阅读该等效插件的 definitions.ts 和原生源代码。在 YAML 中固定方法名称、枚举值、事件名称和错误代码。将该等效插件的包作为 migration.notes 提供给审核者。
插件同时声明了 <hook> 条目和 package.json 中的 scripts.capacitor:* 条目(混合插件)Capacitor 脚本已经存在。将其记录为 Tier 1“已转换”Hook。询问用户是要复用、重写,还是与新迁移的 Cordova Hook 合并。
插件通过 <config-file> 修改 AndroidManifest.xml,添加 <uses-permission>、<meta-data>、<queries> 或 <provider>放入插件自己的 android/src/main/AndroidManifest.xml,Gradle 清单合并器会自动将其合并到宿主应用。无需执行宿主应用步骤。在 migration.notes 下记录,以便生成器输出。
插件通过 <config-file> 修改 Info.plist,添加 Apple 要求的隐私说明字符串(NSCameraUsageDescription、NSLocationWhenInUseUsageDescription、NSMicrophoneUsageDescription 等)宿主应用的 Info.plist,Apple App Store 要求这些内容位于宿主应用的 plist 中,而非插件的 plist 中。在 migration.notes 下记录,并在 MIGRATION.md 中提供可复制粘贴的代码片段。
插件通过 $VAR 安装时占位符,使用 <config-file> 修改 Info.plist,添加面向使用者的特定值(Apple Pay 商户 ID、OAuth 客户端 ID、分析密钥)强烈推荐使用运行时配置 JSON 文件模式:由混合 capacitor:sync:after 脚本读取 <Plugin>Configuration.json。如果 Cordova 插件中已有脚本,则复用;否则提供一屏即可完成的模板。这样可以将面向使用者的特定值完全排除在 plist 之外。
插件通过 <config-file> 修改 entitlements plist(*-Debug.plist、*-Release.plist、*-Entitlements.plist),以添加 com.apple.developer.in-app-payments、aps-environment、com.apple.security.application-groups 等功能所需配置宿主应用功能 + entitlement。 在 migration.notes 下记录;在 MIGRATION.md 中说明使用者必须启用的确切 Xcode 功能(Apple Pay、推送通知、App Groups 等)和 entitlement 值。
插件为 iOS 声明了带有 weak="true" 的 <framework>插件自己的 podspec。 在 dependencies.ios.system_frameworks 中记录,并添加一条 migration.notes,以便生成器输出 s.weak_framework 而非 s.framework。无需执行宿主应用步骤。
插件使用 <edit-config> 和 mode="merge",向宿主 <application> 元素添加 android:requestLegacyExternalStorage 或类似属性宿主应用的 AndroidManifest(如果该属性适用于宿主应用);否则使用插件自己的 AndroidManifest。在 migration.notes 中记录确切属性和父元素,以便 MIGRATION.md 包含可复制粘贴的代码片段。
插件使用 <js-module runs="true">添加到 migration.warnings。建议在 Web 层使用显式的 initialize() 方法或在构造函数中初始化。
插件有多个 <js-module> 条目,且含有多个 <clobbers> 目标(例如常量模块 + 主模块)合并为单个 registerPlugin() 注册。在 definitions.ts 中将常量与插件接口一起导出。Capacitor 没有对应的多重 clobber 机制。
插件通过 <source-file target-dir="res/..."> 包含 Android 资源文件在 migration.source_files.android 下记录,并注明目标 res/ 子路径。生成器会将其复制到 android/src/main/res/<subpath>/。常见于 FileProvider 路径和主题。
插件使用 <preference name="..." default="..."> 和安装时变量替换(plugin.xml 中的 ${VAR}),并在 <config-file target="*-Info.plist"> 或 AndroidManifest.xml 中引用优先采用运行时配置 JSON 文件模式(使用者将值填入 <Plugin>Configuration.json,由混合 capacitor:sync:after 脚本读取)。如果 Cordova 插件中已有脚本,则复用。备选方案:在 capacitor.config.json 中使用 plugins.<PluginJSName> 下的运行时配置。
插件使用 <preference name="ANDROIDX_CORE_VERSION" default="1.18.0">(或类似的仅构建时版本固定项),并在插件自己的 build.gradle 中引用插件自己的 build.gradle,在生成的 Gradle 文件中按字面值固定版本。无需执行宿主应用步骤,也无需运行时配置。使用者不会看到此配置。
插件的原生处理程序解析字符串化的 JSON 数据块(Gson.fromJson、JSONObject(args.getString(0)))将解析后的结构映射到强类型的 api.types 接口,绝不能使用 string。从原生解析位置(Kotlin data class 或 Swift struct)提取结构定义。
一个 JS 方法根据 typeof param 分派到多个 cordova.exec() 操作名称(例如 vibrate(num) 与 vibrate([...]))拆分为多个类型化的 Capacitor 方法,例如 vibrate({ duration })、vibrateWithPattern({ pattern, repeat })、cancelVibration()。在 migration.cordova_to_capacitor_map 中记录拆分,并将其添加到 migration.warnings,作为面向使用者的破坏性变更。
生成器因“bad indentation”或“mapping entry”解析错误而拒绝 YAML某个 cordova_to_capacitor_map 条目包含未加引号的 JS 语法((、{、: 等)。为每个 cordova: 和 capacitor: 值都加引号,使其成为 YAML 字符串。必须重新输出计划;生成器无法按原样加载。
Cordova 原生源代码请求运行时权限,但 Cordova JS 接口没有权限方法将 checkPermissions()(Promise<PermissionStatus>)和 requestPermissions(options?)(Promise<PermissionStatus>)添加到 api.methods,并将 PermissionStatus 接口添加到 api.types。否则,迁移后的插件将违反 Capacitor 惯例,使用者也会期待这些方法。
Cordova 原生源代码有用于提取元数据的辅助类(ExifHelper、MimeTypeHelper 等),但 Cordova JS 文档没有列出相应字段阅读构造原生响应的位置。将元数据字段(通常为 exif?: any、mimeType?、size?)添加到结果类型中。Cordova JS 文档经常低估原生端实际返回的内容。
官方 Capacitor 等效插件的原生源代码行数超过 Cordova 源代码的 3 倍添加 migration.notes 条目,提醒审核者,照搬移植会导致未实现平台特定行为(例如,以 AudioServicesPlaySystemSound 替代 iOS CHHapticEngine,或以单次振动替代 Android 基于模式的触觉反馈)。建议评估是否将使用者转向官方包。
Cordova 插件的 plugin.xml 含有 <platform name="ios" package="swift"> 或任何 <pod ... nospm="true">插件已在 CocoaPods 之外提供 SPM 支持。将其 Package.swift 依赖项移至 dependencies.ios.spm;仅将没有 nospm="true" 的 pod 移至 dependencies.ios.cocoapods。Capacitor 移植版必须同时提供 Package.swift 和 .podspec。
插件声明了对另一个 Cordova 插件的 <dependency>单独解决该依赖项。如果其没有 Capacitor 等效插件或迁移计划,则将其视为当前插件的阻碍项。
插件的 iOS 源代码仅使用 Objective-C记录 migration.language_modernization.ios: { from: objective_c, to: swift }。注明使用者可能仍需要桥接头文件。
插件的 Android 源代码仅使用 Java记录 migration.language_modernization.android: { from: java, to: kotlin }。用户提出要求时,生成器仍会生成 Java,但默认建议使用 Kotlin。
生成器拒绝 YAML重新阅读 capacitor-plugin-generator/references/input-contract.md。在此技能中修复 YAML,而不是修改生成器。不要绕过契约。
生成器提示缺少线格式字符串重新阅读官方 Capacitor 等效插件的 definitions.ts。逐字更新 api.types 值。不要根据易读名称进行“翻译”。
用户请求 Mode A,但工作副本不受版本控制或为只读拒绝 Mode A。建议使用 Mode B。没有 VCS 时,从错误的原地移动中恢复需要手动操作。
插件宣传了源代码并未实现的功能以源代码为准。在 migration.warnings 下记录宣传但未实现的功能。不要为了符合文档而虚构 API 方法。
Hook 根据文件名被归类为 Tier 1,但实际上需要交互阅读脚本源代码,而不只是 <hook> 的 name 属性。任何通过 stdin 提示、打开 TTY 或调用 read / prompt 的内容都属于 Tier 3。
依赖项被标记为“直接迁移”,但对应 pod / Gradle 产物已弃用在标记为直接迁移前,核实最新发布日期以及 Swift / AndroidX 兼容性。超过 3 年未更新的内容应改为“替换”或“阻碍项”。
插件复杂度被评估为“简单”,但其公共 API 方法有 15 个以上始终统计公共 API 方法。公共方法超过 10 个的插件至少属于中等复杂度,无论其他信号如何。
分析时漏掉了阻碍项始终扫描 plugin.xml 中的 <config-file>、<edit-config>、<js-module runs="true">、<hook> 和 <dependency>;这些都是必须检查的潜在阻碍项。如果 YAML 看起来过于整齐,进入 Phase 9 前要重新扫描。
生成器在 Phase 11 重新读取 Cordova 源代码YAML 计划不完整。根据 capacitor-plugin-generator/references/input-contract.md 重新验证;将 JS API 签名、原生方法映射、权限、依赖项和阻碍项一并写入计划,以免生成器需要查看 Cordova 目录树。
用户在检查点因不接受某个阻碍项而停止在 MIGRATION.md 中记录该阻碍项并停止。不要调用生成器。记录拒绝原因,以便下次尝试时处理。
复杂插件在单次调用中超出生成器的上下文容量使用增量模式:按平台分别调用生成器(web → iOS → Android → final),并在每个平台之间设置用户检查点,而不是一次性处理整个插件。参见 references/using-plugin-generator.md。
Mode A 移动操作与 Cordova 仓库中的文件冲突(顶层名称冲突)停止整个流程。与用户手动解决(重命名、删除或移动冲突文件),或者回退到 Mode B,针对同级目录重新运行 Phase 11。

相关技能

  • capacitor-plugin-generator (必需的下游依赖): 第 11 阶段会通过 Skill 工具以结构化模式调用此技能, 并使用第 9 阶段生成的 YAML 计划。生成器的 references/input-contract.md 是交接内容格式的权威规范。 此技能遵循并引用该规范,但不会重复生成器侧的任何 规则。
  • build-actions-generator (可选的下游依赖,仅用于 ODC 路径): 当 odc_target: true 时,第 11a 阶段会调用此技能。它会为 Capacitor 插件的 build-actions/ 目录 生成 buildAction.json,涵盖配置级原生设置(manifest、plist、Gradle 依赖、 entitlements),因此生成器无需为这些项目生成对应的 Capacitor hook。

参考资料

  • references/output-modes.md:模式 A(原地迁移并使用 .cordova-archive/)与模式 B(并排放置)的目录布局和 git mv 模式。
  • references/unsupported-patterns.md:<config-file>、<edit-config>、<hook>、<js-module runs>、偏好设置、权限及各模式的阻塞阈值。
  • references/dependency-migration.md:CocoaPods、SPM、系统框架、Gradle 坐标、AAR/JAR、自定义 Maven 仓库及各依赖的阻塞阈值。
  • references/hooks-migration.md:三级 hook 分类(第 1 级 Capacitor hook、第 2 级 npm 脚本、第 3 级阻塞项)及脚本分析工作流。
  • references/api-mappings.md:JavaScript 桥接、iOS(CDVPlugin → CAPPlugin)、Android(CordovaPlugin → Plugin)以及从 plugin.xml 到 package.json 的转换。
  • references/migration-patterns.md:回调 → Promise、权限处理、多平台配置,以及跨平台一致的错误处理。
  • references/complexity-assessment.md:simple / moderate / complex / blocked 评分标准,以及会导致插件在不同类别间变动的输入。
  • references/using-plugin-generator.md:根据 capacitor-plugin-generator/references/input-contract.md 构建 YAML、migration: 可选块,以及第 11 阶段的调用模式(标准模式与增量模式)。
  • references/post-migration-cleanup.md:将中间笔记整合到 MIGRATION.md、模式 A 的迁移流程、归档 Cordova 源码、更新 README,以及面向使用者的破坏性变更检查清单。
  • references/example-analysis.md:完整的端到端示例,包括读取 plugin.xml、依赖分析、hook 分类、YAML 输出和生成器交接。

评论

支持 Markdown