@lark-apaas/fullstack-cli 1.1.37-alpha.8 → 1.1.38
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 +47 -0
- package/package.json +1 -1
- package/templates/scripts/build.sh +10 -48
package/dist/index.js
CHANGED
|
@@ -2438,6 +2438,13 @@ var syncConfig = {
|
|
|
2438
2438
|
to: ".spark_project",
|
|
2439
2439
|
type: "file",
|
|
2440
2440
|
overwrite: true
|
|
2441
|
+
},
|
|
2442
|
+
// 9. 确保 tsconfig.app.json 排除 shared/static 目录(避免 TSC 严格校验 JSON 导致编译失败)
|
|
2443
|
+
{
|
|
2444
|
+
type: "ensure-json-array-item",
|
|
2445
|
+
to: "tsconfig.app.json",
|
|
2446
|
+
jsonPath: "exclude",
|
|
2447
|
+
items: ["shared/static"]
|
|
2441
2448
|
}
|
|
2442
2449
|
],
|
|
2443
2450
|
// 文件权限设置
|
|
@@ -2692,6 +2699,11 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
|
|
|
2692
2699
|
mergeJsonFile(srcPath2, destPath2, rule.arrayMerge);
|
|
2693
2700
|
return;
|
|
2694
2701
|
}
|
|
2702
|
+
if (rule.type === "ensure-json-array-item") {
|
|
2703
|
+
const destPath2 = path5.join(userProjectRoot, rule.to);
|
|
2704
|
+
ensureJsonArrayItem(destPath2, rule.jsonPath, rule.items);
|
|
2705
|
+
return;
|
|
2706
|
+
}
|
|
2695
2707
|
if (!("from" in rule)) {
|
|
2696
2708
|
return;
|
|
2697
2709
|
}
|
|
@@ -2834,6 +2846,41 @@ function addLineToFile(filePath, line) {
|
|
|
2834
2846
|
fs7.appendFileSync(filePath, appendContent);
|
|
2835
2847
|
console.log(`[fullstack-cli] \u2713 ${fileName} (added: ${line})`);
|
|
2836
2848
|
}
|
|
2849
|
+
function ensureJsonArrayItem(filePath, jsonPath, items) {
|
|
2850
|
+
const fileName = path5.basename(filePath);
|
|
2851
|
+
if (!fs7.existsSync(filePath)) {
|
|
2852
|
+
console.log(`[fullstack-cli] \u25CB ${fileName} (not found, skipped)`);
|
|
2853
|
+
return;
|
|
2854
|
+
}
|
|
2855
|
+
const content = JSON.parse(fs7.readFileSync(filePath, "utf-8"));
|
|
2856
|
+
const parts = jsonPath.split(".");
|
|
2857
|
+
let current = content;
|
|
2858
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
2859
|
+
const part = parts[i];
|
|
2860
|
+
if (current[part] == null || typeof current[part] !== "object") {
|
|
2861
|
+
current[part] = {};
|
|
2862
|
+
}
|
|
2863
|
+
current = current[part];
|
|
2864
|
+
}
|
|
2865
|
+
const lastKey = parts[parts.length - 1];
|
|
2866
|
+
if (!Array.isArray(current[lastKey])) {
|
|
2867
|
+
current[lastKey] = [];
|
|
2868
|
+
}
|
|
2869
|
+
const arr = current[lastKey];
|
|
2870
|
+
const added = [];
|
|
2871
|
+
for (const item of items) {
|
|
2872
|
+
if (!arr.includes(item)) {
|
|
2873
|
+
arr.push(item);
|
|
2874
|
+
added.push(item);
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
if (added.length === 0) {
|
|
2878
|
+
console.log(`[fullstack-cli] \u25CB ${fileName} ${jsonPath} (already contains all items)`);
|
|
2879
|
+
return;
|
|
2880
|
+
}
|
|
2881
|
+
fs7.writeFileSync(filePath, JSON.stringify(content, null, 2) + "\n");
|
|
2882
|
+
console.log(`[fullstack-cli] \u2713 ${fileName} ${jsonPath} (added: ${added.join(", ")})`);
|
|
2883
|
+
}
|
|
2837
2884
|
function mergeJsonFile(src, dest, arrayMerge) {
|
|
2838
2885
|
const fileName = path5.basename(dest);
|
|
2839
2886
|
if (!fs7.existsSync(src)) {
|
package/package.json
CHANGED
|
@@ -19,69 +19,32 @@ print_time() {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
# ==================== 步骤 0 ====================
|
|
22
|
-
echo "🗑️ [0/
|
|
22
|
+
echo "🗑️ [0/5] 安装插件"
|
|
23
23
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
24
24
|
npx fullstack-cli action-plugin init
|
|
25
25
|
print_time $STEP_START
|
|
26
26
|
echo ""
|
|
27
27
|
|
|
28
28
|
# ==================== 步骤 1 ====================
|
|
29
|
-
echo "📝 [1/
|
|
29
|
+
echo "📝 [1/5] 更新 openapi 代码"
|
|
30
30
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
31
31
|
npm run gen:openapi
|
|
32
32
|
print_time $STEP_START
|
|
33
33
|
echo ""
|
|
34
34
|
|
|
35
35
|
# ==================== 步骤 2 ====================
|
|
36
|
-
echo "🗑️ [2/
|
|
36
|
+
echo "🗑️ [2/5] 清理 dist 目录"
|
|
37
37
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
38
38
|
rm -rf "$ROOT_DIR/dist"
|
|
39
39
|
print_time $STEP_START
|
|
40
40
|
echo ""
|
|
41
41
|
|
|
42
42
|
# ==================== 步骤 3 ====================
|
|
43
|
-
echo "🗺️ [3/6] 生成路由定义"
|
|
44
|
-
STEP_START=$(node -e "console.log(Date.now())")
|
|
45
|
-
|
|
46
|
-
# 在 client/server 构建之前生成到 dist/,供 DefinePlugin 注入前端 bundle
|
|
47
|
-
# 注意:nest-cli.json 中 deleteOutDir 必须为 false(模板默认值),否则 nest build 会清掉 dist/
|
|
48
|
-
echo " ├─ 生成 API 路由定义..."
|
|
49
|
-
npx generate-api-routes --server-dir ./server --out-dir ./dist > /tmp/gen-api-routes.log 2>&1 &
|
|
50
|
-
API_ROUTES_PID=$!
|
|
51
|
-
|
|
52
|
-
echo " ├─ 生成页面路由定义..."
|
|
53
|
-
npx generate-page-routes --app-path ./client/src/app.tsx --out-dir ./dist > /tmp/gen-page-routes.log 2>&1 &
|
|
54
|
-
PAGE_ROUTES_PID=$!
|
|
55
|
-
|
|
56
|
-
API_ROUTES_EXIT=0
|
|
57
|
-
PAGE_ROUTES_EXIT=0
|
|
58
|
-
|
|
59
|
-
wait $API_ROUTES_PID || API_ROUTES_EXIT=$?
|
|
60
|
-
wait $PAGE_ROUTES_PID || PAGE_ROUTES_EXIT=$?
|
|
61
|
-
|
|
62
|
-
if [ $API_ROUTES_EXIT -ne 0 ]; then
|
|
63
|
-
echo " ⚠️ API 路由生成失败(不影响构建)"
|
|
64
|
-
cat /tmp/gen-api-routes.log
|
|
65
|
-
else
|
|
66
|
-
echo " ✅ API 路由生成完成"
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
if [ $PAGE_ROUTES_EXIT -ne 0 ]; then
|
|
70
|
-
echo " ⚠️ 页面路由生成失败(不影响构建)"
|
|
71
|
-
cat /tmp/gen-page-routes.log
|
|
72
|
-
else
|
|
73
|
-
echo " ✅ 页面路由生成完成"
|
|
74
|
-
fi
|
|
75
|
-
print_time $STEP_START
|
|
76
|
-
echo ""
|
|
77
|
-
|
|
78
|
-
# ==================== 步骤 4 ====================
|
|
79
|
-
echo "🔨 [4/6] 并行构建 server 和 client"
|
|
80
43
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
81
44
|
|
|
82
45
|
# 根据 only_frontend_change 决定是否构建 server
|
|
83
46
|
if [[ "${only_frontend_change:-false}" == "true" ]]; then
|
|
84
|
-
echo "🔨 [
|
|
47
|
+
echo "🔨 [3/5] 仅构建 client (only_frontend_change=true)"
|
|
85
48
|
|
|
86
49
|
echo " ├─ 启动 client 构建..."
|
|
87
50
|
npm run build:client > /tmp/build-client.log 2>&1
|
|
@@ -95,7 +58,7 @@ if [[ "${only_frontend_change:-false}" == "true" ]]; then
|
|
|
95
58
|
|
|
96
59
|
echo " ✅ Client 构建完成"
|
|
97
60
|
else
|
|
98
|
-
echo "🔨 [
|
|
61
|
+
echo "🔨 [3/5] 并行构建 server 和 client"
|
|
99
62
|
|
|
100
63
|
# 并行构建
|
|
101
64
|
echo " ├─ 启动 server 构建..."
|
|
@@ -133,8 +96,8 @@ fi
|
|
|
133
96
|
print_time $STEP_START
|
|
134
97
|
echo ""
|
|
135
98
|
|
|
136
|
-
# ==================== 步骤
|
|
137
|
-
echo "📦 [5
|
|
99
|
+
# ==================== 步骤 4 ====================
|
|
100
|
+
echo "📦 [4/5] 准备产物"
|
|
138
101
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
139
102
|
|
|
140
103
|
# 移动 client 下的 HTML 文件到 dist/dist/client,保证 views 路径在 dev/prod 下一致
|
|
@@ -164,15 +127,14 @@ rm -rf "$DIST_DIR/tsconfig.node.tsbuildinfo"
|
|
|
164
127
|
print_time $STEP_START
|
|
165
128
|
echo ""
|
|
166
129
|
|
|
167
|
-
# ==================== 步骤
|
|
168
|
-
echo "✂️ [6/6] 智能依赖裁剪"
|
|
130
|
+
# ==================== 步骤 5 ====================
|
|
169
131
|
STEP_START=$(node -e "console.log(Date.now())")
|
|
170
132
|
|
|
171
133
|
# 智能依赖裁剪(仅全量构建时执行,纯前端场景不打包 server,无需裁剪)
|
|
172
134
|
if [[ "${only_frontend_change:-false}" == "true" ]]; then
|
|
173
|
-
echo "✂️ [
|
|
135
|
+
echo "✂️ [5/5] 跳过智能依赖裁剪 (only_frontend_change=true)"
|
|
174
136
|
else
|
|
175
|
-
echo "✂️ [
|
|
137
|
+
echo "✂️ [5/5] 智能依赖裁剪"
|
|
176
138
|
|
|
177
139
|
# 分析实际依赖、复制并裁剪 node_modules、生成精简的 package.json
|
|
178
140
|
node "$ROOT_DIR/scripts/prune-smart.js"
|