Files
soul-yongping/开发文档/8、部署/Standalone模式说明.md
2026-02-09 15:09:29 +08:00

6.4 KiB
Raw Blame History

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 startnext 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 的原因

  1. 宝塔服务器部署:减少服务器上的依赖安装
  2. 单机/宝塔部署:目录小,启动快
  3. GitHub Actions 部署:构建和运行环境分离
  4. 团队协作:减少环境配置问题

📚 相关文档