Files
soul-yongping/开发文档/8、部署/Standalone模式说明.md

225 lines
6.4 KiB
Markdown
Raw Normal View History

2026-02-09 14:43:35 +08:00
# 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`