6.4 KiB
6.4 KiB
Next.js Standalone 模式详解
📖 什么是 Standalone 模式?
Standalone 模式是 Next.js 提供的一种独立部署模式,它会将应用及其所有运行时依赖打包成一个自包含的独立目录,可以直接在服务器上运行,无需安装完整的项目依赖。
🔧 如何启用?
在 next.config.mjs 中配置:
const nextConfig = {
output: 'standalone', // 启用 standalone 模式
// ... 其他配置
}
你的项目已经启用:
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 命令)
🚀 启动方式对比
普通模式
# 需要先安装依赖
npm install --production
# 使用 next 命令启动
npm start
# 或
next start -p 30006
Standalone 模式
# 不需要安装依赖,直接启动
node server.js
# 或指定端口
PORT=30006 node server.js
# 使用 PM2
pm2 start server.js --name soul
你的项目 PM2 配置:
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. 启动方式不同
❌ 错误:
npm start # standalone 模式下没有 next 命令
next start # 命令不存在
✅ 正确:
node server.js # 直接运行 Node.js
2. 需要手动复制静态资源
Standalone 输出不包含:
.next/static- 静态资源(CSS、JS 等)public- 公共静态文件
部署时需要手动复制:
# 复制静态资源
cp -r .next/static /www/wwwroot/soul/.next/
cp -r public /www/wwwroot/soul/
你的部署脚本已经处理了:
# 复制 .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
解决方案(你的文档已说明):
### 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 的原因
- 宝塔服务器部署:减少服务器上的依赖安装
- 单机/宝塔部署:目录小,启动快
- GitHub Actions 部署:构建和运行环境分离
- 团队协作:减少环境配置问题
📚 相关文档
- Next.js Standalone 官方文档
- 你的项目部署文档:
DEPLOYMENT.md - PM2 配置:
ecosystem.config.cjs - 部署脚本:
scripts/deploy_soul.py