@coze-arch/cli 0.1.8-alpha.7654a3 → 0.1.8-alpha.7f9604

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.
Files changed (47) hide show
  1. package/README.md +0 -18
  2. package/lib/__templates__/expo/.cozeproj/scripts/prepare-node-modules.sh +10 -178
  3. package/lib/__templates__/nextjs/.coze +1 -1
  4. package/lib/__templates__/nextjs/README.md +0 -18
  5. package/lib/__templates__/nextjs/eslint.config.mjs +1 -1
  6. package/lib/__templates__/nextjs/next.config.ts +9 -0
  7. package/lib/__templates__/nextjs/scripts/build.ps1 +1 -1
  8. package/lib/__templates__/nextjs/scripts/build.sh +2 -2
  9. package/lib/__templates__/nextjs/scripts/dev.ps1 +2 -2
  10. package/lib/__templates__/nextjs/scripts/dev.sh +55 -16
  11. package/lib/__templates__/nextjs/scripts/prepare-node-modules.sh +212 -0
  12. package/lib/__templates__/nextjs/scripts/prepare.sh +2 -10
  13. package/lib/__templates__/nextjs/scripts/validate.sh +1 -11
  14. package/lib/__templates__/nextjs/src/server.ts +1 -1
  15. package/lib/__templates__/nextjs/template.config.js +6 -20
  16. package/lib/__templates__/nextjs/tsconfig.json +1 -0
  17. package/lib/__templates__/nuxt-vue/.coze +1 -1
  18. package/lib/__templates__/nuxt-vue/README.md +2 -20
  19. package/lib/__templates__/nuxt-vue/scripts/build.sh +1 -1
  20. package/lib/__templates__/nuxt-vue/scripts/dev.sh +4 -10
  21. package/lib/__templates__/nuxt-vue/scripts/prepare-node-modules.sh +212 -0
  22. package/lib/__templates__/nuxt-vue/scripts/prepare.sh +2 -10
  23. package/lib/__templates__/nuxt-vue/scripts/validate.sh +1 -11
  24. package/lib/__templates__/taro/.coze +2 -2
  25. package/lib/__templates__/taro/.cozeproj/scripts/build-on-local-disk.sh +194 -0
  26. package/lib/__templates__/taro/.cozeproj/scripts/deploy_build.sh +1 -9
  27. package/lib/__templates__/taro/.cozeproj/scripts/dev_build.sh +1 -10
  28. package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +50 -51
  29. package/lib/__templates__/taro/.cozeproj/scripts/pack.sh +42 -13
  30. package/lib/__templates__/taro/.cozeproj/scripts/prepare-node-modules.sh +10 -178
  31. package/lib/__templates__/taro/.cozeproj/scripts/validate.sh +0 -3
  32. package/lib/__templates__/taro/package.json +5 -5
  33. package/lib/__templates__/vite/.coze +1 -1
  34. package/lib/__templates__/vite/README.md +0 -20
  35. package/lib/__templates__/vite/scripts/build.sh +1 -1
  36. package/lib/__templates__/vite/scripts/dev.sh +4 -10
  37. package/lib/__templates__/vite/scripts/prepare-node-modules.sh +212 -0
  38. package/lib/__templates__/vite/scripts/prepare.sh +2 -10
  39. package/lib/__templates__/vite/scripts/validate.sh +1 -7
  40. package/lib/__templates__/vite/template.config.js +6 -20
  41. package/lib/cli.js +184 -367
  42. package/package.json +1 -2
  43. package/lib/__templates__/nextjs/scripts/local-workspace.cjs +0 -302
  44. package/lib/__templates__/nuxt-vue/scripts/local-workspace.cjs +0 -302
  45. package/lib/__templates__/taro/.cozeproj/scripts/local-workspace.cjs +0 -351
  46. package/lib/__templates__/taro/.cozeproj/scripts/taro-build.cjs +0 -66
  47. package/lib/__templates__/vite/scripts/local-workspace.cjs +0 -302
package/README.md CHANGED
@@ -42,20 +42,6 @@ coze-dev validate # 读取 dev.validate
42
42
  `dev` 和 `build` 在执行前会尝试应用模板补丁;补丁失败会记录调试信息,但不会阻止主命令。
43
43
  子进程日志默认写入 `~/.coze-logs/dev.log`,可用 `--log-file <path>` 覆盖。
44
44
 
45
- ## Web 云盘开发
46
-
47
- Vite、Next.js、Nuxt 的 Unix 开发 wrapper 在 `COZE_DRIVE_ROOT`(默认 `/Coze/Drive`)内通过
48
- `rsync` 同步源码到本机临时目录 `coze-web-<uid>/<source-path-hash>/`,再安装依赖和执行。
49
- `prepare/dev` 使用 `dev` 子目录,`validate` 使用独立的 `check` 子目录,避免类型生成干扰热更新。
50
- 依赖和开发编译产物留在本地;只有安装成功且云盘依赖输入未变化时才回写锁文件。所有修复仍在云盘完成。
51
- dev 的 detached 进程持续同步,框架只监听本地镜像;同步失败或依赖输入变化时停止服务。
52
-
53
- 本地镜像仅用于 `[dev].build/run/validate`;部署配置、`build.sh` 和 `start.sh` 保持原流程。
54
- 普通本地目录和 Windows PowerShell 入口保持原流程。`rsync` 由开发环境提供,`[dev].deps` 仅作声明。
55
- 存量项目通过 `coze-dev patch --dry-run` / `coze-dev patch` 升级,沿用 patch 总开关。
56
- 仅升级完整匹配旧模板的三个 Unix 开发脚本并保留端口;自定义开发脚本、命令和同名 helper 会跳过。
57
- 只更新开发插件不会替换存量项目脚本。
58
-
59
45
  ## Windows 与 WSL
60
46
 
61
47
  原生 Windows(`process.platform === "win32"`)优先使用 `.coze` 中非空的 Windows
@@ -120,7 +106,3 @@ npm run build
120
106
  ```
121
107
 
122
108
  端到端模板验证使用 `npm run test:e2e`,会真实安装模板依赖并启动服务。发布前需完成该验证。
123
-
124
- Web 镜像集成测试使用 `npm run test:integration:web`,依赖 Node.js、bash、rsync 和临时
125
- loopback 监听权限;包管理器和框架命令使用替身,验证目录、同步、锁文件与进程生命周期,
126
- 不替代真实框架 E2E。
@@ -98,7 +98,6 @@ printf '%s\n' "$$" > "$LOCK_DIR/pid"
98
98
  trap release_lock EXIT
99
99
 
100
100
  mkdir -p "$WORK_DIR"
101
- INSTALL_STATE_FILE="$WORK_DIR/.install-state"
102
101
 
103
102
  # Previous versions mirrored the whole project into WORK_DIR. That gives pnpm
104
103
  # and framework dev servers two paths for the same source tree, which breaks
@@ -119,13 +118,12 @@ cleanup_legacy_workspace() {
119
118
  done < <(find "$workspace_dir" -mindepth 1 -maxdepth 1 -print0)
120
119
  }
121
120
 
122
- # Preserve existing project caches during dependency preparation.
123
121
  cleanup_legacy_shadow_project() {
124
122
  local entry name
125
123
  while IFS= read -r -d '' entry; do
126
124
  name="$(basename "$entry")"
127
125
  case "$name" in
128
- node_modules|client|server|caches|.install-state) continue ;;
126
+ node_modules|client|server) continue ;;
129
127
  esac
130
128
  rm -rf "$entry"
131
129
  done < <(find "$WORK_DIR" -mindepth 1 -maxdepth 1 -print0)
@@ -143,162 +141,6 @@ link_install_entry() {
143
141
  fi
144
142
  }
145
143
 
146
- hash_install_input() {
147
- if command -v sha256sum >/dev/null 2>&1; then
148
- sha256sum | awk '{print $1}'
149
- elif command -v shasum >/dev/null 2>&1; then
150
- shasum -a 256 | awk '{print $1}'
151
- else
152
- cksum | awk '{print $1 "-" $2}'
153
- fi
154
- }
155
-
156
- append_file_to_install_fingerprint() {
157
- local relative_path="$1"
158
- local source_path="$PROJECT_ROOT/$relative_path"
159
- printf 'path=%s\n' "$relative_path"
160
- if [ -f "$source_path" ]; then
161
- cat "$source_path"
162
- else
163
- printf '<missing>\n'
164
- fi
165
- }
166
-
167
- append_directory_to_install_fingerprint() {
168
- local relative_path="$1"
169
- local source_path="$PROJECT_ROOT/$relative_path"
170
- local file
171
- printf 'path=%s\n' "$relative_path"
172
- if [ ! -d "$source_path" ]; then
173
- printf '<missing>\n'
174
- return
175
- fi
176
-
177
- while IFS= read -r file; do
178
- printf 'file=%s\n' "${file#"${PROJECT_ROOT}/"}"
179
- cat "$file"
180
- done < <(find -P "$source_path" -type f -print | LC_ALL=C sort)
181
- }
182
-
183
- # Everything that can change the resolved dependency tree. The leading version marker
184
- # invalidates every stored state when this scheme itself changes.
185
- calculate_install_fingerprint() {
186
- local filename workspace argument
187
- {
188
- printf 'prepare-node-modules-install-state=1\n'
189
- printf 'node-version=%s\n' "$(node --version)"
190
- printf 'pnpm-version=%s\n' "$(pnpm --version)"
191
- printf 'node-env=%s\n' "${NODE_ENV:-}"
192
- printf 'npm-config-production=%s\n' "${npm_config_production:-}"
193
- printf 'npm-config-production-upper=%s\n' "${NPM_CONFIG_PRODUCTION:-}"
194
- printf 'pnpm-config-production=%s\n' "${PNPM_CONFIG_PRODUCTION:-}"
195
- for argument in "$@"; do
196
- printf 'install-argument=%s\n' "$argument"
197
- done
198
- for filename in package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc; do
199
- append_file_to_install_fingerprint "$filename"
200
- done
201
- for workspace in client server; do
202
- append_file_to_install_fingerprint "$workspace/package.json"
203
- done
204
- append_directory_to_install_fingerprint patches
205
- } | hash_install_input
206
- }
207
-
208
- install_requires_refresh() {
209
- local argument
210
- for argument in "$@"; do
211
- case "$argument" in
212
- --force|-f|--lockfile-only|--fix-lockfile) return 0 ;;
213
- esac
214
- done
215
- return 1
216
- }
217
-
218
- # Reuse skips pnpm install entirely, so it must not skip side effects that live outside
219
- # node_modules. preinstall is exempt: it only guards which package manager may run, and
220
- # there is no install to guard when the tree is already in place.
221
- package_has_install_lifecycle() {
222
- local package_path="$1"
223
- node - "$package_path" <<'NODE'
224
- const fs = require('node:fs');
225
- const [packagePath] = process.argv.slice(2);
226
-
227
- try {
228
- const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
229
- const scripts = packageJson && typeof packageJson.scripts === 'object' && packageJson.scripts
230
- ? packageJson.scripts
231
- : {};
232
- const hasLifecycle = ['install', 'postinstall', 'prepare'].some(
233
- name => typeof scripts[name] === 'string' && scripts[name].trim() !== '',
234
- );
235
-
236
- process.exit(hasLifecycle ? 0 : 1);
237
- } catch {
238
- process.exit(0);
239
- }
240
- NODE
241
- }
242
-
243
- install_reuse_is_safe() {
244
- local workspace package_path
245
- for package_path in "$PROJECT_ROOT/.pnpmfile.cjs" "$PROJECT_ROOT/.pnpmfile.js"; do
246
- if [ -e "$package_path" ]; then
247
- echo "[node_modules] Reinstalling because pnpm hooks are present: $package_path"
248
- return 1
249
- fi
250
- done
251
-
252
- if [ -f "$PROJECT_ROOT/.npmrc" ] && grep -Eq '^[[:space:]]*pnpmfile[[:space:]]*=' "$PROJECT_ROOT/.npmrc"; then
253
- echo "[node_modules] Reinstalling because .npmrc configures a pnpm hook."
254
- return 1
255
- fi
256
-
257
- for workspace in . client server; do
258
- package_path="$PROJECT_ROOT/$workspace/package.json"
259
- [ -f "$package_path" ] || continue
260
- if package_has_install_lifecycle "$package_path"; then
261
- echo "[node_modules] Reinstalling because $package_path has an install lifecycle script."
262
- return 1
263
- fi
264
- done
265
- return 0
266
- }
267
-
268
- dependencies_are_ready() {
269
- local workspace
270
- [ -f "$WORK_DIR/node_modules/.modules.yaml" ] || return 1
271
- for workspace in client server; do
272
- if [ -f "$PROJECT_ROOT/$workspace/package.json" ] &&
273
- [ ! -f "$WORK_DIR/$workspace/node_modules/.modules.yaml" ]; then
274
- return 1
275
- fi
276
- done
277
- return 0
278
- }
279
-
280
- # 判断顺序按代价从小到大排。指纹要读云盘上的 lockfile 和整个 patches/,所以放最后:只有其余
281
- # 条件都满足、确实可能复用时才付这份开销。build.sh 和 prepare.sh 不设开关,第一行就返回了。
282
- install_can_be_reused() {
283
- local installed_fingerprint=""
284
-
285
- [ "${COZE_REUSE_NODE_MODULES:-}" = "1" ] || return 1
286
- install_requires_refresh "$@" && return 1
287
- [ -f "$INSTALL_STATE_FILE" ] || return 1
288
- IFS= read -r installed_fingerprint < "$INSTALL_STATE_FILE" || return 1
289
- dependencies_are_ready || return 1
290
- install_reuse_is_safe || return 1
291
- [ "$installed_fingerprint" = "$(calculate_install_fingerprint "$@")" ] || return 1
292
- return 0
293
- }
294
-
295
- write_install_state() {
296
- local fingerprint="$1" temporary_state
297
- temporary_state="$(mktemp "$WORK_DIR/.install-state.XXXXXX")"
298
- printf '%s\n' "$fingerprint" > "$temporary_state"
299
- mv -f "$temporary_state" "$INSTALL_STATE_FILE"
300
- }
301
-
302
144
  copy_install_metadata() {
303
145
  local filename source_file target_file workspace
304
146
  for filename in pnpm-lock.yaml pnpm-workspace.yaml .npmrc; do
@@ -348,26 +190,16 @@ link_node_modules() {
348
190
  cleanup_legacy_shadow_project
349
191
  copy_install_metadata
350
192
 
351
- if install_can_be_reused "$@"; then
352
- echo "[node_modules] Reusing unchanged dependencies in $WORK_DIR"
353
- else
354
- # A stale state file must not survive a failed install.
355
- rm -f "$INSTALL_STATE_FILE"
356
- echo "[node_modules] Installing dependencies in $WORK_DIR"
357
- if ! (cd "$WORK_DIR" && pnpm install "$@"); then
358
- exit 1
359
- fi
360
-
361
- if [ -f "$WORK_DIR/pnpm-lock.yaml" ]; then
362
- temporary_lockfile="$(mktemp "$PROJECT_ROOT/.pnpm-lock.yaml.XXXXXX")"
363
- cp "$WORK_DIR/pnpm-lock.yaml" "$temporary_lockfile"
364
- chmod 0644 "$temporary_lockfile"
365
- mv -f "$temporary_lockfile" "$PROJECT_ROOT/pnpm-lock.yaml"
366
- fi
193
+ echo "[node_modules] Installing dependencies in $WORK_DIR"
194
+ if ! (cd "$WORK_DIR" && pnpm install "$@"); then
195
+ exit 1
196
+ fi
367
197
 
368
- # pnpm may have rewritten the lockfile, so record the fingerprint of the tree as it
369
- # now stands. Otherwise the next run would see a changed input and reinstall.
370
- write_install_state "$(calculate_install_fingerprint "$@")"
198
+ if [ -f "$WORK_DIR/pnpm-lock.yaml" ]; then
199
+ temporary_lockfile="$(mktemp "$PROJECT_ROOT/.pnpm-lock.yaml.XXXXXX")"
200
+ cp "$WORK_DIR/pnpm-lock.yaml" "$temporary_lockfile"
201
+ chmod 0644 "$temporary_lockfile"
202
+ mv -f "$temporary_lockfile" "$PROJECT_ROOT/pnpm-lock.yaml"
371
203
  fi
372
204
 
373
205
  link_node_modules "$PROJECT_ROOT" "$WORK_DIR/node_modules"
@@ -9,7 +9,7 @@ run = ["bash", "./scripts/dev.sh"]
9
9
  run_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/dev.ps1"]
10
10
  validate = ["bash", "./scripts/validate.sh"]
11
11
  validate_win = ["powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "./scripts/validate.ps1"]
12
- deps = ["git", "rsync"] # -> apt install git rsync
12
+ deps = ["git"] # -> apt install git
13
13
 
14
14
  [deploy]
15
15
  build = ["bash","./scripts/build.sh"]
@@ -361,21 +361,3 @@ export const useStore = create<Store>((set) => ({
361
361
  3. **遵循 Next.js App Router 规范**,正确区分服务端/客户端组件
362
362
  4. **使用 TypeScript** 进行类型安全开发
363
363
  5. **使用 `@/` 路径别名** 导入模块(已配置)
364
-
365
- ## 云盘源码与本地开发
366
-
367
- Vite、Next.js、Nuxt 的 Unix 开发脚本在 `COZE_DRIVE_ROOT`(默认 `/Coze/Drive`)内通过
368
- `scripts/local-workspace.cjs` 将源码用 `rsync` 同步到本机临时目录。系统需提供 Node.js、pnpm、bash 和 rsync。
369
- 所有开发与修复仍在云盘源码目录完成,从该目录执行 `.coze` 的 `[dev]` 命令。
370
-
371
- - `prepare.sh` 同步并在本地安装依赖;安装成功且云盘依赖输入未变化时,仅将更新的锁文件回写云盘。
372
- - `dev.sh` 在本地镜像运行开发服务,每轮 rsync 结束后等待一秒再同步,框架监听本地文件进行热更新。
373
- 同步失败或依赖输入变化时停止服务;修复后重新运行 `prepare.sh` / `dev.sh`。
374
- - `validate.sh` 使用独立的本地 `check` 目录,避免类型生成影响正在运行的 `dev` 服务。
375
- - 同步排除 `.git`、`node_modules`、日志和框架输出;不要在镜像修复源码或将依赖、编译产物回传云盘。
376
- 日志和 PID 默认保留在源码目录的 `logs/`,实际镜像路径见脚本输出。
377
-
378
- 本地镜像仅用于 `[dev].build/run/validate`。部署配置、`build.sh`、`start.sh` 保持原流程;
379
- 普通本地目录和 Windows PowerShell 入口也保持原流程。
380
- 存量项目通过新版 CLI 的 `coze-dev patch --dry-run` / `coze-dev patch` 升级,沿用 patch 总开关。
381
- 仅升级完整匹配旧模板的三个 Unix 开发脚本并保留端口;自定义开发脚本、命令或同名 helper 会跳过。
@@ -52,7 +52,7 @@ const eslintConfig = defineConfig([
52
52
  'server.js',
53
53
  'dist/',
54
54
  // Script files (CommonJS):
55
- 'scripts/**/*.{js,cjs}',
55
+ 'scripts/**/*.js',
56
56
  ]),
57
57
  ]);
58
58
 
@@ -1,9 +1,18 @@
1
1
  import type { NextConfig } from 'next';
2
+ import path from 'path';
2
3
 
3
4
  const nextConfig: NextConfig = {
4
5
  // outputFileTracingRoot: path.resolve(__dirname, '../../'), // Uncomment and add 'import path from "path"' if needed
5
6
  /* config options here */
6
7
  serverExternalPackages: ['coze-coding-dev-sdk'],
8
+ webpack: (config, { dev }) => {
9
+ if (dev && config.cache && config.cache.type === 'filesystem') {
10
+ config.cache.cacheDirectory = path.resolve(
11
+ 'node_modules/.cache/next-webpack',
12
+ );
13
+ }
14
+ return config;
15
+ },
7
16
  allowedDevOrigins: ['*.dev.coze.site'],
8
17
  images: {
9
18
  remotePatterns: [
@@ -8,7 +8,7 @@ Write-Host "Installing dependencies..."
8
8
  if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
9
9
 
10
10
  Write-Host "Building the Next.js project..."
11
- & pnpm next build
11
+ & pnpm next build --webpack
12
12
  if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
13
13
 
14
14
  Write-Host "Bundling server with tsup..."
@@ -6,10 +6,10 @@ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
6
6
  cd "${COZE_WORKSPACE_PATH}"
7
7
 
8
8
  echo "Installing dependencies..."
9
- pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
9
+ bash "$COZE_WORKSPACE_PATH/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
10
10
 
11
11
  echo "Building the Next.js project..."
12
- pnpm next build
12
+ pnpm next build --webpack
13
13
 
14
14
  echo "Bundling server with tsup..."
15
15
  pnpm tsup src/server.ts --format cjs --platform node --target node20 --outDir dist --no-splitting --no-minify
@@ -28,7 +28,7 @@ Stop-ListeningProcess $port
28
28
 
29
29
  <% if (process.env.NODE_ENV === 'test') { %>
30
30
  $env:PORT = "$port"
31
- & pnpm next dev --hostname 0.0.0.0 --port $port
31
+ & pnpm next dev --webpack --hostname 0.0.0.0 --port $port
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 next dev --hostname 0.0.0.0 --port $port") -WorkingDirectory $workspace -RedirectStandardOutput $logFile -RedirectStandardError $errorLogFile -PassThru
48
+ $process = Start-Process -FilePath $env:ComSpec -ArgumentList @("/d", "/s", "/c", "pnpm next dev --webpack --hostname 0.0.0.0 --port $port") -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
  }
@@ -1,20 +1,14 @@
1
1
  #!/bin/bash
2
2
  set -Eeuo pipefail
3
3
 
4
- # Resolve the source project from this script, then let the Web runner choose its local mirror.
5
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
6
- PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd -P)"
7
- if [[ "${COZE_WEB_LOCAL_ACTIVE:-}" != "${PROJECT_ROOT}" ]]; then
8
- exec node "${SCRIPT_DIR}/local-workspace.cjs" dev "$@"
9
- fi
10
- COZE_WORKSPACE_PATH="${PROJECT_ROOT}"
11
-
12
4
  <% if (process.env.NODE_ENV === 'test') { %>
13
5
  # 测试环境:支持环境变量覆盖端口
14
6
  PORT="${PORT:-<%= port %>}"
7
+ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
15
8
  DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
16
9
  <% } else { %>
17
10
  PORT="${DEPLOY_RUN_PORT:-${PORT:-<%= port %>}}"
11
+ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
18
12
  DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
19
13
  <% } %>
20
14
 
@@ -58,17 +52,62 @@ kill_port_if_listening() {
58
52
  echo "Port ${DEPLOY_RUN_PORT} cleared."
59
53
  }
60
54
 
55
+ # Next 的路由清单由 watchpack 每次启动重新扫 src 下的 app/pages 目录现算,而 watchpack
56
+ # 不会进入软链目录,软链子树里的 page/route 会被静默跳过:既不注册路由,也不打任何日志,
57
+ # 表现为该路由一直 404 而 .next 里没有它的产物。这里只做提示,不改动源码。
58
+ warn_source_symlinks() {
59
+ local source_dir="${COZE_WORKSPACE_PATH}/src"
60
+ local links link
61
+ if [[ ! -e "${source_dir}" ]]; then
62
+ return
63
+ fi
64
+ links=$(find "${source_dir}" -type l 2>/dev/null || true)
65
+ if [[ -z "${links}" ]]; then
66
+ return
67
+ fi
68
+ echo "Warning: 以下路径是软链,Next 不会进入其中,里面的 page/route 不会被编译:" >&2
69
+ while IFS= read -r link; do
70
+ echo " ${link}" >&2
71
+ done <<< "${links}"
72
+ }
73
+
74
+ # 云盘挂载偶尔会把新建文件的 mtime 设为 Unix epoch。Watchpack 会因此把路由文件当作
75
+ # 启动前的旧状态,导致 Next 的首轮扫描漏掉 route/page。只在云盘项目启动前刷新 app/pages
76
+ # 的目录和普通文件时间戳;不跟随软链、不改文件内容。
77
+ refresh_drive_route_mtimes() {
78
+ local drive_root="${COZE_DRIVE_ROOT:-/Coze/Drive}"
79
+ local project_root route_dir
80
+ project_root="$(pwd -P)"
81
+ if [[ -d "${drive_root}" ]]; then
82
+ drive_root="$(cd "${drive_root}" && pwd -P)"
83
+ else
84
+ drive_root="${drive_root%/}"
85
+ fi
86
+
87
+ case "${project_root}" in
88
+ "${drive_root}"|"${drive_root}"/*) ;;
89
+ *) return ;;
90
+ esac
91
+
92
+ for route_dir in "${COZE_WORKSPACE_PATH}/src/app" "${COZE_WORKSPACE_PATH}/src/pages"; do
93
+ [[ -d "${route_dir}" ]] || continue
94
+ if ! find -P "${route_dir}" \( -type f -o -type d \) -exec touch {} + 2>/dev/null; then
95
+ echo "Warning: failed to refresh Next route timestamps in ${route_dir}." >&2
96
+ fi
97
+ done
98
+ }
99
+
61
100
  <% if (process.env.NODE_ENV === 'test') { %>
62
101
  echo "Clearing port ${DEPLOY_RUN_PORT} before start."
63
102
  kill_port_if_listening
64
- if [[ "${COZE_WEB_LOCAL_MIRROR:-}" != "1" ]]; then
65
- pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
66
- fi
103
+ bash "${COZE_WORKSPACE_PATH}/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
104
+ warn_source_symlinks
105
+ refresh_drive_route_mtimes
67
106
  echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
68
107
 
69
108
  # 测试环境保持服务为前台进程,便于 e2e 收集输出并停止进程。
70
109
  # 开发环境直接使用 Next 的 dev CLI,避免云盘文件事件在 custom server 链路中丢失。
71
- exec node "${SCRIPT_DIR}/local-workspace.cjs" watch pnpm next dev --hostname 0.0.0.0 --port "${DEPLOY_RUN_PORT}"
110
+ exec pnpm next dev --webpack --hostname 0.0.0.0 --port "${DEPLOY_RUN_PORT}"
72
111
  <% } else { %>
73
112
  LOG_DIR="${COZE_LOG_DIR:-${COZE_WORKSPACE_PATH}/logs}"
74
113
  LOG_FILE="${LOG_DIR}/app.log"
@@ -255,9 +294,9 @@ fi
255
294
 
256
295
  echo "Clearing port ${DEPLOY_RUN_PORT} before start."
257
296
  kill_port_if_listening
258
- if [[ "${COZE_WEB_LOCAL_MIRROR:-}" != "1" ]]; then
259
- pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
260
- fi
297
+ bash "${COZE_WORKSPACE_PATH}/scripts/prepare-node-modules.sh" --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
298
+ warn_source_symlinks
299
+ refresh_drive_route_mtimes
261
300
  echo "Starting HTTP service on port ${DEPLOY_RUN_PORT} for dev..."
262
301
 
263
302
  mkdir -p "${LOG_DIR}"
@@ -265,7 +304,7 @@ mkdir -p "${LOG_DIR}"
265
304
 
266
305
  export PORT="${DEPLOY_RUN_PORT}"
267
306
  server_pid="$(spawn_detached "${COZE_WORKSPACE_PATH}" "${LOG_FILE}" \
268
- "$(command -v node)" "${SCRIPT_DIR}/local-workspace.cjs" watch "$(command -v pnpm)" next dev --hostname 0.0.0.0 --port "${DEPLOY_RUN_PORT}")"
307
+ "$(command -v pnpm)" next dev --webpack --hostname 0.0.0.0 --port "${DEPLOY_RUN_PORT}")"
269
308
  if [[ -z "${server_pid}" ]]; then
270
309
  echo "Dev server failed to start: 未获取到后台进程 PID。" >&2
271
310
  dump_log