@lark-apaas/fullstack-cli 1.1.34-alpha.5 → 1.1.35
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/dist/index.js +59 -25
- package/package.json +1 -1
- package/templates/scripts/build.sh +48 -86
package/dist/index.js
CHANGED
|
@@ -7264,26 +7264,48 @@ var UPLOAD_STATIC_DEFAULTS = {
|
|
|
7264
7264
|
};
|
|
7265
7265
|
|
|
7266
7266
|
// src/commands/build/api-client.ts
|
|
7267
|
+
var ERROR_RESPONSE_PREVIEW_LIMIT = 2e3;
|
|
7268
|
+
async function getErrorResponseDetails(response) {
|
|
7269
|
+
try {
|
|
7270
|
+
if (typeof response.text === "function") {
|
|
7271
|
+
const text = await response.text();
|
|
7272
|
+
if (!text) {
|
|
7273
|
+
return "";
|
|
7274
|
+
}
|
|
7275
|
+
return `, response: ${text.slice(0, ERROR_RESPONSE_PREVIEW_LIMIT)}`;
|
|
7276
|
+
}
|
|
7277
|
+
if (typeof response.json === "function") {
|
|
7278
|
+
const data = await response.json();
|
|
7279
|
+
const serialized = JSON.stringify(data);
|
|
7280
|
+
if (!serialized) {
|
|
7281
|
+
return "";
|
|
7282
|
+
}
|
|
7283
|
+
return `, response: ${serialized.slice(0, ERROR_RESPONSE_PREVIEW_LIMIT)}`;
|
|
7284
|
+
}
|
|
7285
|
+
} catch {
|
|
7286
|
+
return "";
|
|
7287
|
+
}
|
|
7288
|
+
return "";
|
|
7289
|
+
}
|
|
7290
|
+
async function throwIfResponseNotOk(response, message) {
|
|
7291
|
+
if (response.ok && response.status === 200) {
|
|
7292
|
+
return;
|
|
7293
|
+
}
|
|
7294
|
+
const details = await getErrorResponseDetails(response);
|
|
7295
|
+
throw new Error(`${message}: ${response.status} ${response.statusText}${details}`);
|
|
7296
|
+
}
|
|
7267
7297
|
async function genArtifactUploadCredential(appId, body) {
|
|
7268
7298
|
const client = getHttpClient();
|
|
7269
7299
|
const url = `/v1/app/${appId}/pipeline/gen_artifact_upload_credential`;
|
|
7270
7300
|
const response = await client.post(url, body);
|
|
7271
|
-
|
|
7272
|
-
throw new Error(
|
|
7273
|
-
`gen_artifact_upload_credential \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
|
|
7274
|
-
);
|
|
7275
|
-
}
|
|
7301
|
+
await throwIfResponseNotOk(response, "gen_artifact_upload_credential \u8BF7\u6C42\u5931\u8D25");
|
|
7276
7302
|
return response.json();
|
|
7277
7303
|
}
|
|
7278
7304
|
async function getDefaultBucketId(appId) {
|
|
7279
7305
|
const client = getHttpClient();
|
|
7280
7306
|
const url = `/v1/app/${appId}/storage/inner/staticBucket`;
|
|
7281
7307
|
const response = await client.post(url, {});
|
|
7282
|
-
|
|
7283
|
-
throw new Error(
|
|
7284
|
-
`getOrCreateStaticBucket \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
|
|
7285
|
-
);
|
|
7286
|
-
}
|
|
7308
|
+
await throwIfResponseNotOk(response, "getOrCreateStaticBucket \u8BF7\u6C42\u5931\u8D25");
|
|
7287
7309
|
const data = await response.json();
|
|
7288
7310
|
if (data.status_code !== "0") {
|
|
7289
7311
|
throw new Error(`getOrCreateStaticBucket \u8FD4\u56DE\u5F02\u5E38, status_code: ${data.status_code}`);
|
|
@@ -7298,22 +7320,14 @@ async function preUploadStaticAttachment(appId, bucketId) {
|
|
|
7298
7320
|
const client = getHttpClient();
|
|
7299
7321
|
const url = `/v1/app/${appId}/storage/bucket/${bucketId}/preUploadStatic`;
|
|
7300
7322
|
const response = await client.post(url, {});
|
|
7301
|
-
|
|
7302
|
-
throw new Error(
|
|
7303
|
-
`preUploadStatic \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
|
|
7304
|
-
);
|
|
7305
|
-
}
|
|
7323
|
+
await throwIfResponseNotOk(response, "preUploadStatic \u8BF7\u6C42\u5931\u8D25");
|
|
7306
7324
|
return response.json();
|
|
7307
7325
|
}
|
|
7308
7326
|
async function uploadStaticAttachmentCallback(appId, bucketId, body) {
|
|
7309
7327
|
const client = getHttpClient();
|
|
7310
7328
|
const url = `/v1/app/${appId}/storage/bucket/${bucketId}/object/callbackStatic`;
|
|
7311
7329
|
const response = await client.post(url, body);
|
|
7312
|
-
|
|
7313
|
-
throw new Error(
|
|
7314
|
-
`callbackStatic \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
|
|
7315
|
-
);
|
|
7316
|
-
}
|
|
7330
|
+
await throwIfResponseNotOk(response, "callbackStatic \u8BF7\u6C42\u5931\u8D25");
|
|
7317
7331
|
return response.json();
|
|
7318
7332
|
}
|
|
7319
7333
|
|
|
@@ -7354,6 +7368,7 @@ import * as fs25 from "fs";
|
|
|
7354
7368
|
import * as os2 from "os";
|
|
7355
7369
|
import * as path21 from "path";
|
|
7356
7370
|
import { execFileSync } from "child_process";
|
|
7371
|
+
import { HttpError } from "@lark-apaas/http-client";
|
|
7357
7372
|
function readCredentialsFromEnv() {
|
|
7358
7373
|
const uploadPrefix = process.env.STATIC_UPLOAD_PREFIX;
|
|
7359
7374
|
const uploadID = process.env.STATIC_UPLOAD_ID;
|
|
@@ -7433,7 +7448,7 @@ async function uploadStatic(options) {
|
|
|
7433
7448
|
console.error(`${LOG_PREFIX} \u8C03\u7528 callbackStatic (uploadID: ${uploadID})...`);
|
|
7434
7449
|
const callbackResp = await uploadStaticAttachmentCallback(appId, bucketId, { uploadID });
|
|
7435
7450
|
if (callbackResp.status_code !== "0") {
|
|
7436
|
-
throw new Error(`callbackStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${callbackResp.status_code}`);
|
|
7451
|
+
throw new Error(`callbackStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${callbackResp.status_code}, response: ${JSON.stringify(callbackResp)}`);
|
|
7437
7452
|
}
|
|
7438
7453
|
const attachments = callbackResp.data?.attachments || [];
|
|
7439
7454
|
console.error(`${LOG_PREFIX} \u4E0A\u4F20\u5B8C\u6210\uFF0C\u5171 ${attachments.length} \u4E2A\u6587\u4EF6`);
|
|
@@ -7441,7 +7456,23 @@ async function uploadStatic(options) {
|
|
|
7441
7456
|
} catch (error) {
|
|
7442
7457
|
const message = error instanceof Error ? error.message : String(error);
|
|
7443
7458
|
console.error(`${LOG_PREFIX} Error: ${message}`);
|
|
7444
|
-
|
|
7459
|
+
if (error instanceof HttpError && error.response) {
|
|
7460
|
+
const logId = error.response.headers.get("x-tt-logid") || error.response.headers.get("X-Tt-Logid");
|
|
7461
|
+
if (logId) {
|
|
7462
|
+
console.error(`${LOG_PREFIX} logid: ${logId}`);
|
|
7463
|
+
}
|
|
7464
|
+
try {
|
|
7465
|
+
const responseText = await error.response.text();
|
|
7466
|
+
if (responseText) {
|
|
7467
|
+
console.error(`${LOG_PREFIX} response: ${responseText}`);
|
|
7468
|
+
}
|
|
7469
|
+
} catch {
|
|
7470
|
+
}
|
|
7471
|
+
if (error.config?.url) {
|
|
7472
|
+
console.error(`${LOG_PREFIX} request url: ${error.config.url}`);
|
|
7473
|
+
}
|
|
7474
|
+
}
|
|
7475
|
+
process.exitCode = 1;
|
|
7445
7476
|
}
|
|
7446
7477
|
}
|
|
7447
7478
|
function resolveTosutilPath(tosutilPath) {
|
|
@@ -7458,14 +7489,14 @@ function resolveTosutilPath(tosutilPath) {
|
|
|
7458
7489
|
async function fetchPreUpload(appId, bucketId) {
|
|
7459
7490
|
const response = await preUploadStaticAttachment(appId, bucketId);
|
|
7460
7491
|
if (response.status_code !== "0") {
|
|
7461
|
-
throw new Error(`preUploadStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${response.status_code}`);
|
|
7492
|
+
throw new Error(`preUploadStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${response.status_code}, response: ${JSON.stringify(response)}`);
|
|
7462
7493
|
}
|
|
7463
7494
|
const { uploadPrefix, uploadID, uploadCredential } = response.data || {};
|
|
7464
7495
|
if (!uploadPrefix || !uploadID) {
|
|
7465
|
-
throw new Error(
|
|
7496
|
+
throw new Error(`preUploadStatic \u8FD4\u56DE\u6570\u636E\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11 uploadPrefix \u6216 uploadID, response: ${JSON.stringify(response)}`);
|
|
7466
7497
|
}
|
|
7467
7498
|
if (!uploadCredential?.AccessKeyID || !uploadCredential?.SecretAccessKey || !uploadCredential?.SessionToken) {
|
|
7468
|
-
throw new Error(
|
|
7499
|
+
throw new Error(`preUploadStatic \u8FD4\u56DE\u7684\u51ED\u8BC1\u5B57\u6BB5\u4E0D\u5B8C\u6574, response: ${JSON.stringify(response)}`);
|
|
7469
7500
|
}
|
|
7470
7501
|
return response;
|
|
7471
7502
|
}
|
|
@@ -7510,15 +7541,18 @@ async function preUploadStatic(options) {
|
|
|
7510
7541
|
const response = await preUploadStaticAttachment(appId, bucketId);
|
|
7511
7542
|
if (response.status_code !== "0") {
|
|
7512
7543
|
console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${response.status_code}`);
|
|
7544
|
+
console.error(`${LOG_PREFIX2} preUploadStatic \u54CD\u5E94: ${JSON.stringify(response)}`);
|
|
7513
7545
|
return;
|
|
7514
7546
|
}
|
|
7515
7547
|
const { downloadURLPrefix, uploadPrefix, uploadID, uploadCredential } = response.data || {};
|
|
7516
7548
|
if (!downloadURLPrefix || !uploadPrefix || !uploadID) {
|
|
7517
7549
|
console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u6570\u636E\u4E0D\u5B8C\u6574`);
|
|
7550
|
+
console.error(`${LOG_PREFIX2} preUploadStatic \u54CD\u5E94: ${JSON.stringify(response)}`);
|
|
7518
7551
|
return;
|
|
7519
7552
|
}
|
|
7520
7553
|
if (!uploadCredential?.AccessKeyID || !uploadCredential?.SecretAccessKey || !uploadCredential?.SessionToken) {
|
|
7521
7554
|
console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u7684\u51ED\u8BC1\u5B57\u6BB5\u4E0D\u5B8C\u6574`);
|
|
7555
|
+
console.error(`${LOG_PREFIX2} preUploadStatic \u54CD\u5E94: ${JSON.stringify(response)}`);
|
|
7522
7556
|
return;
|
|
7523
7557
|
}
|
|
7524
7558
|
console.log(`export STATIC_ASSETS_BASE_URL="${shellEscape(downloadURLPrefix)}"`);
|
package/package.json
CHANGED
|
@@ -40,59 +40,40 @@ print_time $STEP_START
|
|
|
40
40
|
echo ""
|
|
41
41
|
|
|
42
42
|
# ==================== 步骤 3 ====================
|
|
43
|
+
echo "🔨 [3/5] 并行构建 server 和 client"
|
|
43
44
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
44
45
|
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
SERVER_PID=$!
|
|
67
|
-
|
|
68
|
-
echo " ├─ 启动 client 构建..."
|
|
69
|
-
npm run build:client > /tmp/build-client.log 2>&1 &
|
|
70
|
-
CLIENT_PID=$!
|
|
71
|
-
|
|
72
|
-
# 等待两个构建完成
|
|
73
|
-
SERVER_EXIT=0
|
|
74
|
-
CLIENT_EXIT=0
|
|
75
|
-
|
|
76
|
-
wait $SERVER_PID || SERVER_EXIT=$?
|
|
77
|
-
wait $CLIENT_PID || CLIENT_EXIT=$?
|
|
78
|
-
|
|
79
|
-
# 检查构建结果
|
|
80
|
-
if [ $SERVER_EXIT -ne 0 ]; then
|
|
81
|
-
echo " ❌ Server 构建失败"
|
|
82
|
-
cat /tmp/build-server.log
|
|
83
|
-
exit 1
|
|
84
|
-
fi
|
|
85
|
-
|
|
86
|
-
if [ $CLIENT_EXIT -ne 0 ]; then
|
|
87
|
-
echo " ❌ Client 构建失败"
|
|
88
|
-
cat /tmp/build-client.log
|
|
89
|
-
exit 1
|
|
90
|
-
fi
|
|
91
|
-
|
|
92
|
-
echo " ✅ Server 构建完成"
|
|
93
|
-
echo " ✅ Client 构建完成"
|
|
46
|
+
# 并行构建
|
|
47
|
+
echo " ├─ 启动 server 构建..."
|
|
48
|
+
npm run build:server > /tmp/build-server.log 2>&1 &
|
|
49
|
+
SERVER_PID=$!
|
|
50
|
+
|
|
51
|
+
echo " ├─ 启动 client 构建..."
|
|
52
|
+
npm run build:client > /tmp/build-client.log 2>&1 &
|
|
53
|
+
CLIENT_PID=$!
|
|
54
|
+
|
|
55
|
+
# 等待两个构建完成
|
|
56
|
+
SERVER_EXIT=0
|
|
57
|
+
CLIENT_EXIT=0
|
|
58
|
+
|
|
59
|
+
wait $SERVER_PID || SERVER_EXIT=$?
|
|
60
|
+
wait $CLIENT_PID || CLIENT_EXIT=$?
|
|
61
|
+
|
|
62
|
+
# 检查构建结果
|
|
63
|
+
if [ $SERVER_EXIT -ne 0 ]; then
|
|
64
|
+
echo " ❌ Server 构建失败"
|
|
65
|
+
cat /tmp/build-server.log
|
|
66
|
+
exit 1
|
|
94
67
|
fi
|
|
95
68
|
|
|
69
|
+
if [ $CLIENT_EXIT -ne 0 ]; then
|
|
70
|
+
echo " ❌ Client 构建失败"
|
|
71
|
+
cat /tmp/build-client.log
|
|
72
|
+
exit 1
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
echo " ✅ Server 构建完成"
|
|
76
|
+
echo " ✅ Client 构建完成"
|
|
96
77
|
print_time $STEP_START
|
|
97
78
|
echo ""
|
|
98
79
|
|
|
@@ -100,24 +81,18 @@ echo ""
|
|
|
100
81
|
echo "📦 [4/5] 准备产物"
|
|
101
82
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
102
83
|
|
|
84
|
+
# 拷贝 run.sh 到 dist/(prod 从 dist/ 启动,确保 cwd 一致性)
|
|
85
|
+
cp "$ROOT_DIR/scripts/run.sh" "$DIST_DIR/"
|
|
86
|
+
|
|
87
|
+
# 拷贝 .env 文件(如果存在)
|
|
88
|
+
if [ -f "$ROOT_DIR/.env" ]; then
|
|
89
|
+
cp "$ROOT_DIR/.env" "$DIST_DIR/"
|
|
90
|
+
fi
|
|
91
|
+
|
|
103
92
|
# 移动 client 下的 HTML 文件到 dist/dist/client,保证 views 路径在 dev/prod 下一致
|
|
104
|
-
# HTML 文件属于前端产物,始终执行
|
|
105
93
|
if [ -d "$DIST_DIR/client" ]; then
|
|
106
94
|
mkdir -p "$DIST_DIR/dist/client"
|
|
107
|
-
find "$DIST_DIR/client" -maxdepth 1 -name "*.html" -exec
|
|
108
|
-
fi
|
|
109
|
-
|
|
110
|
-
# server 相关产物准备(only_frontend_change=true 时跳过)
|
|
111
|
-
if [[ "${only_frontend_change:-false}" == "true" ]]; then
|
|
112
|
-
echo " [skip] 跳过 run.sh/.env 复制 (only_frontend_change=true)"
|
|
113
|
-
else
|
|
114
|
-
# 拷贝 run.sh 到 dist/(prod 从 dist/ 启动,确保 cwd 一致性)
|
|
115
|
-
cp "$ROOT_DIR/scripts/run.sh" "$DIST_DIR/"
|
|
116
|
-
|
|
117
|
-
# 拷贝 .env 文件(如果存在)
|
|
118
|
-
if [ -f "$ROOT_DIR/.env" ]; then
|
|
119
|
-
cp "$ROOT_DIR/.env" "$DIST_DIR/"
|
|
120
|
-
fi
|
|
95
|
+
find "$DIST_DIR/client" -maxdepth 1 -name "*.html" -exec mv {} "$DIST_DIR/dist/client/" \;
|
|
121
96
|
fi
|
|
122
97
|
|
|
123
98
|
# 清理无用文件
|
|
@@ -128,17 +103,11 @@ print_time $STEP_START
|
|
|
128
103
|
echo ""
|
|
129
104
|
|
|
130
105
|
# ==================== 步骤 5 ====================
|
|
106
|
+
echo "✂️ [5/5] 智能依赖裁剪"
|
|
131
107
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
132
108
|
|
|
133
|
-
#
|
|
134
|
-
|
|
135
|
-
echo "✂️ [5/5] 跳过智能依赖裁剪 (only_frontend_change=true)"
|
|
136
|
-
else
|
|
137
|
-
echo "✂️ [5/5] 智能依赖裁剪"
|
|
138
|
-
|
|
139
|
-
# 分析实际依赖、复制并裁剪 node_modules、生成精简的 package.json
|
|
140
|
-
node "$ROOT_DIR/scripts/prune-smart.js"
|
|
141
|
-
fi
|
|
109
|
+
# 分析实际依赖、复制并裁剪 node_modules、生成精简的 package.json
|
|
110
|
+
node "$ROOT_DIR/scripts/prune-smart.js"
|
|
142
111
|
|
|
143
112
|
print_time $STEP_START
|
|
144
113
|
echo ""
|
|
@@ -149,16 +118,9 @@ print_time $TOTAL_START
|
|
|
149
118
|
|
|
150
119
|
# 输出产物信息
|
|
151
120
|
DIST_SIZE=$(du -sh "$DIST_DIR" | cut -f1)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
NODE_MODULES_SIZE=$(du -sh "$DIST_DIR/node_modules" | cut -f1)
|
|
159
|
-
echo ""
|
|
160
|
-
echo "📊 构建产物统计:"
|
|
161
|
-
echo " 产物大小: $DIST_SIZE"
|
|
162
|
-
echo " node_modules: $NODE_MODULES_SIZE"
|
|
163
|
-
echo ""
|
|
164
|
-
fi
|
|
121
|
+
NODE_MODULES_SIZE=$(du -sh "$DIST_DIR/node_modules" | cut -f1)
|
|
122
|
+
echo ""
|
|
123
|
+
echo "📊 构建产物统计:"
|
|
124
|
+
echo " 产物大小: $DIST_SIZE"
|
|
125
|
+
echo " node_modules: $NODE_MODULES_SIZE"
|
|
126
|
+
echo ""
|