fe-build-cli 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +430 -0
- package/package.json +41 -0
- package/src/cli.js +492 -0
- package/src/config-template.js +83 -0
- package/src/deploy-core.js +326 -0
- package/src/dingtalk.js +238 -0
- package/src/git-branch.js +259 -0
- package/src/index.d.ts +330 -0
- package/src/index.js +47 -0
- package/src/ssh-client.js +153 -0
package/README.md
ADDED
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
# fe-build-cli
|
|
2
|
+
|
|
3
|
+
前端项目打包部署 CLI 工具,支持多服务器部署、Git 分支管理、回滚等功能。
|
|
4
|
+
|
|
5
|
+
## 功能特性
|
|
6
|
+
|
|
7
|
+
- ✅ 多服务器环境部署
|
|
8
|
+
- ✅ 两种发布模式:主分支发布 / 当前分支发布
|
|
9
|
+
- ✅ Git 分支自动合并流程
|
|
10
|
+
- ✅ SSH 远程部署(带进度条)
|
|
11
|
+
- ✅ 自动备份与回滚
|
|
12
|
+
- ✅ 保护目录(部署时不删除指定目录)
|
|
13
|
+
- ✅ TypeScript 类型支持
|
|
14
|
+
|
|
15
|
+
## 流程图
|
|
16
|
+
|
|
17
|
+
查看详细的部署流程图:[docs/flow-diagram.html](docs/flow-diagram.html)
|
|
18
|
+
|
|
19
|
+
流程图包含:
|
|
20
|
+
- 主分支发布模式流程
|
|
21
|
+
- 当前分支发布模式流程
|
|
22
|
+
- 部署详细步骤(8 步)
|
|
23
|
+
- 回滚流程
|
|
24
|
+
|
|
25
|
+
## 安装
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# 全局安装
|
|
29
|
+
npm install -g fe-build-cli
|
|
30
|
+
|
|
31
|
+
# 或在项目中安装
|
|
32
|
+
npm install fe-build-cli --save-dev
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 快速开始
|
|
36
|
+
|
|
37
|
+
### 1. 创建配置文件
|
|
38
|
+
|
|
39
|
+
在项目根目录创建 `fe-build.config.js`:
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
import process from 'node:process';
|
|
43
|
+
|
|
44
|
+
export default {
|
|
45
|
+
// 分支配置(用于主分支发布模式)
|
|
46
|
+
branches: {
|
|
47
|
+
test: 'test', // 测试分支名
|
|
48
|
+
main: 'main' // 主分支名
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
// 发布模式:'main'(主分支发布)或 'current'(当前分支发布)
|
|
52
|
+
deployMode: 'main',
|
|
53
|
+
|
|
54
|
+
// 服务器配置
|
|
55
|
+
servers: {
|
|
56
|
+
production: {
|
|
57
|
+
sshHost: 'your-server.com',
|
|
58
|
+
sshUser: 'deployer',
|
|
59
|
+
sshKeyPath: `${process.env.USERPROFILE || process.env.HOME}/.ssh/id_rsa`,
|
|
60
|
+
deployUrl: 'https://your-domain.com',
|
|
61
|
+
backupDir: '/www/backups/your-app',
|
|
62
|
+
deployDir: '/www/your-app',
|
|
63
|
+
backupPrefix: 'backup-production',
|
|
64
|
+
buildMode: 'production',
|
|
65
|
+
protectedDirs: ['webgl', 'uploads']
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
test: {
|
|
69
|
+
sshHost: 'test-server.com',
|
|
70
|
+
sshUser: 'deployer',
|
|
71
|
+
sshKeyPath: `${process.env.USERPROFILE || process.env.HOME}/.ssh/id_rsa`,
|
|
72
|
+
deployUrl: 'https://test.your-domain.com',
|
|
73
|
+
backupDir: '/www/backups/test-app',
|
|
74
|
+
deployDir: '/www/test-app',
|
|
75
|
+
backupPrefix: 'backup-test',
|
|
76
|
+
buildMode: 'test',
|
|
77
|
+
protectedDirs: ['webgl']
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 2. 执行部署
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# 交互式选择环境部署
|
|
87
|
+
fe-build
|
|
88
|
+
|
|
89
|
+
# 直接部署到指定环境
|
|
90
|
+
fe-build deploy production
|
|
91
|
+
|
|
92
|
+
# 部署到所有环境
|
|
93
|
+
fe-build deploy all
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 命令说明
|
|
97
|
+
|
|
98
|
+
### deploy(部署)
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
fe-build [deploy] [环境] [选项]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
| 参数 | 说明 |
|
|
105
|
+
|------|------|
|
|
106
|
+
| `环境` | 目标环境名称(如 production、test),或 `all` 部署到所有环境 |
|
|
107
|
+
| `--config <路径>` | 指定配置文件路径 |
|
|
108
|
+
| `--current-branch` | 使用当前分支发布(不切换分支) |
|
|
109
|
+
| `--main-branch` | 使用主分支发布流程 |
|
|
110
|
+
| `--skip-build` | 跳过构建步骤 |
|
|
111
|
+
| `--no-push` | 主分支发布时不推送到远程 |
|
|
112
|
+
|
|
113
|
+
**示例:**
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# 交互式部署
|
|
117
|
+
fe-build
|
|
118
|
+
|
|
119
|
+
# 部署到生产环境
|
|
120
|
+
fe-build deploy production
|
|
121
|
+
|
|
122
|
+
# 当前分支发布(不切换分支)
|
|
123
|
+
fe-build --current-branch
|
|
124
|
+
|
|
125
|
+
# 主分支发布流程
|
|
126
|
+
fe-build --main-branch
|
|
127
|
+
|
|
128
|
+
# 跳过构建,仅上传部署
|
|
129
|
+
fe-build --skip-build
|
|
130
|
+
|
|
131
|
+
# 使用指定配置文件
|
|
132
|
+
fe-build --config ./custom-config.js
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### rollback(回滚)
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
fe-build rollback [环境] [--version <版本号>]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
| 参数 | 说明 |
|
|
142
|
+
|------|------|
|
|
143
|
+
| `环境` | 目标环境名称 |
|
|
144
|
+
| `--version <版本号>` | 指定回滚版本(可选,默认回滚到上一版本) |
|
|
145
|
+
|
|
146
|
+
**示例:**
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# 回滚生产环境到上一版本
|
|
150
|
+
fe-build rollback production
|
|
151
|
+
|
|
152
|
+
# 回滚到指定版本
|
|
153
|
+
fe-build rollback production --version build-20240101-abc123
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### help(帮助)
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
fe-build help
|
|
160
|
+
fe-build --help
|
|
161
|
+
fe-build -h
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## 发布模式详解
|
|
165
|
+
|
|
166
|
+
### 主分支发布模式(默认)
|
|
167
|
+
|
|
168
|
+
流程:当前分支 → 测试分支 → 主分支 → 部署
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
172
|
+
│ 当前分支 │ ──► │ 测试分支 │ ──► │ 主分支 │ ──► │ 部署 │
|
|
173
|
+
│ (feature) │ │ (test) │ │ (main) │ │ (服务器) │
|
|
174
|
+
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**适用场景:** 正式发布,需要经过测试分支验证
|
|
178
|
+
|
|
179
|
+
**执行步骤:**
|
|
180
|
+
1. 检查工作区是否干净
|
|
181
|
+
2. 切换到测试分支,拉取最新代码
|
|
182
|
+
3. 合并当前分支到测试分支
|
|
183
|
+
4. 推送测试分支到远程
|
|
184
|
+
5. 切换到主分支,拉取最新代码
|
|
185
|
+
6. 合并测试分支到主分支
|
|
186
|
+
7. 推送主分支到远程
|
|
187
|
+
8. 执行构建和部署
|
|
188
|
+
9. 可选择切回原分支
|
|
189
|
+
|
|
190
|
+
### 当前分支发布模式
|
|
191
|
+
|
|
192
|
+
流程:当前分支 → 直接部署
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
┌─────────────┐ ┌─────────────┐
|
|
196
|
+
│ 当前分支 │ ──► │ 部署 │
|
|
197
|
+
│ (feature) │ │ (服务器) │
|
|
198
|
+
└─────────────┘ └─────────────┘
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**适用场景:** 快速测试、临时发布、开发调试
|
|
202
|
+
|
|
203
|
+
**执行步骤:**
|
|
204
|
+
1. 获取当前分支信息
|
|
205
|
+
2. 执行构建和部署(不切换分支)
|
|
206
|
+
|
|
207
|
+
## 配置文件详解
|
|
208
|
+
|
|
209
|
+
### 完整配置示例
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
import process from 'node:process';
|
|
213
|
+
|
|
214
|
+
export default {
|
|
215
|
+
// 分支配置
|
|
216
|
+
branches: {
|
|
217
|
+
test: 'test', // 测试分支名(必填,主分支模式需要)
|
|
218
|
+
main: 'main' // 主分支名(必填,主分支模式需要)
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
// 发布模式
|
|
222
|
+
deployMode: 'main', // 'main' 或 'current'
|
|
223
|
+
|
|
224
|
+
// 服务器配置
|
|
225
|
+
servers: {
|
|
226
|
+
production: {
|
|
227
|
+
// SSH 连接配置
|
|
228
|
+
sshHost: '101.44.66.5', // 服务器 IP 或域名(必填)
|
|
229
|
+
sshUser: 'deployer', // SSH 用户名(必填)
|
|
230
|
+
sshKeyPath: `${process.env.USERPROFILE || process.env.HOME}/.ssh/id_rsa`, // SSH 私钥路径(必填)
|
|
231
|
+
sshPort: 22, // SSH 端口(可选,默认 22)
|
|
232
|
+
|
|
233
|
+
// 部署配置
|
|
234
|
+
deployUrl: 'https://www.example.com', // 部署后访问地址(必填)
|
|
235
|
+
backupDir: '/www/backups/example', // 备份目录(必填)
|
|
236
|
+
deployDir: '/www/example', // 部署目录(必填)
|
|
237
|
+
backupPrefix: 'backup-production', // 备份文件前缀(必填)
|
|
238
|
+
|
|
239
|
+
// 构建配置
|
|
240
|
+
buildMode: 'production', // 构建模式:production 或 test
|
|
241
|
+
buildCommand: 'yarn build', // 自定义构建命令(可选)
|
|
242
|
+
|
|
243
|
+
// 保护目录(部署时不删除)
|
|
244
|
+
protectedDirs: ['webgl', 'uploads', 'static']
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
// 备份保留数量(可选,默认 1)
|
|
249
|
+
backupRetentionCount: 3,
|
|
250
|
+
|
|
251
|
+
// 钉钉通知配置(可选)
|
|
252
|
+
dingtalk: {
|
|
253
|
+
webhook: 'https://oapi.dingtalk.com/robot/send?access_token=your-token', // 钉钉机器人 webhook
|
|
254
|
+
enabled: true // 是否启用通知,默认 true
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### 配置项说明
|
|
260
|
+
|
|
261
|
+
| 配置项 | 类型 | 必填 | 说明 |
|
|
262
|
+
|--------|------|------|------|
|
|
263
|
+
| `branches.test` | string | 主分支模式必填 | 测试分支名 |
|
|
264
|
+
| `branches.main` | string | 主分支模式必填 | 主分支名 |
|
|
265
|
+
| `deployMode` | string | 否 | 发布模式,默认 `main` |
|
|
266
|
+
| `servers` | object | 是 | 服务器配置对象 |
|
|
267
|
+
| `servers[key].sshHost` | string | 是 | 服务器 IP 或域名 |
|
|
268
|
+
| `servers[key].sshUser` | string | 是 | SSH 用户名 |
|
|
269
|
+
| `servers[key].sshKeyPath` | string | 是 | SSH 私钥路径 |
|
|
270
|
+
| `servers[key].sshPort` | number | 否 | SSH 端口,默认 22 |
|
|
271
|
+
| `servers[key].deployUrl` | string | 是 | 部署后访问地址 |
|
|
272
|
+
| `servers[key].backupDir` | string | 是 | 备份目录 |
|
|
273
|
+
| `servers[key].deployDir` | string | 是 | 部署目录 |
|
|
274
|
+
| `servers[key].backupPrefix` | string | 是 | 备份文件前缀 |
|
|
275
|
+
| `servers[key].buildMode` | string | 否 | 构建模式,默认 production |
|
|
276
|
+
| `servers[key].buildCommand` | string | 否 | 自定义构建命令 |
|
|
277
|
+
| `servers[key].protectedDirs` | string[] | 否 | 保护目录列表 |
|
|
278
|
+
| `backupRetentionCount` | number | 否 | 备份保留数量,默认 1 |
|
|
279
|
+
| `dingtalk.webhook` | string | 否 | 钉钉机器人 webhook URL |
|
|
280
|
+
| `dingtalk.enabled` | boolean | 否 | 是否启用通知,默认 true |
|
|
281
|
+
|
|
282
|
+
## 钉钉通知
|
|
283
|
+
|
|
284
|
+
部署完成后可自动发送钉钉消息通知,支持以下场景:
|
|
285
|
+
|
|
286
|
+
- **部署成功通知**:包含环境、版本、分支、服务器、耗时等信息
|
|
287
|
+
- **部署失败通知**:包含错误信息,便于快速排查
|
|
288
|
+
- **回滚通知**:包含回滚结果和备份文件信息
|
|
289
|
+
|
|
290
|
+
### 配置钉钉机器人
|
|
291
|
+
|
|
292
|
+
1. 在钉钉群中添加机器人,获取 webhook URL
|
|
293
|
+
2. 在配置文件中添加:
|
|
294
|
+
|
|
295
|
+
```javascript
|
|
296
|
+
dingtalk: {
|
|
297
|
+
webhook: 'https://oapi.dingtalk.com/robot/send?access_token=your-token',
|
|
298
|
+
enabled: true
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### 通知消息示例
|
|
303
|
+
|
|
304
|
+
部署成功通知:
|
|
305
|
+
|
|
306
|
+
```
|
|
307
|
+
🚀 部署成功通知
|
|
308
|
+
|
|
309
|
+
环境: production
|
|
310
|
+
状态: ✅ 成功
|
|
311
|
+
时间: 2024-01-01 10:30:00
|
|
312
|
+
|
|
313
|
+
构建版本: build-20240101-abc123
|
|
314
|
+
发布分支: main
|
|
315
|
+
发布模式: 主分支发布
|
|
316
|
+
服务器: 101.44.66.5
|
|
317
|
+
部署耗时: 120秒
|
|
318
|
+
|
|
319
|
+
访问地址: https://www.example.com
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## 部署流程详解
|
|
323
|
+
|
|
324
|
+
### 部署步骤(8 步)
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
[步骤 1/8] 构建项目
|
|
328
|
+
[步骤 2/8] 验证构建输出
|
|
329
|
+
[步骤 3/8] 压缩本地构建产物
|
|
330
|
+
[步骤 4/8] 备份现有部署
|
|
331
|
+
[步骤 5/8] 上传压缩包
|
|
332
|
+
[步骤 6/8] 清理并解压新版本
|
|
333
|
+
[步骤 7/8] 删除压缩包
|
|
334
|
+
[步骤 8/8] 完成
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### 保护目录机制
|
|
338
|
+
|
|
339
|
+
部署时会保护指定的目录不被删除,适用于:
|
|
340
|
+
- 大型静态资源(如 WebGL 文件)
|
|
341
|
+
- 用户上传文件
|
|
342
|
+
- 第三方服务生成的文件
|
|
343
|
+
|
|
344
|
+
配置示例:
|
|
345
|
+
```javascript
|
|
346
|
+
protectedDirs: ['webgl', 'uploads', 'static']
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
部署时这些目录会被保留,不会被新版本覆盖。
|
|
350
|
+
|
|
351
|
+
## API 使用
|
|
352
|
+
|
|
353
|
+
除了 CLI 命令,也可以作为模块在代码中使用:
|
|
354
|
+
|
|
355
|
+
```javascript
|
|
356
|
+
import {
|
|
357
|
+
deployToServer,
|
|
358
|
+
rollbackDeployment,
|
|
359
|
+
executeMainBranchFlow,
|
|
360
|
+
executeCurrentBranchFlow,
|
|
361
|
+
SSHClient
|
|
362
|
+
} from 'fe-build-cli';
|
|
363
|
+
|
|
364
|
+
// 部署到服务器
|
|
365
|
+
await deployToServer({
|
|
366
|
+
environment: 'production',
|
|
367
|
+
envConfig: serverConfig,
|
|
368
|
+
buildVersion: 'build-20240101-abc123'
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// 执行主分支发布流程
|
|
372
|
+
const result = executeMainBranchFlow({
|
|
373
|
+
testBranch: 'test',
|
|
374
|
+
mainBranch: 'main',
|
|
375
|
+
pushToRemote: true
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// 使用 SSH 客户端
|
|
379
|
+
const ssh = new SSHClient(serverConfig);
|
|
380
|
+
await ssh.connect();
|
|
381
|
+
await ssh.execCommand('ls -la');
|
|
382
|
+
await ssh.disconnect();
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
## 兼容旧项目
|
|
386
|
+
|
|
387
|
+
如果你的项目已有 `scripts/deploy.config.js`,可以直接使用,无需迁移:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
# 自动识别 scripts/deploy.config.js
|
|
391
|
+
fe-build
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## 常见问题
|
|
395
|
+
|
|
396
|
+
### 1. SSH 连接失败
|
|
397
|
+
|
|
398
|
+
检查 SSH 配置:
|
|
399
|
+
- 确保 SSH 私钥路径正确
|
|
400
|
+
- 确保服务器已添加到 known_hosts
|
|
401
|
+
- 确保用户有部署目录的写入权限
|
|
402
|
+
|
|
403
|
+
### 2. 构建失败
|
|
404
|
+
|
|
405
|
+
检查构建命令:
|
|
406
|
+
- 确保 `buildCommand` 配置正确
|
|
407
|
+
- 确保项目依赖已安装
|
|
408
|
+
- 确保构建脚本可正常执行
|
|
409
|
+
|
|
410
|
+
### 3. 分支合并冲突
|
|
411
|
+
|
|
412
|
+
主分支发布模式下,如果合并有冲突:
|
|
413
|
+
- 工具会自动中止合并
|
|
414
|
+
- 需要手动解决冲突后重新执行
|
|
415
|
+
|
|
416
|
+
### 4. Windows 路径问题
|
|
417
|
+
|
|
418
|
+
Windows 下 SSH 私钥路径:
|
|
419
|
+
```javascript
|
|
420
|
+
sshKeyPath: `${process.env.USERPROFILE}/.ssh/id_rsa`
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## 版本要求
|
|
424
|
+
|
|
425
|
+
- Node.js >= 18.0.0
|
|
426
|
+
- 支持 ES Module
|
|
427
|
+
|
|
428
|
+
## License
|
|
429
|
+
|
|
430
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fe-build-cli",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "前端项目打包部署 CLI 工具,支持多服务器部署、分支管理、回滚、钉钉通知等功能",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"fe-build": "src/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./src/index.js",
|
|
13
|
+
"types": "./src/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"src",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"deploy",
|
|
25
|
+
"cli",
|
|
26
|
+
"frontend",
|
|
27
|
+
"build",
|
|
28
|
+
"ssh",
|
|
29
|
+
"git",
|
|
30
|
+
"dingtalk"
|
|
31
|
+
],
|
|
32
|
+
"author": "",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18.0.0"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"ssh2": "^1.15.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {}
|
|
41
|
+
}
|