vite-plugin-deploy-ftp 3.3.0 → 3.4.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 +151 -123
- package/dist/index.d.ts +1 -1
- package/dist/index.js +32 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
# vite-plugin-deploy-ftp
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## 介绍
|
|
6
|
-
|
|
7
|
-
`vite-plugin-deploy-ftp` 是一个 Vite 插件,用于将打包后的文件上传到 FTP 服务器。插件支持:
|
|
8
|
-
|
|
9
|
-
- 单个 FTP 服务器配置
|
|
10
|
-
- 多个 FTP 服务器配置(可多选上传目标)
|
|
11
|
-
- 自动备份远程文件
|
|
12
|
-
- 连接重试机制
|
|
13
|
-
- 选择性文件备份
|
|
14
|
-
- 当前版本仅支持 ESM(`import`),不再提供 CommonJS(`require`)入口
|
|
3
|
+
把 Vite 打包后的目录上传到 FTP,适合不想手动打开 FTP 工具、重复拖文件发布的项目。
|
|
15
4
|
|
|
16
5
|
## 安装
|
|
17
6
|
|
|
@@ -19,72 +8,137 @@
|
|
|
19
8
|
pnpm add vite-plugin-deploy-ftp -D
|
|
20
9
|
```
|
|
21
10
|
|
|
22
|
-
##
|
|
11
|
+
## 快速开始
|
|
23
12
|
|
|
24
|
-
|
|
13
|
+
推荐用环境变量控制是否上传,默认本地普通打包不上传,只有明确开启时才发布。
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# .env
|
|
17
|
+
FTP_HOST=ftp.example.com
|
|
18
|
+
FTP_PORT=21
|
|
19
|
+
FTP_USER=username
|
|
20
|
+
FTP_PASSWORD=password
|
|
21
|
+
FTP_PATH=/public_html
|
|
22
|
+
FTP_ALIAS=https://example.com
|
|
23
|
+
DEPLOY_FTP=0
|
|
24
|
+
```
|
|
25
25
|
|
|
26
26
|
```ts
|
|
27
27
|
// vite.config.ts
|
|
28
|
+
import { defineConfig, loadEnv } from 'vite'
|
|
28
29
|
import vitePluginDeployFtp from 'vite-plugin-deploy-ftp'
|
|
29
30
|
|
|
30
|
-
export default {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
31
|
+
export default defineConfig(({ mode }) => {
|
|
32
|
+
const env = loadEnv(mode, process.cwd(), '')
|
|
33
|
+
const shouldDeploy = env.DEPLOY_FTP === '1'
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
plugins: [
|
|
37
|
+
vitePluginDeployFtp({
|
|
38
|
+
open: shouldDeploy,
|
|
39
|
+
autoUpload: true,
|
|
40
|
+
failOnError: true,
|
|
41
|
+
host: env.FTP_HOST,
|
|
42
|
+
port: +(env.FTP_PORT || 21),
|
|
43
|
+
user: env.FTP_USER,
|
|
44
|
+
password: env.FTP_PASSWORD,
|
|
45
|
+
uploadPath: env.FTP_PATH?.split(',').map((path) => path.trim()) || '',
|
|
46
|
+
alias: env.FTP_ALIAS,
|
|
47
|
+
singleBack: true,
|
|
48
|
+
singleBackFiles: ['index.html'],
|
|
49
|
+
}),
|
|
50
|
+
],
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
上传时再打开开关:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# macOS / Linux
|
|
59
|
+
DEPLOY_FTP=1 pnpm build
|
|
60
|
+
|
|
61
|
+
# Windows PowerShell
|
|
62
|
+
$env:DEPLOY_FTP='1'; pnpm build
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`FTP_PATH` 可以写一个目录:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
FTP_PATH=/public_html
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
也可以写多个目录:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
FTP_PATH=/public_html,/backup_html
|
|
47
75
|
```
|
|
48
76
|
|
|
49
|
-
|
|
77
|
+
## 常用配置说明
|
|
78
|
+
|
|
79
|
+
| 参数 | 说明 |
|
|
80
|
+
| ----------------- | -------------------------------------------------------------- |
|
|
81
|
+
| `open` | 是否启用上传。推荐用环境变量控制,避免普通打包时误上传。 |
|
|
82
|
+
| `autoUpload` | 是否跳过“是否上传”的确认。自动发布时建议设为 `true`。 |
|
|
83
|
+
| `failOnError` | 上传失败时是否让命令失败。发布流程里建议设为 `true`。 |
|
|
84
|
+
| `uploadPath` | 上传目录。支持字符串,也支持字符串数组,数组会上传到多个目录。 |
|
|
85
|
+
| `alias` | 访问域名。填写后,上传完成会输出可访问链接。 |
|
|
86
|
+
| `singleBack` | 是否只备份指定文件。通常备份 `index.html` 就够,速度更快。 |
|
|
87
|
+
| `singleBackFiles` | 单文件备份列表,支持子目录文件,例如 `assets/app.js`。 |
|
|
88
|
+
| `ftps` | 多个 FTP 服务器配置。需要发布到多个服务器时使用。 |
|
|
89
|
+
| `defaultFtp` | 多 FTP 时默认选中的服务器名称,可减少手动选择。 |
|
|
90
|
+
| `concurrency` | 同时上传的数量。服务器不稳定时保持默认值更稳。 |
|
|
91
|
+
|
|
92
|
+
## 重要行为说明
|
|
93
|
+
|
|
94
|
+
- 插件只在 Vite 构建结束后上传。
|
|
95
|
+
- `open: false` 时不会上传,也不会检查 FTP 配置。
|
|
96
|
+
- `uploadPath` 传数组时,会把同一份文件依次上传到每个目录。
|
|
97
|
+
- 多 FTP 和多目录可以一起使用,会按“服务器 × 目录”的组合逐个上传。
|
|
98
|
+
- 上传前如果远端目录已有文件,会根据配置询问或执行备份。
|
|
99
|
+
- `singleBack: true` 时,只备份 `singleBackFiles` 里的文件。
|
|
100
|
+
- `autoUpload: false` 时,上传前会询问是否继续。
|
|
101
|
+
- 上传失败且 `failOnError: true` 时,构建命令会失败,方便发布系统拦截。
|
|
102
|
+
- 当前版本仅支持 ESM,也就是 `import`,不支持 `require`。
|
|
103
|
+
|
|
104
|
+
## 风险提示
|
|
105
|
+
|
|
106
|
+
- 不建议把 FTP 用户名、密码直接写进 `vite.config.ts`,推荐放到环境变量里。
|
|
107
|
+
- 生产发布建议使用 `open` 环境变量开关,避免普通打包误传线上目录。
|
|
108
|
+
- `uploadPath` 写成数组时,会上传到多个目录,请确认每个目录都是预期目标。
|
|
109
|
+
- 完整备份会下载远端目录并重新上传压缩包,远端文件多时会比较慢。
|
|
110
|
+
- 如果 FTP 服务器不稳定,不建议把 `concurrency` 调太高。
|
|
111
|
+
|
|
112
|
+
## 示例
|
|
113
|
+
|
|
114
|
+
### 多个 FTP 服务器
|
|
50
115
|
|
|
51
116
|
```ts
|
|
52
|
-
// vite.config.ts
|
|
53
117
|
import vitePluginDeployFtp from 'vite-plugin-deploy-ftp'
|
|
54
118
|
|
|
55
119
|
export default {
|
|
56
120
|
plugins: [
|
|
57
121
|
vitePluginDeployFtp({
|
|
58
|
-
open:
|
|
122
|
+
open: process.env.DEPLOY_FTP === '1',
|
|
123
|
+
autoUpload: true,
|
|
59
124
|
uploadPath: '/public_html',
|
|
60
|
-
|
|
61
|
-
singleBackFiles: ['index.html'],
|
|
62
|
-
maxRetries: 3,
|
|
63
|
-
retryDelay: 1000,
|
|
125
|
+
defaultFtp: 'production',
|
|
64
126
|
ftps: [
|
|
65
127
|
{
|
|
66
|
-
name: '
|
|
67
|
-
host:
|
|
68
|
-
port: 21,
|
|
69
|
-
user: 'prod_user',
|
|
70
|
-
password: 'prod_password',
|
|
71
|
-
alias: 'https://production.com',
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
name: '测试环境',
|
|
75
|
-
host: 'ftp.test.com',
|
|
128
|
+
name: 'production',
|
|
129
|
+
host: process.env.FTP_PROD_HOST,
|
|
76
130
|
port: 21,
|
|
77
|
-
user:
|
|
78
|
-
password:
|
|
79
|
-
alias: 'https://
|
|
131
|
+
user: process.env.FTP_PROD_USER,
|
|
132
|
+
password: process.env.FTP_PROD_PASSWORD,
|
|
133
|
+
alias: 'https://example.com',
|
|
80
134
|
},
|
|
81
135
|
{
|
|
82
|
-
name: '
|
|
83
|
-
host:
|
|
136
|
+
name: 'test',
|
|
137
|
+
host: process.env.FTP_TEST_HOST,
|
|
84
138
|
port: 21,
|
|
85
|
-
user:
|
|
86
|
-
password:
|
|
87
|
-
alias: 'https://
|
|
139
|
+
user: process.env.FTP_TEST_USER,
|
|
140
|
+
password: process.env.FTP_TEST_PASSWORD,
|
|
141
|
+
alias: 'https://test.example.com',
|
|
88
142
|
},
|
|
89
143
|
],
|
|
90
144
|
}),
|
|
@@ -92,23 +146,50 @@ export default {
|
|
|
92
146
|
}
|
|
93
147
|
```
|
|
94
148
|
|
|
95
|
-
|
|
149
|
+
### 多个上传目录
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import vitePluginDeployFtp from 'vite-plugin-deploy-ftp'
|
|
153
|
+
|
|
154
|
+
export default {
|
|
155
|
+
plugins: [
|
|
156
|
+
vitePluginDeployFtp({
|
|
157
|
+
open: process.env.DEPLOY_FTP === '1',
|
|
158
|
+
autoUpload: true,
|
|
159
|
+
host: process.env.FTP_HOST,
|
|
160
|
+
user: process.env.FTP_USER,
|
|
161
|
+
password: process.env.FTP_PASSWORD,
|
|
162
|
+
uploadPath: ['/public_html', '/backup_html'],
|
|
163
|
+
alias: 'https://example.com',
|
|
164
|
+
}),
|
|
165
|
+
],
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## 完整配置表
|
|
96
170
|
|
|
97
171
|
### 通用参数
|
|
98
172
|
|
|
99
|
-
| 参数 | 类型
|
|
100
|
-
| ----------------- |
|
|
101
|
-
| `open` | `boolean`
|
|
102
|
-
| `uploadPath` | `string`
|
|
103
|
-
| `singleBack` | `boolean`
|
|
104
|
-
| `singleBackFiles` | `string[]`
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
173
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
174
|
+
| ----------------- | -------------------- | ---------------- | ------------------------------------------------ |
|
|
175
|
+
| `open` | `boolean` | `true` | 是否启用插件 |
|
|
176
|
+
| `uploadPath` | `string \| string[]` | - | FTP 服务器上的上传路径,传数组时会上传到多个目录 |
|
|
177
|
+
| `singleBack` | `boolean` | `false` | 是否使用单文件备份模式 |
|
|
178
|
+
| `singleBackFiles` | `string[]` | `['index.html']` | 单文件备份模式下要备份的文件列表 |
|
|
179
|
+
| `debug` | `boolean` | `false` | 是否输出调试耗时 |
|
|
180
|
+
| `maxRetries` | `number` | `3` | 连接或上传失败时的最大重试次数 |
|
|
181
|
+
| `retryDelay` | `number` | `1000` | 重试延迟时间,单位毫秒 |
|
|
182
|
+
| `showBackFile` | `boolean` | `false` | 是否显示备份文件列表 |
|
|
183
|
+
| `autoUpload` | `boolean` | `false` | 是否跳过上传确认 |
|
|
184
|
+
| `fancy` | `boolean` | `true` | 是否使用更丰富的终端输出 |
|
|
185
|
+
| `failOnError` | `boolean` | `true` | 上传失败时是否中断构建命令 |
|
|
186
|
+
| `concurrency` | `number` | `1` | 同时上传的任务数量 |
|
|
107
187
|
|
|
108
188
|
### 单个 FTP 配置参数
|
|
109
189
|
|
|
110
190
|
| 参数 | 类型 | 默认值 | 说明 |
|
|
111
191
|
| ---------- | -------- | ------ | -------------------------- |
|
|
192
|
+
| `name` | `string` | - | FTP 配置名称 |
|
|
112
193
|
| `host` | `string` | - | FTP 服务器地址 |
|
|
113
194
|
| `port` | `number` | `21` | FTP 服务器端口 |
|
|
114
195
|
| `user` | `string` | - | FTP 用户名 |
|
|
@@ -117,11 +198,12 @@ export default {
|
|
|
117
198
|
|
|
118
199
|
### 多个 FTP 配置参数
|
|
119
200
|
|
|
120
|
-
| 参数
|
|
121
|
-
|
|
|
122
|
-
| `ftps`
|
|
201
|
+
| 参数 | 类型 | 说明 |
|
|
202
|
+
| ------------ | ------------- | ----------------------- |
|
|
203
|
+
| `ftps` | `FtpConfig[]` | FTP 服务器配置数组 |
|
|
204
|
+
| `defaultFtp` | `string` | 默认使用的 FTP 配置名称 |
|
|
123
205
|
|
|
124
|
-
|
|
206
|
+
### FtpConfig 对象
|
|
125
207
|
|
|
126
208
|
| 参数 | 类型 | 默认值 | 说明 |
|
|
127
209
|
| ---------- | -------- | ------ | ---------------------------------- |
|
|
@@ -131,57 +213,3 @@ export default {
|
|
|
131
213
|
| `user` | `string` | - | FTP 用户名 |
|
|
132
214
|
| `password` | `string` | - | FTP 密码 |
|
|
133
215
|
| `alias` | `string` | `''` | 网站别名,用于生成完整 URL |
|
|
134
|
-
|
|
135
|
-
## 功能特性
|
|
136
|
-
|
|
137
|
-
### 多服务器选择
|
|
138
|
-
|
|
139
|
-
当使用多个 FTP 配置时,插件会显示一个多选界面,让您选择要上传到哪些服务器:
|
|
140
|
-
|
|
141
|
-
```
|
|
142
|
-
? 选择要上传的FTP服务器(可多选)
|
|
143
|
-
❯ ◯ 生产环境
|
|
144
|
-
◯ 测试环境
|
|
145
|
-
◯ 开发环境
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### 备份功能
|
|
149
|
-
|
|
150
|
-
插件提供两种备份模式:
|
|
151
|
-
|
|
152
|
-
1. **完整备份**: 将远程目录下的所有文件打包备份
|
|
153
|
-
2. **选择性备份**: 只备份指定的文件(通过 `singleBackFiles` 配置)
|
|
154
|
-
|
|
155
|
-
### 连接重试
|
|
156
|
-
|
|
157
|
-
当 FTP 连接失败时,插件会自动重试,您可以通过 `maxRetries` 和 `retryDelay` 参数控制重试行为。
|
|
158
|
-
|
|
159
|
-
## 环境变量示例
|
|
160
|
-
|
|
161
|
-
建议将敏感信息(如用户名和密码)放在环境变量中:
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
# .env
|
|
165
|
-
VITE_FTP_HOST=ftp.example.com
|
|
166
|
-
VITE_FTP_PORT=21
|
|
167
|
-
VITE_FTP_USER=username
|
|
168
|
-
VITE_FTP_PASSWORD=password
|
|
169
|
-
VITE_FTP_PATH=/public_html
|
|
170
|
-
VITE_FTP_ALIAS=https://example.com
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
```ts
|
|
174
|
-
// vite.config.ts
|
|
175
|
-
export default {
|
|
176
|
-
plugins: [
|
|
177
|
-
vitePluginDeployFtp({
|
|
178
|
-
host: process.env.VITE_FTP_HOST,
|
|
179
|
-
port: +(process.env.VITE_FTP_PORT || 21),
|
|
180
|
-
user: process.env.VITE_FTP_USER,
|
|
181
|
-
password: process.env.VITE_FTP_PASSWORD,
|
|
182
|
-
uploadPath: process.env.VITE_FTP_PATH,
|
|
183
|
-
alias: process.env.VITE_FTP_ALIAS,
|
|
184
|
-
}),
|
|
185
|
-
],
|
|
186
|
-
}
|
|
187
|
-
```
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -135,7 +135,8 @@ var renderPanel = (title, rows, tone = "info", footer) => {
|
|
|
135
135
|
const paddedLabel = padVisual(row.label, labelWidth);
|
|
136
136
|
const prefix = `${paddedLabel} `;
|
|
137
137
|
const availableValueWidth = Math.max(8, innerWidth - stringWidth(prefix));
|
|
138
|
-
|
|
138
|
+
const value = row.preserveValue ? row.value : fitVisual(row.value, availableValueWidth);
|
|
139
|
+
contentLines.push(`${chalk3.gray(prefix)}${value}`);
|
|
139
140
|
}
|
|
140
141
|
}
|
|
141
142
|
if (footer) {
|
|
@@ -144,7 +145,10 @@ var renderPanel = (title, rows, tone = "info", footer) => {
|
|
|
144
145
|
}
|
|
145
146
|
const top = color(`\u256D${"\u2500".repeat(innerWidth + 2)}\u256E`);
|
|
146
147
|
const bottom = color(`\u2570${"\u2500".repeat(innerWidth + 2)}\u256F`);
|
|
147
|
-
const body = contentLines.map((line) =>
|
|
148
|
+
const body = contentLines.map((line) => {
|
|
149
|
+
const fittedLine = stringWidth(line) > innerWidth ? line : fitVisual(line, innerWidth);
|
|
150
|
+
return `${color("\u2502")} ${fittedLine} ${color("\u2502")}`;
|
|
151
|
+
}).join("\n");
|
|
148
152
|
return `${top}
|
|
149
153
|
${body}
|
|
150
154
|
${bottom}`;
|
|
@@ -272,7 +276,8 @@ var renderBackupPanel = (summary) => {
|
|
|
272
276
|
{ label: "\u7ED3\u679C:", value: chalk5.green(`${summary.items.length} \u4E2A\u5907\u4EFD\u6587\u4EF6`) },
|
|
273
277
|
...previewItems.map((item, index) => ({
|
|
274
278
|
label: `\u6587\u4EF6 ${index + 1}:`,
|
|
275
|
-
value: chalk5.cyan(
|
|
279
|
+
value: chalk5.cyan(item),
|
|
280
|
+
preserveValue: true
|
|
276
281
|
}))
|
|
277
282
|
];
|
|
278
283
|
if (summary.items.length > previewItems.length) {
|
|
@@ -311,7 +316,12 @@ function vitePluginDeployFtp(option) {
|
|
|
311
316
|
const isMultiFtp = "ftps" in safeOption;
|
|
312
317
|
const ftpConfigs = isMultiFtp ? safeOption.ftps || [] : [{ ...safeOption, name: safeOption.name || safeOption.alias || safeOption.host }];
|
|
313
318
|
const defaultFtp = isMultiFtp ? safeOption.defaultFtp : void 0;
|
|
314
|
-
const
|
|
319
|
+
const uploadPaths = Array.isArray(uploadPath) ? uploadPath : [uploadPath];
|
|
320
|
+
const normalizedUploadPaths = Array.from(
|
|
321
|
+
new Set(
|
|
322
|
+
uploadPaths.map((targetPath) => typeof targetPath === "string" ? normalizeFtpUploadPath(targetPath) : "/")
|
|
323
|
+
)
|
|
324
|
+
);
|
|
315
325
|
let outDir = normalizePath2(path2.resolve("dist"));
|
|
316
326
|
let upload = false;
|
|
317
327
|
let buildFailed = false;
|
|
@@ -323,7 +333,14 @@ function vitePluginDeployFtp(option) {
|
|
|
323
333
|
};
|
|
324
334
|
const validateOptions = () => {
|
|
325
335
|
const errors = [];
|
|
326
|
-
if (
|
|
336
|
+
if (uploadPaths.length === 0) {
|
|
337
|
+
errors.push("uploadPath is required");
|
|
338
|
+
}
|
|
339
|
+
uploadPaths.forEach((targetPath, index) => {
|
|
340
|
+
if (typeof targetPath !== "string" || targetPath.trim() === "") {
|
|
341
|
+
errors.push(`uploadPath${uploadPaths.length > 1 ? `[${index}]` : ""} is required`);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
327
344
|
if (!Number.isInteger(maxRetries) || maxRetries < 1) errors.push("maxRetries must be >= 1");
|
|
328
345
|
if (!Number.isFinite(retryDelay) || retryDelay < 0) errors.push("retryDelay must be >= 0");
|
|
329
346
|
if (!Number.isInteger(concurrency) || concurrency < 1) errors.push("concurrency must be >= 1");
|
|
@@ -737,7 +754,7 @@ function vitePluginDeployFtp(option) {
|
|
|
737
754
|
);
|
|
738
755
|
return { results, debugEntries };
|
|
739
756
|
};
|
|
740
|
-
const deploySingleTarget = async (ftpConfig) => {
|
|
757
|
+
const deploySingleTarget = async (ftpConfig, normalizedUploadPath) => {
|
|
741
758
|
const { host, port = 21, user, password, alias = "", name } = ftpConfig;
|
|
742
759
|
const normalizedAlias = alias ? normalizeUrlLikeBase(alias) : "";
|
|
743
760
|
if (!host || !user || !password) {
|
|
@@ -757,10 +774,11 @@ function vitePluginDeployFtp(option) {
|
|
|
757
774
|
});
|
|
758
775
|
const totalFiles = allFiles.length;
|
|
759
776
|
const displayName = name || host;
|
|
777
|
+
const resultName = normalizedUploadPaths.length > 1 ? `${displayName} ${normalizedUploadPath}` : displayName;
|
|
760
778
|
const startTime = Date.now();
|
|
761
779
|
if (allFiles.length === 0) {
|
|
762
780
|
console.log(`${getLogSymbol("warning")} \u6CA1\u6709\u627E\u5230\u9700\u8981\u4E0A\u4F20\u7684\u6587\u4EF6`);
|
|
763
|
-
return { name:
|
|
781
|
+
return { name: resultName, totalFiles: 0, failedCount: 0 };
|
|
764
782
|
}
|
|
765
783
|
clearScreen();
|
|
766
784
|
console.log(
|
|
@@ -903,7 +921,7 @@ function vitePluginDeployFtp(option) {
|
|
|
903
921
|
}
|
|
904
922
|
];
|
|
905
923
|
if (accessUrl) {
|
|
906
|
-
resultRows.push({ label: "\u8BBF\u95EE:", value: chalk5.cyan(
|
|
924
|
+
resultRows.push({ label: "\u8BBF\u95EE:", value: chalk5.cyan(accessUrl), preserveValue: true });
|
|
907
925
|
}
|
|
908
926
|
if (failedCount > 0) {
|
|
909
927
|
const failedItems = results.filter((result) => !result.success).slice(0, 2);
|
|
@@ -936,7 +954,7 @@ function vitePluginDeployFtp(option) {
|
|
|
936
954
|
});
|
|
937
955
|
console.log(renderDebugPanel(debugEntries));
|
|
938
956
|
}
|
|
939
|
-
return { name:
|
|
957
|
+
return { name: resultName, totalFiles: results.length, failedCount };
|
|
940
958
|
} catch (error) {
|
|
941
959
|
if (preflightSpinner) preflightSpinner.stop();
|
|
942
960
|
console.log(`
|
|
@@ -950,7 +968,7 @@ ${getLogSymbol("danger")} \u4E0A\u4F20\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF
|
|
|
950
968
|
console.log(renderDebugPanel(debugEntries));
|
|
951
969
|
}
|
|
952
970
|
return {
|
|
953
|
-
name:
|
|
971
|
+
name: resultName,
|
|
954
972
|
totalFiles,
|
|
955
973
|
failedCount: totalFiles > 0 ? totalFiles : 1,
|
|
956
974
|
error: error instanceof Error ? error : new Error(String(error))
|
|
@@ -1021,8 +1039,10 @@ ${getLogSymbol("danger")} \u4E0A\u4F20\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF
|
|
|
1021
1039
|
}
|
|
1022
1040
|
const deployResults = [];
|
|
1023
1041
|
for (const ftpConfig of selectedConfigs) {
|
|
1024
|
-
const
|
|
1025
|
-
|
|
1042
|
+
for (const normalizedUploadPath of normalizedUploadPaths) {
|
|
1043
|
+
const targetResult = await deploySingleTarget(ftpConfig, normalizedUploadPath);
|
|
1044
|
+
deployResults.push(targetResult);
|
|
1045
|
+
}
|
|
1026
1046
|
}
|
|
1027
1047
|
return deployResults;
|
|
1028
1048
|
};
|