主要是为 Memento 项目的第一次发布做准备,发布前有一个非常重要的问题,就是我本地的测试数据有些是真实的应用需求,于是就让 AI 设计了一套备份导入导出的功能。
导出可能相对简单,只需要查一次表就行,然后包装成一个压缩包放包括聊天时的头像/附件等。导入这里面最麻烦的逻辑主要是数据改写,比如原先的 ID 在一个新的数据库表里避免重复和异常,需要生成一个新的再替换进去,AI 在这块有很充分的理解,甚至我根本没有刻意和它说,它自己就推理了出来并且良好的实现了。
上线到服务器时甚至服务器根本没有装 NodeJS,于是也花了点时间简单配置必要环境,依旧是参考自己 从零开始部署 Ubuntu 服务器环境 这篇老文(其实也更新过),到了最后的关键时刻,PM2 运行失败了!
pm2 log memento-web
vim /var/log/memento/web.error.log
2026-08-16 13:36:19 +00:00: /root/memento/apps/web/node_modules/.bin/react-router-serve:2
2026-08-16 13:36:19 +00:00: basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
2026-08-16 13:36:19 +00:00: ^^^^^^^
2026-08-16 13:36:19 +00:00:
2026-08-16 13:36:19 +00:00: SyntaxError: missing ) after argument list
2026-08-16 13:36:19 +00:00: at wrapSafe (node:internal/modules/cjs/loader:1804:18)
2026-08-16 13:36:19 +00:00: at Module._compile (node:internal/modules/cjs/loader:1846:20)
2026-08-16 13:36:19 +00:00: at Object..js (node:internal/modules/cjs/loader:2003:10)
2026-08-16 13:36:19 +00:00: at Module.load (node:internal/modules/cjs/loader:1594:32)
2026-08-16 13:36:19 +00:00: at Module._load (node:internal/modules/cjs/loader:1396:12)
2026-08-16 13:36:19 +00:00: at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
2026-08-16 13:36:19 +00:00: at loadCJSModuleWithModuleLoad (node:internal/modules/esm/translators:372:15)
2026-08-16 13:36:19 +00:00: at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:244:9)
2026-08-16 13:36:19 +00:00: at ModuleJob.run (node:internal/modules/esm/module_job:439:25)
2026-08-16 13:36:19 +00:00: at process.processTicksAndRejections (node:internal/process/task_queues:104:5)pm2 log memento-backend
vim /var/log/memento/backend.error.log
2026-08-16 13:36:19 +00:00: Error: Cannot find module 'express'
2026-08-16 13:36:19 +00:00: Require stack:
2026-08-16 13:36:19 +00:00: - /root/memento/apps/backend/dist/main.js
2026-08-16 13:36:19 +00:00: at Module._resolveFilename (node:internal/modules/cjs/loader:1517:15)
2026-08-16 13:36:19 +00:00: at wrapResolveFilename (node:internal/modules/cjs/loader:1071:27)
2026-08-16 13:36:19 +00:00: at defaultResolveImplForCJSLoading (node:internal/modules/cjs/loader:1095:10)
2026-08-16 13:36:19 +00:00: at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1122:12)
2026-08-16 13:36:19 +00:00: at Module._load (node:internal/modules/cjs/loader:1294:5)
2026-08-16 13:36:19 +00:00: at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
2026-08-16 13:36:19 +00:00: at Module.require (node:internal/modules/cjs/loader:1617:12)
2026-08-16 13:36:19 +00:00: at require (node:internal/modules/helpers:153:16)
2026-08-16 13:36:19 +00:00: at Object.<anonymous> (/root/memento/apps/backend/src/main.ts:10:1)
2026-08-16 13:36:19 +00:00: at Module._compile (node:internal/modules/cjs/loader:1872:14) {
2026-08-16 13:36:19 +00:00: code: 'MODULE_NOT_FOUND',
2026-08-16 13:36:19 +00:00: requireStack: [ '/root/memento/apps/backend/dist/main.js' ]
2026-08-16 13:36:19 +00:00: }依旧是 AI 分析,前者是 pm2 配置问题,把 react-router-serve 可执行文件当作 JS 解析了,后者是因为 express 没有显式写入到 Dependency 里面导致直接运行 JS 时找不到依赖。
{
name: "memento-web",
- script: "node_modules/.bin/react-router-serve",
+ script: "node_modules/@react-router/serve/bin.cjs",
}其实我总感觉 PM2 的启动方式挺奇怪的,但是又说不上原因。既不是完全安装依赖+构建后执行 nest start,又不能不装依赖直接使用生成好的 JS 文件。