#!/bin/bash set -euo pipefail usage() { cat <<'EOF' Usage: build-electron-release [options] Options: --no-install 跳过依赖安装 --no-renderer 跳过 vite build --target 打包目标,默认 linux,windows,macos 可用值:linux,windows,win,macos,mac,darwin --release-dir 输出目录,默认 release -h, --help 显示帮助 Environment: PACKAGE_MANAGER 指定包管理器:pnpm、npm、yarn ELECTRON_TARGETS 同 --target RELEASE_DIR 同 --release-dir EOF } install_deps=true build_renderer=true targets="${ELECTRON_TARGETS:-linux,windows,macos}" release_dir="${RELEASE_DIR:-release}" package_manager="${PACKAGE_MANAGER:-}" while [ "$#" -gt 0 ]; do case "$1" in --no-install) install_deps=false ;; --no-renderer) build_renderer=false ;; --target) shift if [ "$#" -lt 1 ]; then echo "缺少 --target 参数值" >&2 exit 1 fi targets="$1" ;; --release-dir) shift if [ "$#" -lt 1 ]; then echo "缺少 --release-dir 参数值" >&2 exit 1 fi release_dir="$1" ;; -h|--help) usage exit 0 ;; *) echo "未知参数:$1" >&2 usage >&2 exit 1 ;; esac shift done detect_package_manager() { if [ -n "$package_manager" ]; then echo "$package_manager" return fi if [ -f pnpm-lock.yaml ]; then echo "pnpm" return fi if [ -f yarn.lock ]; then echo "yarn" return fi echo "npm" } pm="$(detect_package_manager)" install_project_deps() { case "$pm" in pnpm) pnpm install --frozen-lockfile ;; npm) npm ci ;; yarn) yarn install --frozen-lockfile ;; *) echo "不支持的包管理器:$pm" >&2 exit 1 ;; esac } run_local_bin() { case "$pm" in pnpm) pnpm exec "$@" ;; npm) npx --no-install "$@" ;; yarn) yarn exec "$@" ;; esac } has_target() { local target="$1" local item local normalized_targets normalized_targets="$(echo "$targets" | tr 'A-Z' 'a-z' | tr -d ' ')" IFS=',' read -ra items <<< "$normalized_targets" for item in "${items[@]}"; do case "$item:$target" in linux:linux|windows:windows|win:windows|macos:macos|mac:macos|darwin:macos) return 0 ;; esac done return 1 } if $install_deps; then install_project_deps fi if $build_renderer; then run_local_bin vite build fi if has_target linux; then run_local_bin electron-builder --linux AppImage --x64 --publish never --config.directories.output="${release_dir}/linux" fi if has_target windows; then run_local_bin electron-builder --win nsis --x64 --publish never --config.directories.output="${release_dir}/windows" fi if has_target macos; then run_local_bin electron-builder --mac zip --x64 --arm64 --publish never --config.directories.output="${release_dir}/macos" fi