# Next.js Standalone 模式详解 ## 📖 什么是 Standalone 模式? **Standalone 模式**是 Next.js 提供的一种**独立部署模式**,它会将应用及其所有运行时依赖打包成一个**自包含的独立目录**,可以直接在服务器上运行,**无需安装完整的项目依赖**。 ## 🔧 如何启用? 在 `next.config.mjs` 中配置: ```javascript const nextConfig = { output: 'standalone', // 启用 standalone 模式 // ... 其他配置 } ``` 你的项目已经启用: ```9:9:next.config.mjs output: 'standalone', ``` ## 📦 构建产物结构 ### 普通模式(非 standalone) ``` 项目根目录/ ├── .next/ # 构建输出 │ ├── static/ # 静态资源 │ └── server/ # 服务端代码(不完整) ├── node_modules/ # 需要完整安装所有依赖 ├── package.json └── public/ # 静态文件 ``` **部署时需要**: - 上传整个项目 - 在服务器上运行 `npm install` 安装所有依赖 - 使用 `npm start` 或 `next start` 启动 ### Standalone 模式 ``` .next/ └── standalone/ # 独立部署目录(包含所有运行时依赖) ├── server.js # 主启动文件 ⭐ ├── package.json # 精简的依赖列表 ├── node_modules/ # 只包含运行时必需的依赖(已优化) │ └── next/ # Next.js 核心 └── ... # 其他运行时文件 ``` **部署时只需要**: - 上传 `.next/standalone` 目录 - 复制 `.next/static` 静态资源 - 复制 `public` 目录 - 使用 `node server.js` 启动(**不需要 npm/next 命令**) ## 🚀 启动方式对比 ### 普通模式 ```bash # 需要先安装依赖 npm install --production # 使用 next 命令启动 npm start # 或 next start -p 30006 ``` ### Standalone 模式 ```bash # 不需要安装依赖,直接启动 node server.js # 或指定端口 PORT=30006 node server.js # 使用 PM2 pm2 start server.js --name soul ``` 你的项目 PM2 配置: ```10:10:ecosystem.config.cjs script: 'server.js', ``` ## ✨ Standalone 模式的优势 ### 1. **部署包更小** 📉 - 只包含运行时必需的依赖 - 不包含开发依赖(如 TypeScript、ESLint 等) - 通常比完整 `node_modules` 小 50-70% ### 2. **启动更快** ⚡ - 无需在服务器上运行 `npm install` - 直接运行 `node server.js` 即可 - 减少部署时间 ### 3. **环境独立** 🔒 - 不依赖服务器上的 Node.js 版本(只要兼容) - 不依赖全局安装的 npm 包 - 减少环境配置问题 ### 4. **适合单机/宝塔部署** - 产出目录小,无需完整 node_modules - 构建和运行环境分离 - 本项目使用 standalone 配合宝塔 + `scripts/devlop.py` 部署(见 `Next.js宝塔部署方案.md`)。 ### 5. **安全性更好** 🛡️ - 不暴露开发依赖 - 减少攻击面 - 生产环境更干净 ## ⚠️ 注意事项 ### 1. **启动方式不同** ❌ **错误**: ```bash npm start # standalone 模式下没有 next 命令 next start # 命令不存在 ``` ✅ **正确**: ```bash node server.js # 直接运行 Node.js ``` ### 2. **需要手动复制静态资源** Standalone 输出**不包含**: - `.next/static` - 静态资源(CSS、JS 等) - `public` - 公共静态文件 **部署时需要手动复制**: ```bash # 复制静态资源 cp -r .next/static /www/wwwroot/soul/.next/ cp -r public /www/wwwroot/soul/ ``` 你的部署脚本已经处理了: ```407:424:scripts/deploy_soul.py # 复制 .next/static static_dst = os.path.join(staging, ".next", "static") if os.path.exists(static_dst): shutil.rmtree(static_dst) os.makedirs(os.path.dirname(static_dst), exist_ok=True) shutil.copytree(static_src, static_dst) # 复制 public if os.path.isdir(public_src): public_dst = os.path.join(staging, "public") if os.path.exists(public_dst): shutil.rmtree(public_dst) shutil.copytree(public_src, public_dst) # 复制 ecosystem.config.cjs if os.path.isfile(ecosystem_src): shutil.copy2(ecosystem_src, os.path.join(staging, "ecosystem.config.cjs")) ``` ### 3. **Windows 构建问题** Windows 上构建 standalone 可能遇到符号链接权限问题: ``` EPERM: operation not permitted, symlink ``` **解决方案**(你的文档已说明): ```181:196:DEPLOYMENT.md ### Windows 本地执行 `pnpm build` 报 EPERM symlink 本项目使用 `output: 'standalone'`,构建时 Next.js 会创建符号链接。**Windows 默认不允许普通用户创建符号链接**,会报错: - `EPERM: operation not permitted, symlink ... -> .next\standalone\node_modules\...` **可选做法(任选其一):** 1. **开启 Windows 开发者模式(推荐,一劳永逸)** - 设置 → 隐私和安全性 → 针对开发人员 → **开发人员模式** 打开 - 开启后无需管理员即可创建符号链接,本地 `pnpm build` 可正常完成。 2. **以管理员身份运行终端再执行构建** - 右键 Cursor/终端 → "以管理员身份运行",在项目根目录执行 `pnpm build`。 若只做部署、不在本机打 standalone 包,可用 `python scripts/devlop.py --no-build` 跳过构建后上传已有包,或由服务器/计划任务在服务器上执行构建。 ``` ## 📊 对比总结 | 特性 | 普通模式 | Standalone 模式 | |------|---------|----------------| | **部署包大小** | 大(完整 node_modules) | 小(仅运行时依赖) | | **服务器安装** | 需要 `npm install` | 不需要 | | **启动命令** | `npm start` / `next start` | `node server.js` | | **部署时间** | 较慢(需安装依赖) | 较快(直接运行) | | **环境要求** | 需要 npm/next 命令 | 只需要 Node.js | | **适用场景** | 传统部署 | 容器化、独立部署 | ## 🎯 你的项目使用 Standalone 的原因 1. **宝塔服务器部署**:减少服务器上的依赖安装 2. **单机/宝塔部署**:目录小,启动快 3. **GitHub Actions 部署**:构建和运行环境分离 4. **团队协作**:减少环境配置问题 ## 📚 相关文档 - [Next.js Standalone 官方文档](https://nextjs.org/docs/pages/api-reference/next-config-js/output#standalone) - 你的项目部署文档:`DEPLOYMENT.md` - PM2 配置:`ecosystem.config.cjs` - 部署脚本:`scripts/deploy_soul.py`