@coze-arch/cli 0.1.4-alpha.8c3e03 → 0.1.4-alpha.99c367
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/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +2 -0
- package/lib/__templates__/expo/.cozeproj/scripts/prepare-node-modules.sh +242 -52
- package/lib/__templates__/nextjs/eslint.config.mjs +11 -5
- package/lib/__templates__/nextjs/package.json +1 -1
- package/lib/__templates__/nextjs/scripts/dev.ps1 +2 -2
- package/lib/__templates__/nextjs/scripts/dev.sh +26 -2
- package/lib/__templates__/nextjs/scripts/prepare-node-modules.sh +242 -52
- package/lib/__templates__/nuxt-vue/scripts/prepare-node-modules.sh +242 -52
- package/lib/__templates__/taro/.cozeproj/scripts/prepare-node-modules.sh +242 -52
- package/lib/__templates__/vite/scripts/prepare-node-modules.sh +242 -52
- package/lib/cli.js +1 -1
- package/package.json +1 -1
|
@@ -199,7 +199,9 @@ start_expo() {
|
|
|
199
199
|
local -a expo_env
|
|
200
200
|
expo_env=(
|
|
201
201
|
"EXPO_NO_DEPENDENCY_VALIDATION=1"
|
|
202
|
+
"EXPO_SDK_VERSION=54.0.0"
|
|
202
203
|
"EXPO_PUBLIC_BACKEND_BASE_URL=$EXPO_PUBLIC_BACKEND_BASE_URL"
|
|
204
|
+
"EXPO_PUBLIC_API_BASE=$EXPO_PUBLIC_BACKEND_BASE_URL"
|
|
203
205
|
"EXPO_PACKAGER_PROXY_URL=$EXPO_PACKAGER_PROXY_URL"
|
|
204
206
|
"EXPO_PUBLIC_COZE_PROJECT_ID=$EXPO_PUBLIC_COZE_PROJECT_ID"
|
|
205
207
|
)
|
|
@@ -40,84 +40,246 @@ case "$WORK_DIR" in
|
|
|
40
40
|
esac
|
|
41
41
|
|
|
42
42
|
LOCK_DIR="$NM_ROOT/$PROJECT_ID.lock"
|
|
43
|
+
LOCK_TIMEOUT_SECONDS="${COZE_NODE_MODULES_LOCK_TIMEOUT_SECONDS:-120}"
|
|
44
|
+
case "$LOCK_TIMEOUT_SECONDS" in
|
|
45
|
+
''|*[!0-9]*|0)
|
|
46
|
+
echo "[node_modules] COZE_NODE_MODULES_LOCK_TIMEOUT_SECONDS must be a positive integer" >&2
|
|
47
|
+
exit 1
|
|
48
|
+
;;
|
|
49
|
+
esac
|
|
50
|
+
|
|
51
|
+
lock_owner_is_alive() {
|
|
52
|
+
local owner_pid=""
|
|
53
|
+
[ -f "$LOCK_DIR/pid" ] || return 1
|
|
54
|
+
IFS= read -r owner_pid < "$LOCK_DIR/pid" || return 1
|
|
55
|
+
case "$owner_pid" in
|
|
56
|
+
''|*[!0-9]*) return 1 ;;
|
|
57
|
+
esac
|
|
58
|
+
kill -0 "$owner_pid" 2>/dev/null
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
lock_acquired=false
|
|
62
|
+
release_lock() {
|
|
63
|
+
local owner_pid=""
|
|
64
|
+
if [ "$lock_acquired" != true ] || [ ! -f "$LOCK_DIR/pid" ]; then
|
|
65
|
+
return 0
|
|
66
|
+
fi
|
|
67
|
+
IFS= read -r owner_pid < "$LOCK_DIR/pid" || true
|
|
68
|
+
if [ "$owner_pid" = "$$" ]; then
|
|
69
|
+
rm -f "$LOCK_DIR/pid"
|
|
70
|
+
rmdir "$LOCK_DIR" 2>/dev/null || true
|
|
71
|
+
fi
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
lock_started_at="$(date +%s)"
|
|
75
|
+
missing_owner_checks=0
|
|
43
76
|
while ! mkdir "$LOCK_DIR" 2>/dev/null; do
|
|
77
|
+
if lock_owner_is_alive; then
|
|
78
|
+
missing_owner_checks=0
|
|
79
|
+
else
|
|
80
|
+
missing_owner_checks=$((missing_owner_checks + 1))
|
|
81
|
+
if [ "$missing_owner_checks" -ge 2 ]; then
|
|
82
|
+
stale_lock_dir="$LOCK_DIR.stale.$$"
|
|
83
|
+
if mv "$LOCK_DIR" "$stale_lock_dir" 2>/dev/null; then
|
|
84
|
+
echo "[node_modules] Recovering stale dependency preparation lock."
|
|
85
|
+
rm -rf "$stale_lock_dir"
|
|
86
|
+
fi
|
|
87
|
+
missing_owner_checks=0
|
|
88
|
+
continue
|
|
89
|
+
fi
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
lock_now="$(date +%s)"
|
|
93
|
+
if [ $((lock_now - lock_started_at)) -ge "$LOCK_TIMEOUT_SECONDS" ]; then
|
|
94
|
+
echo "[node_modules] Timed out waiting ${LOCK_TIMEOUT_SECONDS}s for dependency preparation lock: $LOCK_DIR" >&2
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
44
97
|
echo "[node_modules] Waiting for another dependency preparation for this project..."
|
|
45
98
|
sleep 1
|
|
46
99
|
done
|
|
47
|
-
|
|
100
|
+
printf '%s\n' "$$" > "$LOCK_DIR/pid"
|
|
101
|
+
lock_acquired=true
|
|
102
|
+
trap release_lock EXIT
|
|
48
103
|
|
|
49
104
|
mkdir -p "$WORK_DIR"
|
|
105
|
+
INSTALL_STATE_FILE="$WORK_DIR/.install-state"
|
|
106
|
+
|
|
107
|
+
# Previous versions mirrored the whole project into WORK_DIR. That gives pnpm
|
|
108
|
+
# and framework dev servers two paths for the same source tree, which breaks
|
|
109
|
+
# file watching and on-demand compilation. Keep only managed local outputs.
|
|
110
|
+
cleanup_legacy_workspace() {
|
|
111
|
+
local workspace_dir="$1" entry name
|
|
112
|
+
if [ -L "$workspace_dir" ] || { [ -e "$workspace_dir" ] && [ ! -d "$workspace_dir" ]; }; then
|
|
113
|
+
rm -rf "$workspace_dir"
|
|
114
|
+
return
|
|
115
|
+
fi
|
|
116
|
+
if [ ! -d "$workspace_dir" ]; then
|
|
117
|
+
return 0
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
while IFS= read -r -d '' entry; do
|
|
121
|
+
name="$(basename "$entry")"
|
|
122
|
+
[ "$name" = "node_modules" ] || rm -rf "$entry"
|
|
123
|
+
done < <(find "$workspace_dir" -mindepth 1 -maxdepth 1 -print0)
|
|
124
|
+
}
|
|
50
125
|
|
|
51
|
-
|
|
52
|
-
# workspace directories stay real too, so pnpm never writes them to Drive.
|
|
53
|
-
mirror_root() {
|
|
126
|
+
cleanup_legacy_shadow_project() {
|
|
54
127
|
local entry name
|
|
55
128
|
while IFS= read -r -d '' entry; do
|
|
56
129
|
name="$(basename "$entry")"
|
|
57
130
|
case "$name" in
|
|
58
|
-
node_modules|
|
|
59
|
-
client|server)
|
|
60
|
-
[ -f "$PROJECT_ROOT/$name/package.json" ] && continue
|
|
61
|
-
;;
|
|
131
|
+
node_modules|client|server|.install-state|.next) continue ;;
|
|
62
132
|
esac
|
|
63
133
|
rm -rf "$entry"
|
|
64
134
|
done < <(find "$WORK_DIR" -mindepth 1 -maxdepth 1 -print0)
|
|
65
135
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
node_modules|pnpm-lock.yaml) continue ;;
|
|
70
|
-
client|server)
|
|
71
|
-
[ -f "$entry/package.json" ] && continue
|
|
72
|
-
;;
|
|
73
|
-
esac
|
|
74
|
-
ln -s "$entry" "$WORK_DIR/$name"
|
|
75
|
-
done < <(find "$PROJECT_ROOT" -mindepth 1 -maxdepth 1 -print0)
|
|
136
|
+
for workspace in client server; do
|
|
137
|
+
cleanup_legacy_workspace "$WORK_DIR/$workspace"
|
|
138
|
+
done
|
|
76
139
|
}
|
|
77
140
|
|
|
78
|
-
|
|
79
|
-
local
|
|
80
|
-
|
|
81
|
-
if [ -
|
|
82
|
-
|
|
141
|
+
link_install_entry() {
|
|
142
|
+
local source_path="$1" target_path="$2"
|
|
143
|
+
rm -rf "$target_path"
|
|
144
|
+
if [ -e "$source_path" ]; then
|
|
145
|
+
ln -s "$source_path" "$target_path"
|
|
83
146
|
fi
|
|
84
|
-
|
|
147
|
+
}
|
|
85
148
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
149
|
+
hash_install_input() {
|
|
150
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
151
|
+
sha256sum | awk '{print $1}'
|
|
152
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
153
|
+
shasum -a 256 | awk '{print $1}'
|
|
154
|
+
else
|
|
155
|
+
cksum | awk '{print $1 "-" $2}'
|
|
156
|
+
fi
|
|
157
|
+
}
|
|
89
158
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
159
|
+
calculate_install_fingerprint() {
|
|
160
|
+
local filename workspace
|
|
161
|
+
{
|
|
162
|
+
printf 'prepare-node-modules-version=2\n'
|
|
163
|
+
printf 'pnpm-version=%s\n' "$(pnpm --version)"
|
|
164
|
+
for filename in package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc; do
|
|
165
|
+
printf 'file=%s\n' "$filename"
|
|
166
|
+
if [ -f "$PROJECT_ROOT/$filename" ]; then
|
|
167
|
+
cat "$PROJECT_ROOT/$filename"
|
|
168
|
+
else
|
|
169
|
+
printf '<missing>\n'
|
|
170
|
+
fi
|
|
171
|
+
done
|
|
172
|
+
for workspace in client server; do
|
|
173
|
+
printf 'file=%s/package.json\n' "$workspace"
|
|
174
|
+
if [ -f "$PROJECT_ROOT/$workspace/package.json" ]; then
|
|
175
|
+
cat "$PROJECT_ROOT/$workspace/package.json"
|
|
176
|
+
else
|
|
177
|
+
printf '<missing>\n'
|
|
178
|
+
fi
|
|
179
|
+
done
|
|
180
|
+
} | hash_install_input
|
|
94
181
|
}
|
|
95
182
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
183
|
+
dependencies_are_ready() {
|
|
184
|
+
local workspace
|
|
185
|
+
[ -d "$WORK_DIR/node_modules" ] || return 1
|
|
186
|
+
for workspace in client server; do
|
|
187
|
+
if [ -f "$PROJECT_ROOT/$workspace/package.json" ] && [ ! -d "$WORK_DIR/$workspace/node_modules" ]; then
|
|
188
|
+
return 1
|
|
189
|
+
fi
|
|
190
|
+
done
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
write_install_state() {
|
|
194
|
+
local fingerprint="$1" temporary_state
|
|
195
|
+
temporary_state="$(mktemp "$WORK_DIR/.install-state.XXXXXX")"
|
|
196
|
+
printf '%s\n' "$fingerprint" > "$temporary_state"
|
|
197
|
+
mv -f "$temporary_state" "$INSTALL_STATE_FILE"
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
prepare_next_output() {
|
|
201
|
+
local next_root="$PROJECT_ROOT/.next"
|
|
202
|
+
local next_dev="$next_root/dev"
|
|
203
|
+
local target="$WORK_DIR/.next/dev"
|
|
204
|
+
local current=""
|
|
205
|
+
if [ ! -f "$PROJECT_ROOT/next.config.js" ] &&
|
|
206
|
+
[ ! -f "$PROJECT_ROOT/next.config.mjs" ] &&
|
|
207
|
+
[ ! -f "$PROJECT_ROOT/next.config.ts" ]; then
|
|
208
|
+
return 0
|
|
100
209
|
fi
|
|
101
|
-
done
|
|
102
210
|
|
|
103
|
-
#
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
211
|
+
# Migrate links created by the previous implementation, which linked the
|
|
212
|
+
# entire .next directory. Keep the root local so production output stays in
|
|
213
|
+
# the project while only development output is redirected to local disk.
|
|
214
|
+
if [ -L "$next_root" ]; then
|
|
215
|
+
current="$(readlink "$next_root")"
|
|
216
|
+
case "$current" in
|
|
217
|
+
"$NM_ROOT"/*/.next)
|
|
218
|
+
rm "$next_root"
|
|
219
|
+
;;
|
|
220
|
+
*)
|
|
221
|
+
echo "[node_modules] refusing to replace unmanaged .next symlink: $next_root" >&2
|
|
222
|
+
exit 1
|
|
223
|
+
;;
|
|
224
|
+
esac
|
|
225
|
+
elif [ -e "$next_root" ] && [ ! -d "$next_root" ]; then
|
|
226
|
+
echo "[node_modules] refusing to replace non-directory Next output: $next_root" >&2
|
|
227
|
+
exit 1
|
|
228
|
+
fi
|
|
229
|
+
mkdir -p "$next_root"
|
|
108
230
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
231
|
+
if [ "${COZE_LOCAL_NEXT_OUTPUT:-}" != "1" ]; then
|
|
232
|
+
# .next/dev is separate from production output in Next 16. Leave its
|
|
233
|
+
# managed link in place so production preparation does not discard a dev
|
|
234
|
+
# cache or modify output used by a running dev server.
|
|
235
|
+
return 0
|
|
236
|
+
fi
|
|
114
237
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
fi
|
|
238
|
+
mkdir -p "$target"
|
|
239
|
+
if [ -L "$next_dev" ]; then
|
|
240
|
+
current="$(readlink "$next_dev")"
|
|
241
|
+
if [ "$current" = "$target" ]; then
|
|
242
|
+
return 0
|
|
243
|
+
fi
|
|
244
|
+
case "$current" in
|
|
245
|
+
"$NM_ROOT"/*/.next/dev) rm "$next_dev" ;;
|
|
246
|
+
*)
|
|
247
|
+
echo "[node_modules] refusing to replace unmanaged .next/dev symlink: $next_dev" >&2
|
|
248
|
+
exit 1
|
|
249
|
+
;;
|
|
250
|
+
esac
|
|
251
|
+
elif [ -e "$next_dev" ]; then
|
|
252
|
+
rm -rf "$next_dev"
|
|
253
|
+
fi
|
|
254
|
+
# macOS 的 ln -sfn 不会直接替换实体目录,所以上面先清理,再覆盖链接。
|
|
255
|
+
ln -sfn "$target" "$next_dev"
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
copy_install_metadata() {
|
|
259
|
+
local filename source_file target_file workspace
|
|
260
|
+
for filename in pnpm-lock.yaml pnpm-workspace.yaml .npmrc; do
|
|
261
|
+
source_file="$PROJECT_ROOT/$filename"
|
|
262
|
+
target_file="$WORK_DIR/$filename"
|
|
263
|
+
rm -f "$target_file"
|
|
264
|
+
if [ -f "$source_file" ]; then
|
|
265
|
+
cp "$source_file" "$target_file"
|
|
266
|
+
fi
|
|
267
|
+
done
|
|
268
|
+
|
|
269
|
+
link_install_entry "$PROJECT_ROOT/package.json" "$WORK_DIR/package.json"
|
|
270
|
+
link_install_entry "$PROJECT_ROOT/patches" "$WORK_DIR/patches"
|
|
271
|
+
link_install_entry "$PROJECT_ROOT/scripts" "$WORK_DIR/scripts"
|
|
272
|
+
|
|
273
|
+
for workspace in client server; do
|
|
274
|
+
if [ -f "$PROJECT_ROOT/$workspace/package.json" ]; then
|
|
275
|
+
mkdir -p "$WORK_DIR/$workspace"
|
|
276
|
+
link_install_entry "$PROJECT_ROOT/$workspace/package.json" "$WORK_DIR/$workspace/package.json"
|
|
277
|
+
link_install_entry "$PROJECT_ROOT/$workspace/scripts" "$WORK_DIR/$workspace/scripts"
|
|
278
|
+
else
|
|
279
|
+
rm -rf "$WORK_DIR/$workspace"
|
|
280
|
+
fi
|
|
281
|
+
done
|
|
282
|
+
}
|
|
121
283
|
|
|
122
284
|
link_node_modules() {
|
|
123
285
|
local source_dir="$1" target_dir="$2"
|
|
@@ -139,11 +301,39 @@ link_node_modules() {
|
|
|
139
301
|
ln -s "$target_dir" "$source_dir/node_modules"
|
|
140
302
|
}
|
|
141
303
|
|
|
304
|
+
cleanup_legacy_shadow_project
|
|
305
|
+
install_fingerprint="$(calculate_install_fingerprint)"
|
|
306
|
+
copy_install_metadata
|
|
307
|
+
|
|
308
|
+
installed_fingerprint=""
|
|
309
|
+
if [ -f "$INSTALL_STATE_FILE" ]; then
|
|
310
|
+
IFS= read -r installed_fingerprint < "$INSTALL_STATE_FILE" || true
|
|
311
|
+
fi
|
|
312
|
+
|
|
313
|
+
if [ "$installed_fingerprint" = "$install_fingerprint" ] && dependencies_are_ready; then
|
|
314
|
+
echo "[node_modules] Reusing unchanged dependencies in $WORK_DIR"
|
|
315
|
+
else
|
|
316
|
+
rm -f "$INSTALL_STATE_FILE"
|
|
317
|
+
echo "[node_modules] Installing dependencies in $WORK_DIR"
|
|
318
|
+
if ! (cd "$WORK_DIR" && pnpm install "$@"); then
|
|
319
|
+
exit 1
|
|
320
|
+
fi
|
|
321
|
+
|
|
322
|
+
if [ -f "$WORK_DIR/pnpm-lock.yaml" ]; then
|
|
323
|
+
temporary_lockfile="$(mktemp "$PROJECT_ROOT/.pnpm-lock.yaml.XXXXXX")"
|
|
324
|
+
cp "$WORK_DIR/pnpm-lock.yaml" "$temporary_lockfile"
|
|
325
|
+
chmod 0644 "$temporary_lockfile"
|
|
326
|
+
mv -f "$temporary_lockfile" "$PROJECT_ROOT/pnpm-lock.yaml"
|
|
327
|
+
fi
|
|
328
|
+
write_install_state "$(calculate_install_fingerprint)"
|
|
329
|
+
fi
|
|
330
|
+
|
|
142
331
|
link_node_modules "$PROJECT_ROOT" "$WORK_DIR/node_modules"
|
|
143
332
|
for workspace in client server; do
|
|
144
333
|
if [ -f "$PROJECT_ROOT/$workspace/package.json" ]; then
|
|
145
334
|
link_node_modules "$PROJECT_ROOT/$workspace" "$WORK_DIR/$workspace/node_modules"
|
|
146
335
|
fi
|
|
147
336
|
done
|
|
337
|
+
prepare_next_output
|
|
148
338
|
|
|
149
339
|
echo "[node_modules] Dependencies ready"
|
|
@@ -23,6 +23,11 @@ const eslintConfig = defineConfig([
|
|
|
23
23
|
...nextVitals,
|
|
24
24
|
...nextTs,
|
|
25
25
|
{
|
|
26
|
+
settings: {
|
|
27
|
+
// node_modules 里的 barrel 包(lucide-react 等)不参与 ExportMap 构建,
|
|
28
|
+
// import/no-cycle 只需要项目源码的依赖图。
|
|
29
|
+
'import/ignore': ['/node_modules/'],
|
|
30
|
+
},
|
|
26
31
|
rules: {
|
|
27
32
|
'import/no-cycle': ['error', { ignoreExternal: true }],
|
|
28
33
|
'react-hooks/set-state-in-effect': 'off',
|
|
@@ -37,14 +42,15 @@ const eslintConfig = defineConfig([
|
|
|
37
42
|
},
|
|
38
43
|
// Override default ignores of eslint-config-next.
|
|
39
44
|
globalIgnores([
|
|
40
|
-
// Default ignores of eslint-config-next
|
|
41
|
-
|
|
42
|
-
'
|
|
43
|
-
'
|
|
45
|
+
// Default ignores of eslint-config-next (trailing slash prunes the whole
|
|
46
|
+
// directory instead of walking into it):
|
|
47
|
+
'.next/',
|
|
48
|
+
'out/',
|
|
49
|
+
'build/',
|
|
44
50
|
'next-env.d.ts',
|
|
45
51
|
// Build artifacts:
|
|
46
52
|
'server.js',
|
|
47
|
-
'dist
|
|
53
|
+
'dist/',
|
|
48
54
|
// Script files (CommonJS):
|
|
49
55
|
'scripts/**/*.js',
|
|
50
56
|
]),
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"build": "bash ./scripts/build.sh",
|
|
7
7
|
"dev": "bash ./scripts/dev.sh",
|
|
8
8
|
"preinstall": "npx only-allow pnpm",
|
|
9
|
-
"lint": "eslint",
|
|
9
|
+
"lint": "eslint --cache --cache-location node_modules/.cache/eslint/",
|
|
10
10
|
"lint:build": "eslint . --quiet",
|
|
11
11
|
"lint:style": "stylelint \"src/**/*.css\"",
|
|
12
12
|
"start": "bash ./scripts/start.sh",
|
|
@@ -28,7 +28,7 @@ Stop-ListeningProcess $port
|
|
|
28
28
|
|
|
29
29
|
<% if (process.env.NODE_ENV === 'test') { %>
|
|
30
30
|
$env:PORT = "$port"
|
|
31
|
-
& pnpm tsx watch src/server.ts
|
|
31
|
+
& pnpm tsx watch --ignore .next src/server.ts
|
|
32
32
|
exit $LASTEXITCODE
|
|
33
33
|
<% } else { %>
|
|
34
34
|
$logDirectory = if ($env:COZE_LOG_DIR) { $env:COZE_LOG_DIR } else { Join-Path $workspace "logs" }
|
|
@@ -45,7 +45,7 @@ if (Test-Path $pidFile) {
|
|
|
45
45
|
$previousPort = $env:PORT
|
|
46
46
|
$env:PORT = "$port"
|
|
47
47
|
try {
|
|
48
|
-
$process = Start-Process -FilePath $env:ComSpec -ArgumentList @("/d", "/s", "/c", "pnpm tsx watch src/server.ts") -WorkingDirectory $workspace -RedirectStandardOutput $logFile -RedirectStandardError $errorLogFile -PassThru
|
|
48
|
+
$process = Start-Process -FilePath $env:ComSpec -ArgumentList @("/d", "/s", "/c", "pnpm tsx watch --ignore .next src/server.ts") -WorkingDirectory $workspace -RedirectStandardOutput $logFile -RedirectStandardError $errorLogFile -PassThru
|
|
49
49
|
} finally {
|
|
50
50
|
if ($null -eq $previousPort) { Remove-Item Env:PORT -ErrorAction SilentlyContinue } else { $env:PORT = $previousPort }
|
|
51
51
|
}
|
|
@@ -14,6 +14,28 @@ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
|
|
|
14
14
|
|
|
15
15
|
cd "${COZE_WORKSPACE_PATH}"
|
|
16
16
|
|
|
17
|
+
configure_drive_watcher() {
|
|
18
|
+
local drive_root="${COZE_DRIVE_ROOT:-/Coze/Drive}"
|
|
19
|
+
local project_root
|
|
20
|
+
project_root="$(pwd -P)"
|
|
21
|
+
if [[ -d "${drive_root}" ]]; then
|
|
22
|
+
drive_root="$(cd "${drive_root}" && pwd -P)"
|
|
23
|
+
else
|
|
24
|
+
drive_root="${drive_root%/}"
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
case "${project_root}" in
|
|
28
|
+
"${drive_root}"|"${drive_root}"/*)
|
|
29
|
+
if [[ -n "${COZE_WATCH_POLL_INTERVAL_MS:-}" && -z "${WATCHPACK_POLLING+x}" ]]; then
|
|
30
|
+
export WATCHPACK_POLLING="${COZE_WATCH_POLL_INTERVAL_MS}"
|
|
31
|
+
echo "Using Watchpack polling every ${WATCHPACK_POLLING}ms."
|
|
32
|
+
fi
|
|
33
|
+
;;
|
|
34
|
+
esac
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
configure_drive_watcher
|
|
38
|
+
|
|
17
39
|
list_port_pids() {
|
|
18
40
|
local port=$1
|
|
19
41
|
local pids=""
|
|
@@ -55,10 +77,11 @@ kill_port_if_listening() {
|
|
|
55
77
|
<% if (process.env.NODE_ENV === 'test') { %>
|
|
56
78
|
echo "Clearing port ${DEPLOY_RUN_PORT} before start."
|
|
57
79
|
kill_port_if_listening
|
|
80
|
+
COZE_LOCAL_NEXT_OUTPUT=1 bash "${COZE_WORKSPACE_PATH}/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
|
|
58
81
|
echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
|
|
59
82
|
|
|
60
83
|
# 测试环境保持服务为前台进程,便于 e2e 收集输出并停止进程。
|
|
61
|
-
exec env PORT="${DEPLOY_RUN_PORT}" pnpm tsx
|
|
84
|
+
exec env PORT="${DEPLOY_RUN_PORT}" pnpm tsx src/server.ts
|
|
62
85
|
<% } else { %>
|
|
63
86
|
LOG_DIR="${COZE_LOG_DIR:-${COZE_WORKSPACE_PATH}/logs}"
|
|
64
87
|
LOG_FILE="${LOG_DIR}/app.log"
|
|
@@ -226,6 +249,7 @@ fi
|
|
|
226
249
|
|
|
227
250
|
echo "Clearing port ${DEPLOY_RUN_PORT} before start."
|
|
228
251
|
kill_port_if_listening
|
|
252
|
+
COZE_LOCAL_NEXT_OUTPUT=1 bash "${COZE_WORKSPACE_PATH}/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
|
|
229
253
|
echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
|
|
230
254
|
|
|
231
255
|
mkdir -p "${LOG_DIR}"
|
|
@@ -233,7 +257,7 @@ mkdir -p "${LOG_DIR}"
|
|
|
233
257
|
|
|
234
258
|
export PORT="${DEPLOY_RUN_PORT}"
|
|
235
259
|
server_pid="$(spawn_detached "${COZE_WORKSPACE_PATH}" "${LOG_FILE}" \
|
|
236
|
-
"$(command -v pnpm)" tsx
|
|
260
|
+
"$(command -v pnpm)" tsx src/server.ts)"
|
|
237
261
|
if [[ -z "${server_pid}" ]]; then
|
|
238
262
|
echo "Dev server failed to start: 未获取到后台进程 PID。" >&2
|
|
239
263
|
dump_log
|