@winner-fed/deploy-cli
TypeScript icon, indicating that this package has built-in type declarations

1.0.0 • Public • Published

@winner-fed/deploy-cli

一站式前端项目部署命令行工具

简介

@winner-fed/deploy-cli 是一个集成了 SEE 平台部署包生成和 FTP/SFTP 文件上传功能的命令行工具。它简化了前端项目的部署流程,支持多种配置方式和部署场景,完美支持 monorepo 环境,让部署变得更加简单高效。

特性

  • 🚀 一键部署: 支持 SEE 包生成和 FTP 上传的一体化部署
  • 📦 SEE 平台集成: 完整支持 SEE 平台的部署包规范
  • 🌐 FTP/SFTP 支持: 灵活的文件传输协议支持
  • 🏗️ Monorepo 支持: 智能识别 monorepo 环境,自动向上查找 git 仓库根目录
  • ⚙️ 多配置格式: 支持 JS、TS、JSON 等多种配置文件格式
  • 🎯 TypeScript 支持: 完整的类型定义和智能提示
  • 🔧 灵活配置: 支持环境变量、命令行参数等多种配置方式
  • 📊 详细日志: 提供详细的部署过程日志和错误信息

安装

全局安装(推荐)

npm install -g @winner-fed/deploy-cli
#
yarn global add @winner-fed/deploy-cli
#
pnpm add -g @winner-fed/deploy-cli

项目内安装

npm install @winner-fed/deploy-cli --save-dev
#
yarn add @winner-fed/deploy-cli --dev
#
pnpm add @winner-fed/deploy-cli -D

快速开始

1. 生成 SEE 部署包

# 全局安装后
deploy-cli see

# 项目内安装
npx deploy-cli see
#
yarn deploy-cli see

# 在 monorepo 子包中使用
cd packages/my-app
npx deploy-cli see

2. FTP 文件上传

# 全局安装后
deploy-cli ftp

# 项目内安装
npx deploy-cli ftp
#
yarn deploy-cli ftp

# 在 monorepo 子包中使用
cd packages/my-app
npx deploy-cli ftp

3. 一键部署(SEE + FTP)

deploy-cli deploy

# 在 monorepo 环境中,工具会自动识别并向上查找 git 仓库根目录
# 无需额外配置即可获取正确的 git 信息

命令行选项

通用选项

deploy-cli [command] [options]

Options:
  --config <path>     指定配置文件路径
  --help             显示帮助信息
  --version          显示版本信息

SEE 包生成

deploy-cli see [options]

Options:
  --config <path>     指定配置文件路径
  --output <dir>      指定输出目录
  --type <type>       应用类型 (bizframe|subsystem)
  --docker           生成 Docker 容器化包

FTP 上传

deploy-cli ftp [options]

Options:
  --config <path>     指定配置文件路径
  --host <host>       FTP 服务器地址
  --port <port>       FTP 服务器端口
  --sftp             使用 SFTP 协议

配置文件

deploy-cli 支持多种配置文件格式,会按以下优先级查找配置:

  1. deploy.config.ts
  2. deploy.config.js
  3. deploy.config.cjs
  4. deploy.config.mjs
  5. deploy.config.json
  6. package.json 中的 deploy 属性

基础配置示例

// deploy.config.js
module.exports = {
  // 项目源码路径
  source: process.cwd(),

  // SEE 包配置
  seeConfig: {
    system: 'my-system',
    type: 'subsystem',
    name: 'my-app',
    version: '1.0.0',
    description: '我的应用',
    outputName: 'dist'
  },

  // FTP 配置
  ftpConfig: {
    user: 'deploy-user',
    password: 'your-password',
    host: 'your-server.com',
    port: 22,
    localPath: './dist',
    remotePath: '/var/www/html',
    include: ['*', '**/*'],
    exclude: ['**/*.map'],
    sftp: true
  }
};

TypeScript 配置示例

// deploy.config.ts
import type { UserConfig } from '@winner-fed/deploy-cli';

const config: UserConfig = {
  source: process.cwd(),

  seeConfig: {
    system: 'winner-front',
    type: 'bizframe',
    name: 'main-app',
    version: '2.0.0',
    description: '主框架应用',
    variables: [
      {
        type: 'input',
        label: 'API 基础路径',
        name: 'API_BASE_URL',
        required: true,
        tooltip: '后端 API 服务地址',
        default: 'https://api.example.com'
      },
      {
        type: 'switch',
        label: '启用调试模式',
        name: 'DEBUG_MODE',
        options: 'true:是;false:否',
        required: false,
        tooltip: '是否启用调试模式',
        default: 'false'
      },
      {
        type: 'password',
        label: '数据库密码',
        name: 'DB_PASSWORD',
        required: true,
        tooltip: '数据库连接密码',
        default: ''
      },
      {
        type: 'hidden',
        label: '应用版本号',
        name: 'APP_VERSION',
        required: false,
        tooltip: '应用内部版本号,用于系统识别',
        default: '1.0.0'
      }
    ],
    isProduction: process.env.NODE_ENV === 'production',
    dockerImage: 'my-app:latest'
  },

  ftpConfig: {
    user: process.env.FTP_USER!,
    password: process.env.FTP_PASSWORD!,
    host: process.env.FTP_HOST!,
    port: parseInt(process.env.FTP_PORT || '22'),
    localPath: './dist',
    remotePath: '/usr/local/nginx/html/my-app',
    include: ['*', '**/*'],
    exclude: ['**/*.map', '**/*.log', '.DS_Store', 'Thumbs.db'],
    deleteRemote: true,
    sftp: true
  }
};

export default config;

配置项详细说明

UserConfig 接口

参数 类型 必填 默认值 说明
source string process.cwd() 项目源码路径
seeConfig SeeConfig - SEE 包配置
ftpConfig FtpConfig - FTP 配置
config string - 自定义配置文件路径

SeeConfig 配置

参数 类型 必填 默认值 说明
system string 'winner-front' 系统类型,SEE 平台分组维度
type 'bizframe' | 'subsystem' 'bizframe' 应用类型
name string package.json.name 发布物名称
version string package.json.version 发布包版本
description string package.json.description 发布包描述
appType string name 发布物类型
group string 'bizframe' 应用分组
configName string 'config.local' 配置文件名称(不含.js)
outputName string 'dist' 输出目录名称
templateFunc function - 自定义变量配置文件生成函数
variables Array [] deploy.xml 模板变量
copyFiles string[] [] 需要直接拷贝的文件列表
seePackageName string ${system}-${name}-${version} SEE 包名称
seePackageType 'web' | 'docker' 'web' SEE 包类型
isDocker boolean false 是否为 Docker 包
dockerImage string - Docker 镜像名
scriptsType 'python' | 'bash' 'python' 脚本类型
buildVersion string - 构建版本
isProduction boolean false 是否为生产包

FtpConfig 配置

参数 类型 必填 默认值 说明
user string - 服务器登录用户名
password string - 服务器登录密码
host string - 服务器主机地址
port number - 服务器端口
localPath string - 本地文件路径
remotePath string - 远程服务器路径
include string[] - 包含的文件模式
exclude string[] [] 排除的文件模式
deleteRemote boolean false 上传前是否删除远程文件
forcePasv boolean true 是否强制被动模式
sftp boolean false 是否使用 SFTP

模板变量配置

interface variables {
  type:
    | 'input'
    | 'select'
    | 'editor'
    | 'switch'
    | 'smallfile'
    | 'table'
    | 'mselect'
    | 'switchForm'
    | 'complexSelect'
    | 'division'
    | 'password'
    | 'hidden';
  label: string; // 控件标签
  name: string; // 变量名称
  options?: string; // 选项配置(select 类型使用)
  required: boolean; // 是否必填
  fold?: boolean; // 是否可折叠
  children?: variables[]; // 子控件
  tooltip: string; // 提示信息
  default: string; // 默认值
}

使用场景

1. 前端项目完整部署

// deploy.config.js
module.exports = {
  seeConfig: {
    system: 'my-system',
    type: 'subsystem',
    name: 'user-management',
    version: '1.0.0',
    description: '用户管理系统',
    variables: [
      {
        type: 'input',
        label: 'API 地址',
        name: 'API_URL',
        required: true,
        tooltip: '后端 API 服务地址',
        default: 'https://api.example.com'
      },
      {
        type: 'password',
        label: '数据库密码',
        name: 'DB_PASSWORD',
        required: true,
        tooltip: '数据库连接密码',
        default: ''
      },
      {
        type: 'hidden',
        label: '应用版本号',
        name: 'APP_VERSION',
        required: false,
        tooltip: '应用内部版本号,用于系统识别',
        default: '1.0.0'
      }
    ],
    isProduction: true
  },
  ftpConfig: {
    user: 'deploy',
    password: process.env.DEPLOY_PASSWORD,
    host: 'prod.example.com',
    port: 22,
    localPath: './dist',
    remotePath: '/var/www/html/user-management',
    include: ['*', '**/*'],
    exclude: ['**/*.map', '**/*.log'],
    deleteRemote: true,
    sftp: true
  }
};

2. 多环境部署配置

// deploy.config.js
const env = process.env.NODE_ENV || 'development';

const environments = {
  development: {
    host: 'dev.example.com',
    remotePath: '/var/www/dev'
  },
  staging: {
    host: 'staging.example.com',
    remotePath: '/var/www/staging'
  },
  production: {
    host: 'prod.example.com',
    remotePath: '/var/www/prod'
  }
};

module.exports = {
  seeConfig: {
    system: 'my-system',
    type: 'subsystem',
    isProduction: env === 'production'
  },
  ftpConfig: {
    user: 'deploy',
    password: process.env.DEPLOY_PASSWORD,
    host: environments[env].host,
    port: 22,
    localPath: './dist',
    remotePath: environments[env].remotePath,
    include: ['*', '**/*'],
    exclude: ['**/*.map'],
    deleteRemote: true,
    sftp: true
  }
};

3. Docker 容器化部署

// deploy.config.js
module.exports = {
  seeConfig: {
    system: 'container-system',
    type: 'subsystem',
    name: 'my-app',
    version: '1.0.0',
    seePackageType: 'docker',
    isDocker: true,
    dockerImage: 'my-app:1.0.0',
    scriptsType: 'bash'
  }
};

4. Monorepo 环境部署

// packages/my-app/deploy.config.js
module.exports = {
  // 工具会自动从子包目录向上查找 git 仓库根目录
  // 例如:从 /monorepo/packages/my-app 向上查找到 /monorepo/.git
  source: __dirname, // 子包目录

  seeConfig: {
    system: 'monorepo-system',
    type: 'subsystem',
    name: 'my-app',
    version: '1.0.0',
    description: 'Monorepo 中的子应用',
    outputName: 'dist',
    // 工具会自动获取正确的 git hash,即使在子包中运行
    isProduction: process.env.NODE_ENV === 'production'
  },

  ftpConfig: {
    user: process.env.FTP_USER,
    password: process.env.FTP_PASSWORD,
    host: 'example.com',
    port: 22,
    localPath: './dist',
    remotePath: '/var/www/html/my-app',
    include: ['*', '**/*'],
    exclude: ['**/*.map'],
    sftp: true
  }
};

在 package.json 中配置

{
  "name": "my-app",
  "version": "1.0.0",
  "scripts": {
    "build": "npm run build:prod",
    "deploy:see": "deploy-cli see",
    "deploy:ftp": "deploy-cli ftp",
    "deploy": "npm run build && deploy-cli see && deploy-cli ftp"
  },
  "deploy": {
    "seeConfig": {
      "system": "my-system",
      "type": "subsystem",
      "outputName": "dist"
    },
    "ftpConfig": {
      "user": "deploy",
      "host": "example.com",
      "port": 22,
      "localPath": "./dist",
      "remotePath": "/var/www/html",
      "include": ["*", "**/*"],
      "exclude": ["**/*.map"],
      "sftp": true
    }
  }
}

环境变量配置

为了安全起见,建议将敏感信息通过环境变量配置:

# .env 文件
FTP_USER=deploy-user
FTP_PASSWORD=your-secure-password
FTP_HOST=your-server.com
FTP_PORT=22
NODE_ENV=production
// deploy.config.js
require('dotenv').config();

module.exports = {
  ftpConfig: {
    user: process.env.FTP_USER,
    password: process.env.FTP_PASSWORD,
    host: process.env.FTP_HOST
    // ... 其他配置
  }
};

自定义配置文件路径

# 使用自定义配置文件
deploy-cli see --config ./build/deploy.config.js
deploy-cli ftp --config ./config/production.js

# 使用相对路径
deploy-cli see --config ../shared/deploy.config.js

错误处理和调试

常见错误及解决方案

  1. 配置文件未找到

    Error: Configuration file not found

    解决方案:确保配置文件存在且路径正确

  2. SEE 包生成失败

    Error: Failed to generate SEE package

    解决方案:检查 outputName 目录是否存在,确保有足够的磁盘空间

  3. FTP 连接失败

    Error: FTP connection failed

    解决方案:检查网络连接、服务器地址、端口和凭据

调试模式

# 启用详细日志
DEBUG=deploy-cli* deploy-cli see
DEBUG=deploy-cli* deploy-cli ftp

最佳实践

1. 配置管理

// 使用配置工厂函数
function createConfig(env) {
  const baseConfig = {
    seeConfig: {
      system: 'my-system',
      type: 'subsystem'
    }
  };

  const envConfigs = {
    development: {
      ftpConfig: {
        host: 'dev.example.com',
        deleteRemote: false
      }
    },
    production: {
      ftpConfig: {
        host: 'prod.example.com',
        deleteRemote: true
      }
    }
  };

  return {
    ...baseConfig,
    ...envConfigs[env]
  };
}

module.exports = createConfig(process.env.NODE_ENV || 'development');

2. 安全配置

// 使用环境变量和配置验证
const requiredEnvVars = ['FTP_USER', 'FTP_PASSWORD', 'FTP_HOST'];
const missingVars = requiredEnvVars.filter((varName) => !process.env[varName]);

if (missingVars.length > 0) {
  throw new Error(`Missing required environment variables: ${missingVars.join(', ')}`);
}

module.exports = {
  ftpConfig: {
    user: process.env.FTP_USER,
    password: process.env.FTP_PASSWORD,
    host: process.env.FTP_HOST
    // ... 其他配置
  }
};

3. 脚本集成

{
  "scripts": {
    "build": "npm run build:prod",
    "deploy:dev": "NODE_ENV=development deploy-cli deploy",
    "deploy:staging": "NODE_ENV=staging deploy-cli deploy",
    "deploy:prod": "NODE_ENV=production deploy-cli deploy",
    "deploy": "npm run build && npm run deploy:prod"
  }
}

4. Monorepo 环境最佳实践

// packages/my-app/package.json
{
  "name": "@my-org/my-app",
  "version": "1.0.0",
  "scripts": {
    "build": "vite build",
    "deploy:dev": "NODE_ENV=development deploy-cli deploy",
    "deploy:prod": "NODE_ENV=production deploy-cli deploy"
  }
}
// packages/my-app/deploy.config.js
module.exports = {
  // 当前子包目录
  source: __dirname,

  seeConfig: {
    system: 'my-system',
    type: 'subsystem',
    name: 'my-app',
    version: require('./package.json').version,
    description: require('./package.json').description,
    outputName: 'dist',
    // 工具会自动向上查找 git 仓库,获取正确的 git hash
    isProduction: process.env.NODE_ENV === 'production'
  },

  ftpConfig: {
    // 使用环境变量配置敏感信息
    user: process.env.FTP_USER,
    password: process.env.FTP_PASSWORD,
    host: process.env.FTP_HOST,
    port: parseInt(process.env.FTP_PORT || '22'),
    localPath: './dist',
    remotePath: `/var/www/html/${require('./package.json').name}`,
    include: ['*', '**/*'],
    exclude: ['**/*.map', '**/*.log'],
    sftp: true
  }
};

注意事项

  1. 配置文件优先级: 命令行 --config 参数 > 项目根目录配置文件 > package.json
  2. 环境变量: 建议使用环境变量管理敏感信息
  3. 路径处理: 所有路径都相对于 source 配置的目录
  4. Monorepo 支持: 工具会自动向上查找 .git 目录,支持在子包中运行并正确获取 git 信息
  5. Docker 部署: 使用 Docker 模式时,确保镜像已构建并推送到仓库
  6. 网络连接: FTP/SFTP 部署需要确保网络连接和防火墙配置正确

更新日志

最新更新

  • Monorepo 支持增强: 新增智能 git 目录查找功能,支持在 monorepo 子包中正确获取 git 信息
  • 类型安全改进: 修复了 TypeScript 类型错误,提供更好的类型支持
  • API 改进: 将部分内部工具函数暴露为公共 API,方便扩展使用

详细的更新日志请查看 CHANGELOG.md

许可证

ISC License

贡献

欢迎提交 Issue 和 Pull Request 来改进这个项目。

相关项目

Package Sidebar

Install

npm i @winner-fed/deploy-cli

Weekly Downloads

22

Version

1.0.0

License

ISC

Unpacked Size

66.7 kB

Total Files

8

Last publish

Collaborators

  • winner-fed