AI-Toolkit 项目在 Windows PowerShell 环境下的启动失败问题排查报告

摘要

本文档记录了在 Windows 10/11 的 PowerShell 环境下,运行 ai-toolkit (ostris/ai-toolkit) 项目的 npm run build_and_start 命令时,出现生产环境启动失败问题的完整排查过程。

核心问题在于,项目依赖的 concurrently 包在特定 Windows + PowerShell + Node.js 环境组合下存在 Bug,导致其启动的子进程(nodenext)的当前工作目录被错误地设置为 C:\Windows\System32,而不是项目所在的目录。

最终解决方案是替换掉有问题的 concurrently 包,改用更稳定且功能相同的 npm-run-all 包来并行执行启动脚本。

1. 项目与环境信息
  • 项目名称: ai-toolkit
  • 项目地址: https://github.com/ostris/ai-toolkit
  • 操作系统: Windows 10 / 11
  • 终端环境: PowerShell
  • Node.js 版本: v18.20.8 (或其他 v18+ 版本)
  • 包管理器: npm
2. 初始问题现象

在项目 ui 目录下执行 npm run build_and_start 命令,build 过程成功,但在 start 阶段,终端反复输出以下错误:

[UI] [Error: Could not find a production build in the '.next' directory. Try building your app with 'next build' before starting the production server.]

这表明 next start 命令没有在包含 .next 文件夹的项目目录中执行。

3. 排查过程
第 1 轮尝试:修改路径为相对路径
  • 怀疑: package.json 中的 start 脚本为 worker 使用了绝对路径,可能导致 concurrently 对另一个命令(next start)的工作目录解析错误。
  • 操作: 将 start 脚本中的 "node M:/Git/ai-toolkit/ui/dist/worker.js" 修改为 "node dist/worker.js"
  • 结果: 失败。错误变得更明确,暴露了真实的问题:
    [WORKER] Error: Cannot find module 'C:\Windows\System32\dist\worker.js'
    
    这证明了 node 命令的执行目录是 C:\Windows\System32
第 2 轮尝试:使用 cd 强制指定工作目录
  • 怀疑: concurrently 无法正确继承当前目录,需要手动在命令中切换。
  • 操作: 将 start 脚本修改为使用 cd 命令先切换目录再执行:
    "start": "concurrently ... \"cd M:\\Git\\ai-toolkit\\ui && node dist/worker.js\" \"cd M:\\Git\\ai-toolkit\\ui && next start --port 8675\""
    
  • 结果: 失败。错误与上一轮完全相同,证明 cd ... && ... 这种复合命令在 concurrently 的子进程中没有生效。
第 3 轮尝试:使用 npm: 协议委托执行
  • 怀疑: concurrently 直接执行 node 命令有问题,但让它调用 npm 脚本本身可能更可靠。
  • 操作: 将脚本拆分,并使用 concurrentlynpm: 协议调用:
    "start:worker": "node dist/worker.js",
    "start:ui": "next start --port 8675",
    "start": "concurrently ... \"npm:start:worker\" \"npm:start:ui\""
    
  • 结果: 失败。出现了决定性的错误信息:
    [UI] npm error enoent Could not read package.json: Error: ENOENT: no such file or directory, open 'C:\Windows\System32\package.json'
    
    这个错误表明,concurrently 在启动 npm 子命令时,依然将工作目录设置为了 C:\Windows\System32。这最终确认了问题根源在于 concurrently 工具本身。
4. 根本原因

concurrently 包在某些 Windows 环境(特别是与 PowerShell 结合时)存在一个严重的 Bug,它无法正确地将父进程(您打开的终端)的工作目录传递给它所创建的子进程。它错误地将系统默认的 C:\Windows\System32 作为子进程的工作目录,导致所有依赖于相对路径或项目文件的命令(如 node dist/worker.jsnext start)全部失败。

5. 最终解决方案

既然 concurrently 是问题的根源,最直接有效的办法就是替换它。

  1. 安装替代品 npm-run-all:
    ui 目录下执行以下命令,安装一个功能相同但更稳定的工具:

    npm install npm-run-all --save-dev
    
  2. 修改 package.json:
    使用 npm-run-all 的语法重写 scripts 部分,它能正确处理并行任务和工作目录。

    "scripts": {
      "dev": "npm-run-all --parallel dev:worker dev:ui",
      "dev:worker": "ts-node-dev --respawn --watch cron --transpile-only cron/worker.ts",
      "dev:ui": "next dev --turbopack",
      "build": "tsc -p tsconfig.worker.json && next build",
      "start": "npm-run-all --parallel start:worker start:ui",
      "start:worker": "node dist/worker.js",
      "start:ui": "next start --port 8675",
      "build_and_start": "npm install && npm run update_db && npm run build && npm run start",
      "lint": "next lint",
      "update_db": "npx prisma generate && npx prisma db push",
      "format": "prettier --write \"**/*.{js,jsx,ts,tsx,css,scss}\""
    },
    
  3. 重新运行:
    执行 npm run build_and_startnpm run start,项目成功启动。

总结

当遇到 Node.js 脚本在特定平台(如 Windows PowerShell)上表现异常,尤其是出现“文件找不到”或“模块找不到”且路径指向系统目录时,应高度怀疑是进程管理工具(如 concurrently)与当前环境的兼容性问题。此时,替换为社区广泛认可的替代方案(如 npm-run-all)是最高效、最可靠的解决办法。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐