Skip to content

Electron 打包发布与自动更新完全指南

前言

开发完成后,如何将 Electron 应用打包发布给用户?如何实现自动更新?这篇文章将详细介绍 Electron 应用的打包发布流程。

electron-builder 配置

安装

bash
npm install --save-dev electron-builder

基础配置

json
// package.json
{
  "name": "my-app",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "build": "electron-builder",
    "build:mac": "electron-builder --mac",
    "build:win": "electron-builder --win",
    "build:linux": "electron-builder --linux"
  },
  "build": {
    "appId": "com.example.myapp",
    "productName": "My App",
    "copyright": "Copyright © 2025 ${author}",
    "directories": {
      "output": "dist",
      "buildResources": "build"
    },
    "files": [
      "**/*",
      "!**/*.ts",
      "!*.map",
      "!*.md",
      "!.vscode",
      "!**/{.DS_Store,.git,.gitignore}"
    ],
    "mac": {
      "category": "public.app-category.productivity",
      "icon": "build/icon.icns",
      "target": ["dmg", "zip"],
      "hardenedRuntime": true,
      "gatekeeperAssess": false,
      "entitlements": "build/entitlements.mac.plist",
      "entitlementsInherit": "build/entitlements.mac.plist"
    },
    "win": {
      "icon": "build/icon.ico",
      "target": ["nsis", "portable"],
      "publisherName": "Your Name",
      "verifyUpdateCodeSignature": false
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true,
      "createDesktopShortcut": true,
      "createStartMenuShortcut": true
    },
    "linux": {
      "icon": "build/icons",
      "target": ["AppImage", "deb", "rpm"],
      "category": "Utility"
    }
  }
}

代码签名

macOS 签名

bash
# 1. 获取开发者证书
# 加入 Apple Developer Program ($99/年)

# 2. 创建 entitlements.plist
cat > build/entitlements.mac.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.cs.allow-jit</key>
    <true/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
</dict>
</plist>
EOF

# 3. 配置签名
{
  "build": {
    "mac": {
      "identity": "Developer ID Application: Your Name (TEAM_ID)",
      "hardenedRuntime": true
    }
  }
}

# 4. 公证应用
npm run build:mac
xcrun altool --notarize-app --primary-bundle-id "com.example.myapp" \
  --username "your@email.com" \
  --password "@keychain:AC_PASSWORD" \
  --file "dist/My App.dmg"

Windows 签名

bash
# 1. 获取代码签名证书
# 从 DigiCert、GlobalSign 等 CA 购买

# 2. 配置签名
{
  "build": {
    "win": {
      "certificateFile": "path/to/certificate.pfx",
      "certificatePassword": "password",
      "signingHashAlgorithms": ["sha256"],
      "rfc3161TimeStampServer": "http://timestamp.digicert.com"
    }
  }
}

# 3. 使用环境变量
export CSC_LINK=path/to/certificate.pfx
export CSC_KEY_PASSWORD=password
npm run build:win

自动更新

配置 electron-updater

bash
npm install electron-updater
javascript
// main.js
const { app, autoUpdater } = require('electron')
const { autoUpdater } = require('electron-updater')
const log = require('electron-log')

// 配置日志
autoUpdater.logger = log
autoUpdater.logger.transports.file.level = 'info'

// 配置更新服务器
autoUpdater.setFeedURL({
  provider: 'generic',
  url: 'https://your-update-server.com/updates'
})

// 检查更新
function checkForUpdates() {
  autoUpdater.checkForUpdatesAndNotify()
}

// 更新事件
autoUpdater.on('checking-for-update', () => {
  log.info('检查更新...')
})

autoUpdater.on('update-available', (info) => {
  log.info('发现新版本:', info.version)
  mainWindow.webContents.send('update-available', info)
})

autoUpdater.on('update-not-available', (info) => {
  log.info('当前已是最新版本')
})

autoUpdater.on('download-progress', (progress) => {
  log.info(`下载进度: ${progress.percent}%`)
  mainWindow.webContents.send('download-progress', progress)
})

autoUpdater.on('update-downloaded', (info) => {
  log.info('更新下载完成')
  mainWindow.webContents.send('update-downloaded', info)
})

// 启动时检查更新
app.whenReady().then(() => {
  createWindow()
  
  // 5秒后检查更新
  setTimeout(checkForUpdates, 5000)
  
  // 每小时检查一次
  setInterval(checkForUpdates, 60 * 60 * 1000)
})

// 安装更新
ipcMain.on('install-update', () => {
  autoUpdater.quitAndInstall()
})

更新服务器配置

json
// package.json
{
  "build": {
    "publish": [
      {
        "provider": "generic",
        "url": "https://your-update-server.com/updates"
      }
    ]
  }
}

生成更新文件

bash
# 打包时自动生成 latest.yml 或 latest-mac.yml
npm run build

# 输出文件:
# dist/
#   My App-1.0.0.dmg
#   My App-1.0.0.dmg.blockmap
#   latest-mac.yml

CI/CD 配置

GitHub Actions

yaml
# .github/workflows/build.yml
name: Build and Release

on:
  push:
    tags:
      - 'v*'

jobs:
  release:
    runs-on: ${{ matrix.os }}
    
    strategy:
      matrix:
        os: [macos-latest, windows-latest, ubuntu-latest]

    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Install dependencies
        run: npm install

      - name: Build
        run: npm run build
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: ${{ matrix.os }}
          path: dist/*

      - name: Release
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        with:
          files: dist/*
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

分发策略

1. 直接下载

提供下载链接:
- Windows: .exe 或 .msi
- macOS: .dmg
- Linux: .AppImage, .deb, .rpm

2. 应用商店

- Mac App Store
- Microsoft Store
- Snap Store (Linux)

3. 自动更新

配置更新服务器,用户自动获取更新

优化建议

减小体积

json
{
  "build": {
    "asar": true,
    "asarUnpack": [
      "node_modules/sharp/**/*"
    ],
    "compression": "maximum"
  }
}

增量更新

json
{
  "build": {
    "publish": [{
      "provider": "generic",
      "url": "https://example.com/updates"
    }],
    "nsis": {
      "differentialPackage": true
    }
  }
}

总结

Electron 应用的打包发布流程包括配置 electron-builder、代码签名、自动更新等关键步骤。掌握这些技能,才能将应用顺利交付给用户。


相关文章推荐: