# Gulp Build Tools 基于 Gulp 的构建文件调整工具库,提供文件重命名、内容替换、上传、压缩、Git操作和SSH执行等功能。 ## 特性 - 🔄 **文件重命名** - 支持文件和文件夹的批量重命名 - 📝 **内容替换** - 支持基于正则表达式的文件内容替换 - 🚀 **文件上传** - 支持 FTP/SFTP 文件上传 - 📦 **文件压缩** - 支持 ZIP、TAR、GZIP 等格式压缩 - 🔧 **Git 操作** - 支持提交、拉取、分支切换等 Git 操作 - 🖥️ **SSH 执行** - 支持远程 SSH 命令执行 - ⚡ **任务组合** - 支持并行和串行任务组合 - 📊 **多任务支持** - Git、Upload、SSH 支持多任务并行/串行执行 - 🎯 **预设模板** - 提供常用的部署预设模板 ## 安装 ```bash npm install @baota/gulp-build-tools # 或 pnpm add @baota/gulp-build-tools ``` ## 快速开始 ```javascript import { createBuildTools } from '@baota/gulp-build-tools'; import { task } from 'gulp'; // 创建构建工具实例 const buildTools = createBuildTools({ verbose: true // 显示详细日志 }); // 文件重命名任务 task('rename', buildTools.renameFiles({ src: 'src/**/*.js', rename: (path) => { path.basename += '.min'; }, dest: 'dist' })); // 内容替换任务 task('replace', buildTools.replaceContent({ src: 'dist/**/*.html', replacements: [ { search: '{{VERSION}}', replace: '1.0.0' } ], dest: 'dist' })); // 文件压缩任务 task('compress', buildTools.compressFiles({ src: 'dist/**/*', filename: 'release.zip', dest: 'releases' })); // 组合任务 task('build', buildTools.createBuildPipeline({ replace: [{ src: 'src/**/*.js', replacements: [{ search: 'development', replace: 'production' }], dest: 'dist' }], compress: { src: 'dist/**/*', filename: 'app.zip', dest: 'releases' } })); ``` ## API 文档 ### 文件重命名 #### `renameFiles(config: RenameConfig)` 重命名文件或文件夹。 ```javascript // 基本重命名 buildTools.renameFiles({ src: 'src/**/*.js', rename: 'new-name.js', // 字符串 dest: 'dist' }); // 使用函数重命名 buildTools.renameFiles({ src: 'src/**/*.js', rename: (path) => { path.basename = path.basename.replace('old', 'new'); }, dest: 'dist' }); // 使用助手函数 import { helpers } from '@baota/gulp-build-tools'; buildTools.renameFiles({ src: 'src/**/*.js', rename: helpers.rename.addPrefix('prod-'), dest: 'dist' }); ``` #### 重命名助手函数 ```javascript const { rename } = helpers; // 添加前缀 rename.addPrefix('prefix-') // 添加后缀 rename.addSuffix('-suffix') // 更改扩展名 rename.changeExtension('.min.js') // 添加时间戳 rename.addTimestamp() // 转换大小写 rename.toLowerCase() rename.toUpperCase() // 替换文件名中的字符 rename.replaceInName(/old/g, 'new') ``` ### 文件内容替换 #### `replaceContent(config: ReplaceConfig)` 替换文件内容。 ```javascript // 基本替换 buildTools.replaceContent({ src: 'dist/**/*.html', replacements: [ { search: '{{TITLE}}', replace: 'My App' }, { search: /\{\{VERSION\}\}/g, replace: '1.0.0' } ], dest: 'dist' }); // 使用函数替换 buildTools.replaceContent({ src: 'dist/**/*.js', replacements: [ { search: /console\.log\([^)]*\);?/g, replace: (match) => { return ''; // 移除所有 console.log } } ], dest: 'dist' }); ``` #### 替换模式助手 ```javascript const { replace } = helpers; // 替换版本号 replace.version('2.0.0') // 替换 API URL replace.apiBaseUrl('https://api.example.com') // 替换环境变量 replace.envVariable('NODE_ENV', 'production') // 替换 HTML 标题 replace.htmlTitle('New Title') // 替换时间戳 replace.timestamp() ``` ### 文件上传 #### `uploadFiles(config: UploadConfig)` 上传文件到 FTP 或 SFTP 服务器。 ```javascript // SFTP 上传 buildTools.uploadFiles({ type: 'sftp', host: 'example.com', username: 'user', password: 'password', // 或使用私钥: privateKey: '/path/to/key', remotePath: '/var/www/html', src: 'dist/**/*', parallel: true, clean: true // 上传前清空远程目录 }); // FTP 上传 buildTools.uploadFiles({ type: 'ftp', host: 'ftp.example.com', username: 'user', password: 'password', remotePath: '/public_html', src: 'dist/**/*' }); ``` ### 文件压缩 #### `compressFiles(config: CompressConfig)` 压缩文件。 ```javascript // ZIP 压缩 buildTools.compressFiles({ src: 'dist/**/*', filename: 'release.zip', dest: 'releases', level: 6 // 压缩级别 0-9 }); // TAR 压缩 buildTools.compressFiles({ src: 'dist/**/*', filename: 'release.tar', dest: 'releases', type: 'tar' }); // GZIP 压缩 buildTools.compressFiles({ src: 'dist/**/*', filename: 'release.tar.gz', dest: 'releases', type: 'gzip' }); ``` #### 压缩助手函数 ```javascript const { compress } = helpers; // 创建压缩配置 compress.createConfig('dist/**/*', 'app.zip', 'releases') // 根据文件名推断类型 compress.inferType('app.tar.gz') // 'gzip' // 生成带时间戳的文件名 compress.timestampedFilename('backup') // 'backup-2024-01-01T12-00-00.zip' // 获取推荐压缩级别 compress.getCompressionLevel('speed') // 1 compress.getCompressionLevel('size') // 9 compress.getCompressionLevel('balanced') // 6 ``` ### Git 操作 #### `gitOperation(config: GitConfig)` 执行 Git 操作。 ```javascript // 提交代码 buildTools.gitOperation({ action: 'commit', message: '发布版本 1.0.0', files: ['dist/**/*', 'package.json'] }); // 拉取代码 buildTools.gitOperation({ action: 'pull', remote: 'origin', branch: 'main' }); // 推送代码 buildTools.gitOperation({ action: 'push', remote: 'origin', branch: 'main' }); // 切换分支 buildTools.gitOperation({ action: 'checkout', branch: 'develop' }); // 创建分支 buildTools.gitOperation({ action: 'branch', branch: 'feature/new-feature' }); // 合并分支 buildTools.gitOperation({ action: 'merge', branch: 'feature/new-feature' }); ``` #### Git 助手函数 ```javascript const { git } = helpers; // 检查仓库状态 const status = await git.checkStatus(); console.log(status.clean); // 是否干净 // 获取当前分支 const branch = await git.getCurrentBranch(); // 检查是否有未提交的更改 const hasChanges = await git.hasUncommittedChanges(); // 获取最新提交信息 const commit = await git.getLatestCommit(); ``` ### SSH 命令执行 #### `sshExecution(config: SSHConfig)` 执行远程 SSH 命令。 ```javascript // 执行单个命令 buildTools.sshExecution({ host: 'example.com', username: 'user', password: 'password', commands: 'pm2 restart all', verbose: true }); // 执行多个命令 buildTools.sshExecution({ host: 'example.com', username: 'user', privateKey: '/path/to/private/key', commands: [ 'cd /var/www/html', 'git pull origin main', 'npm install', 'npm run build', 'pm2 restart all' ] }); ``` #### SSH 助手函数 ```javascript const { ssh } = helpers; // 测试连接 const connected = await ssh.testConnection({ host: 'example.com', username: 'user', password: 'password' }); // 执行单个命令 const result = await ssh.executeCommand( { host: 'example.com', username: 'user', password: 'password' }, 'ls -la' ); // 使用命令模板 ssh.commands.restartService('nginx') ssh.commands.checkService('mysql') ssh.commands.deployApp('/var/www/myapp') ssh.commands.cleanLogs('/var/log', 7) ssh.commands.checkDiskSpace() ``` ## 多任务支持 从 v1.1.0 开始,Git、Upload 和 SSH 功能支持多任务执行,可以同时对多个目标执行操作。 ### 多 Git 操作 ```javascript // 串行执行多个 Git 操作 task('git-multi-serial', buildTools.multiGitOperation([ { action: 'commit', message: '提交当前更改', files: '.' }, { action: 'push', remote: 'origin', branch: 'main' } ], false)); // false = 串行执行 // 并行执行多个 Git 操作(不同仓库) task('git-multi-parallel', buildTools.multiGitOperation([ { action: 'pull', repoPath: '/path/to/repo1', remote: 'origin', branch: 'main' }, { action: 'pull', repoPath: '/path/to/repo2', remote: 'origin', branch: 'develop' } ], true)); // true = 并行执行 ``` ### 多服务器上传 ```javascript // 并行上传到多个服务器 task('upload-multi', buildTools.multiUpload([ { type: 'sftp', host: 'server1.example.com', username: 'deploy', privateKey: '/path/to/key1', remotePath: '/var/www/app', src: 'dist/**/*' }, { type: 'ftp', host: 'server2.example.com', username: 'deploy', password: 'password', remotePath: '/public_html', src: 'dist/**/*' }, { type: 'sftp', host: 'server3.example.com', username: 'deploy', privateKey: '/path/to/key3', remotePath: '/var/www/app', src: 'dist/**/*' } ], true)); // 并行上传 ``` ### 多 SSH 任务 ```javascript // 并行执行多个 SSH 任务 task('ssh-multi', buildTools.multiSSHExecution([ { host: 'web1.example.com', username: 'deploy', privateKey: '/path/to/key', commands: [ 'pm2 restart web-app', 'pm2 status' ] }, { host: 'web2.example.com', username: 'deploy', privateKey: '/path/to/key', commands: [ 'pm2 restart web-app', 'pm2 status' ] }, { host: 'api.example.com', username: 'deploy', privateKey: '/path/to/key', commands: [ 'docker restart api-container', 'docker ps' ] } ], true)); // 并行执行 ``` ### 多任务优势 1. **提高效率**: 并行执行多个任务,显著减少部署时间 2. **错误处理**: 单个任务失败不会影响其他任务 3. **进度可视**: 实时显示每个任务的执行状态 4. **灵活配置**: 可以选择并行或串行执行模式 ### 复合部署流水线 ```javascript // 生产环境多服务器部署 task('deploy:production', series( // 1. 构建和打包 buildTools.replaceContent({ src: 'src/**/*.js', replacements: [{ search: '{{ENV}}', replace: 'production' }], dest: 'dist' }), // 2. 并行上传到多个服务器 buildTools.multiUpload([ { type: 'sftp', host: 'prod-web1.example.com', username: 'deploy', privateKey: '/path/to/key', remotePath: '/var/www/app', src: 'dist/**/*' }, { type: 'sftp', host: 'prod-web2.example.com', username: 'deploy', privateKey: '/path/to/key', remotePath: '/var/www/app', src: 'dist/**/*' } ], true), // 3. 并行重启所有服务 buildTools.multiSSHExecution([ { host: 'prod-web1.example.com', username: 'deploy', privateKey: '/path/to/key', commands: ['pm2 restart app', 'nginx -s reload'] }, { host: 'prod-web2.example.com', username: 'deploy', privateKey: '/path/to/key', commands: ['pm2 restart app', 'nginx -s reload'] } ], true) )); ``` ## 预设模板 ### 前端项目部署 ```javascript import { presets } from '@baota/gulp-build-tools'; // Vue/React 项目部署 const deployConfig = presets.frontend.vueDeploy({ buildDir: 'dist', serverConfig: { type: 'sftp', host: 'example.com', username: 'user', password: 'password', remotePath: '/var/www/html' }, sshConfig: { host: 'example.com', username: 'user', password: 'password', commands: ['nginx -s reload'] } }); task('deploy', buildTools.createBuildPipeline(deployConfig)); ``` ### 后端项目部署 ```javascript // Node.js 项目部署 const deployConfig = presets.backend.nodeDeploy({ appPath: '/var/www/myapp', serverConfig: { type: 'sftp', host: 'example.com', username: 'user', password: 'password', remotePath: '/var/www/myapp' }, sshConfig: { host: 'example.com', username: 'user', password: 'password', commands: [] } }); task('deploy', buildTools.createBuildPipeline(deployConfig)); ``` ## 批量操作 ```javascript import { batchOperations } from '@baota/gulp-build-tools'; // 批量重命名 const renameResults = await batchOperations.rename([ { src: 'src/**/*.js', rename: 'bundle.js', dest: 'dist' }, { src: 'src/**/*.css', rename: 'style.css', dest: 'dist' } ]); // 批量上传 const uploadResults = await batchOperations.upload([ { type: 'sftp', host: 'server1.com', ... }, { type: 'ftp', host: 'server2.com', ... } ]); ``` ## 完整示例 ```javascript import { createBuildTools, presets } from '@baota/gulp-build-tools'; import { task, series } from 'gulp'; const buildTools = createBuildTools({ verbose: true }); // 构建任务 task('build', buildTools.createBuildPipeline({ // 替换版本号和环境变量 replace: [{ src: 'src/**/*.js', replacements: [ { search: '{{VERSION}}', replace: '1.0.0' }, { search: 'development', replace: 'production' } ], dest: 'dist' }], // 重命名文件 rename: [{ src: 'dist/**/*.js', rename: (path) => path.basename += '.min', dest: 'dist' }], // 压缩文件 compress: { src: 'dist/**/*', filename: 'release-1.0.0.zip', dest: 'releases' } })); // 部署任务 task('deploy', buildTools.createBuildPipeline({ // 上传到服务器 upload: { type: 'sftp', host: 'example.com', username: 'deploy', privateKey: '~/.ssh/id_rsa', remotePath: '/var/www/html', src: 'dist/**/*', clean: true }, // 重启服务 ssh: { host: 'example.com', username: 'deploy', privateKey: '~/.ssh/id_rsa', commands: [ 'sudo systemctl reload nginx', 'pm2 restart all' ] } })); // Git 工作流 task('release', series( buildTools.gitOperation({ action: 'commit', message: 'Release 1.0.0', files: '.' }), buildTools.gitOperation({ action: 'push', remote: 'origin', branch: 'main' }) )); // 完整流水线 task('full-deploy', series('build', 'release', 'deploy')); ``` ## 错误处理 所有任务都支持错误处理,可以通过回调函数或 Promise 的方式处理错误: ```javascript // 使用回调 task('example', (cb) => { const stream = buildTools.renameFiles(config); stream.on('error', (error) => { console.error('任务执行失败:', error); cb(error); }); stream.on('end', () => { console.log('任务执行成功'); cb(); }); return stream; }); // 使用批量操作的 Promise task('batch-example', async () => { try { const results = await batchOperations.upload(configs); results.forEach(result => { if (result.success) { console.log('成功:', result.message); } else { console.error('失败:', result.error); } }); } catch (error) { console.error('批量操作失败:', error); } }); ``` ## 许可证 MIT