插件发布 #

一、发布准备 #

1.1 检查项目结构 #

text
my-plugin/
├── src/
│   ├── definitions.ts
│   ├── index.ts
│   └── web.ts
├── ios/
│   ├── Sources/
│   │   └── MyPlugin/
│   │       ├── MyPlugin.swift
│   │       └── MyPlugin.m
│   └── MyPlugin.podspec
├── android/
│   └── src/main/
│       └── java/com/example/myplugin/
│           └── MyPlugin.java
├── dist/                     # 构建输出
├── package.json
├── tsconfig.json
├── rollup.config.js
├── README.md
├── CHANGELOG.md
└── LICENSE

1.2 完善package.json #

json
{
    "name": "@mycompany/my-plugin",
    "version": "1.0.0",
    "description": "A custom Capacitor plugin for...",
    "main": "dist/plugin.cjs.js",
    "module": "dist/esm/index.js",
    "types": "dist/esm/index.d.ts",
    "unpkg": "dist/plugin.js",
    "files": [
        "dist/",
        "ios/",
        "android/",
        "MyPlugin.podspec",
        "README.md",
        "LICENSE"
    ],
    "author": {
        "name": "Your Name",
        "email": "your@email.com",
        "url": "https://yourwebsite.com"
    },
    "repository": {
        "type": "git",
        "url": "https://github.com/mycompany/my-plugin.git"
    },
    "bugs": {
        "url": "https://github.com/mycompany/my-plugin/issues"
    },
    "homepage": "https://github.com/mycompany/my-plugin#readme",
    "keywords": [
        "capacitor",
        "plugin",
        "ionic",
        "cross-platform",
        "native"
    ],
    "license": "MIT",
    "readme": "README.md",
    "engines": {
        "node": ">=16.0.0"
    },
    "peerDependencies": {
        "@capacitor/core": "^6.0.0"
    },
    "devDependencies": {
        "@capacitor/core": "^6.0.0",
        "@capacitor/cli": "^6.0.0",
        "typescript": "^5.0.0",
        "rollup": "^3.0.0",
        "@rollup/plugin-node-resolve": "^15.0.0",
        "@rollup/plugin-typescript": "^11.0.0",
        "rimraf": "^5.0.0"
    },
    "scripts": {
        "build": "npm run clean && npm run compile",
        "clean": "rimraf dist",
        "compile": "rollup -c rollup.config.js",
        "prepublishOnly": "npm run build",
        "lint": "eslint src/**/*.ts",
        "test": "jest"
    },
    "capacitor": {
        "ios": {
            "src": "ios"
        },
        "android": {
            "src": "android"
        }
    }
}

1.3 编写README.md #

markdown
# @mycompany/my-plugin

A Capacitor plugin that provides...

## Installation

```bash
npm install @mycompany/my-plugin
npx cap sync

Configuration #

iOS #

Add the following to your Info.plist:

xml
<key>NSCameraUsageDescription</key>
<string>Your description here</string>

Android #

Add the following to your AndroidManifest.xml:

xml
<uses-permission android:name="android.permission.CAMERA" />

Usage #

typescript
import { MyPlugin } from '@mycompany/my-plugin';

// Basic usage
const result = await MyPlugin.doSomething({
    param1: 'value',
    param2: 123
});

// With event listener
await MyPlugin.addListener('myEvent', (data) => {
    console.log('Event received:', data);
});

API #

doSomething(options) #

Param Type Description
options.param1 string First parameter
options.param2 number Second parameter (optional)

Returns: Promise<DoSomethingResult>

addListener(eventName, listener) #

Param Type Description
eventName string Event name
listener function Callback function

License #

MIT

text

### 1.4 创建CHANGELOG.md

```markdown
# Changelog

All notable changes to this project will be documented in this file.

## [1.0.0] - 2024-01-01

### Added
- Initial release
- Basic plugin functionality
- iOS support
- Android support
- Web support

## [0.1.0] - 2024-01-01

### Added
- Initial development version

二、构建配置 #

2.1 TypeScript配置 #

json
// tsconfig.json
{
    "compilerOptions": {
        "target": "ES2020",
        "module": "ESNext",
        "lib": ["ES2020", "DOM"],
        "declaration": true,
        "declarationMap": true,
        "strict": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "noImplicitThis": true,
        "alwaysStrict": true,
        "noUnusedLocals": false,
        "noUnusedParameters": false,
        "noImplicitReturns": true,
        "noFallthroughCasesInSwitch": false,
        "inlineSourceMap": true,
        "inlineSources": true,
        "experimentalDecorators": true,
        "moduleResolution": "node",
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true,
        "outDir": "./dist",
        "rootDir": "./src"
    },
    "include": ["src/**/*.ts"],
    "exclude": ["node_modules", "dist"]
}

2.2 Rollup配置 #

javascript
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import typescript from '@rollup/plugin-typescript';

export default [
    // ES Module build
    {
        input: 'src/index.ts',
        output: [
            {
                dir: 'dist/esm',
                format: 'esm',
                sourcemap: true,
                preserveModules: true,
                preserveModulesRoot: 'src'
            }
        ],
        plugins: [
            resolve(),
            typescript({
                tsconfig: './tsconfig.json',
                declaration: true,
                declarationDir: './dist/esm'
            })
        ],
        external: ['@capacitor/core']
    },
    // CommonJS build
    {
        input: 'src/index.ts',
        output: {
            file: 'dist/plugin.cjs.js',
            format: 'cjs',
            sourcemap: true
        },
        plugins: [
            resolve(),
            typescript({
                tsconfig: './tsconfig.json'
            })
        ],
        external: ['@capacitor/core']
    },
    // Browser build
    {
        input: 'src/index.ts',
        output: {
            file: 'dist/plugin.js',
            format: 'iife',
            sourcemap: true,
            globals: {
                '@capacitor/core': 'Capacitor'
            }
        },
        plugins: [
            resolve(),
            typescript({
                tsconfig: './tsconfig.json'
            })
        ],
        external: ['@capacitor/core']
    }
];

三、版本管理 #

3.1 语义化版本 #

text
MAJOR.MINOR.PATCH

MAJOR: 不兼容的API变更
MINOR: 向后兼容的功能新增
PATCH: 向后兼容的问题修复

3.2 版本更新流程 #

bash
# 更新版本号
npm version patch  # 1.0.0 -> 1.0.1
npm version minor  # 1.0.0 -> 1.1.0
npm version major  # 1.0.0 -> 2.0.0

# 这会自动:
# 1. 更新package.json版本号
# 2. 创建git commit
# 3. 创建git tag

3.3 预发布版本 #

bash
# Alpha版本
npm version prerelease --preid=alpha
# 1.0.0 -> 1.0.1-alpha.0

# Beta版本
npm version prerelease --preid=beta
# 1.0.0 -> 1.0.1-beta.0

# RC版本
npm version prerelease --preid=rc
# 1.0.0 -> 1.0.1-rc.0

四、发布到npm #

4.1 npm账号准备 #

bash
# 登录npm
npm login

# 验证登录状态
npm whoami

4.2 发布流程 #

bash
# 1. 确保代码已提交
git status

# 2. 运行测试
npm test

# 3. 构建
npm run build

# 4. 发布
npm publish

# 发布作用域包(如@mycompany/my-plugin)
npm publish --access public

4.3 发布预发布版本 #

bash
# 发布alpha版本
npm publish --tag alpha

# 发布beta版本
npm publish --tag beta

# 发布rc版本
npm publish --tag rc

4.4 安装特定版本 #

bash
# 安装最新版本
npm install @mycompany/my-plugin

# 安装特定版本
npm install @mycompany/my-plugin@1.0.0

# 安装预发布版本
npm install @mycompany/my-plugin@beta

五、发布检查清单 #

5.1 发布前检查 #

bash
# 检查package.json
cat package.json

# 检查构建输出
ls -la dist/

# 检查文件列表
npm pack --dry-run

# 本地测试
npm link
cd /path/to/test/project
npm link @mycompany/my-plugin
npx cap sync

5.2 检查清单 #

  • [ ] 更新版本号
  • [ ] 更新CHANGELOG.md
  • [ ] 运行测试
  • [ ] 构建成功
  • [ ] README文档完整
  • [ ] 类型定义正确
  • [ ] iOS Podspec正确
  • [ ] Android配置正确
  • [ ] Git提交完成
  • [ ] Git标签创建

六、自动化发布 #

6.1 GitHub Actions配置 #

yaml
# .github/workflows/release.yml
name: Release

on:
    push:
        tags:
            - 'v*'

jobs:
    build:
        runs-on: ubuntu-latest
        
        steps:
            - uses: actions/checkout@v4
            
            - name: Setup Node.js
              uses: actions/setup-node@v4
              with:
                  node-version: '20'
                  registry-url: 'https://registry.npmjs.org'
            
            - name: Install dependencies
              run: npm ci
            
            - name: Build
              run: npm run build
            
            - name: Test
              run: npm test
            
            - name: Publish to npm
              run: npm publish --access public
              env:
                  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
            
            - name: Create GitHub Release
              uses: softprops/action-gh-release@v1
              with:
                  files: |
                      dist/*.js
                      dist/*.d.ts
              env:
                  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

6.2 设置NPM Token #

  1. 在npm网站创建Access Token
  2. 在GitHub仓库设置中添加Secret:NPM_TOKEN

6.3 自动发布流程 #

bash
# 创建并推送标签
npm version patch
git push --follow-tags

# GitHub Actions会自动:
# 1. 构建项目
# 2. 运行测试
# 3. 发布到npm
# 4. 创建GitHub Release

七、插件维护 #

7.1 更新依赖 #

bash
# 检查过期依赖
npm outdated

# 更新依赖
npm update

# 更新Capacitor版本
npm install @capacitor/core@latest @capacitor/cli@latest

7.2 处理Issue #

markdown
# Issue模板

## Bug Report

**Describe the bug**
A clear description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. See error

**Expected behavior**
A clear description of what you expected to happen.

**Screenshots**
If applicable, add screenshots.

**Environment:**
 - OS: [e.g. iOS 15]
 - Device: [e.g. iPhone 13]
 - Plugin version: [e.g. 1.0.0]
 - Capacitor version: [e.g. 6.0.0]

7.3 版本兼容性 #

json
// package.json
{
    "peerDependencies": {
        "@capacitor/core": "^6.0.0"
    },
    "peerDependenciesMeta": {
        "@capacitor/core": {
            "optional": false
        }
    }
}

八、文档维护 #

8.1 API文档 #

typescript
/**
 * Does something amazing
 * 
 * @param options - The options for the operation
 * @returns A promise that resolves with the result
 * 
 * @example
 * ```typescript
 * const result = await MyPlugin.doSomething({
 *   param1: 'value',
 *   param2: 123
 * });
 * ```
 */
async doSomething(options: DoSomethingOptions): Promise<DoSomethingResult>;

8.2 示例项目 #

text
examples/
├── basic-usage/
│   ├── src/
│   ├── package.json
│   └── README.md
└── advanced-usage/
    ├── src/
    ├── package.json
    └── README.md

九、总结 #

9.1 发布流程 #

text
准备 → 构建 → 测试 → 发布 → 维护

9.2 最佳实践 #

  • 使用语义化版本
  • 保持文档更新
  • 编写完整测试
  • 及时处理Issue
  • 维护兼容性

9.3 下一步 #

插件发布完成后,让我们学习 相机与相册

最后更新:2026-03-28