You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在IIS应用中部署Next.js时node_modules更新问题咨询

Next.js + IIS + Azure DevOps CI/CD 部署问题解决思路

当前部署方式

已成功在IIS根/子应用中部署Next.js应用,手动部署流程为:执行next build后,将构建输出的.next文件夹、node_modules、自定义web.config、server.js复制到IIS指向的构建目录,IISNode运行后会自动生成iisnode文件夹,最终目录结构如下:

next-build
├── .next
├── node_modules
├── web.config
├── server.js
└── iisnode

核心问题

引入Azure DevOps CI/CD流水线后,生成的工件部署到IIS构建目录时,node_modules无法自动更新。尝试过Next.js的standalone输出模式(该模式会在构建产物中包含依赖),但存在兼容性问题无法正常运行。希望找到自动部署时添加node_modules的方案,考虑过在部署阶段执行yarn install,但对Azure DevOps不熟悉,不确定如何实现(此方案需要同时部署package.json)。

相关代码

Server.js

const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');

const dev = process.env.NODE_ENV !== 'production';
const port = process.env.PORT || 3000;
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
    createServer((req, res) => {
        const parsedUrl = parse(req.url, true);
        const { pathname, query } = parsedUrl;
        console.log(parsedUrl);
        console.log(req.headers);
        if (pathname.startsWith('/next-build')) {
            const page = pathname === '/next-build' ? '/' : pathname.substring('/next-build/'.length);
            return app.render(req, res, page, query);
        } else {
            return app.render(req, res, '/next-build', query);
        }
    }).listen(port, (err) => {
        if (err) throw err;
        console.log(`> Ready on http://localhost:${port}`);
    });
});

Azure DevOps 流水线YAML配置

trigger:
- main

pool:
  name: BuildServer

steps:
- task: NodeTool@0
  inputs:
    versionSpec: '18.x'
  displayName: '安装 Node.js'

- script: |
    npm install -g yarn
  displayName: '全局安装 yarn'

- script: |
    yarn install
  displayName: '安装项目依赖'

- script: |
    npm run build
  displayName: '执行 Next.js 构建'

- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: $(build.SourcesDirectory)/.next
    ArtifactName: deploy
    publishLocation: 'Container'

错误信息

错误信息

复现步骤

  • 执行npx create-next-app@latest创建基于Pages路由的Next.js应用
  • 在next.config.js中添加对应IIS应用名称的basePath,例如:basePath: "/next-build"
  • 将代码推送至Azure DevOps仓库
  • 创建新流水线并关联代码仓库
  • 使用上述YAML配置运行流水线,下载生成的工件
  • 解压工件并放入IIS构建文件夹
  • 在IIS中创建应用池并配置正确权限
  • 在Default Web Site下创建名为next-build的子应用,关联上述应用池,物理路径指向构建文件夹
  • 确保站点/应用的访问用户拥有读写权限
  • 安装iisnode和URL Rewrite模块
  • 添加适配IIS的web.config文件
  • 添加上述自定义server.js文件
  • 访问应用即可触发错误

解决方案建议

方案1:调整流水线工件,部署时安装生产依赖

  1. 修改流水线的工件发布范围:
    不要只发布.next文件夹,需要将package.json、yarn.lock(或package-lock.json)、server.js、web.config都纳入发布范围。可以添加CopyFiles任务将这些文件复制到统一输出目录,再发布该目录:
    # 在build步骤后添加
    - task: CopyFiles@2
      inputs:
        SourceFolder: '$(build.SourcesDirectory)'
        Contents: |
          package.json
          yarn.lock
          server.js
          web.config
        TargetFolder: '$(build.ArtifactStagingDirectory)/deploy'
        OverWrite: true
    - task: CopyFiles@2
      inputs:
        SourceFolder: '$(build.SourcesDirectory)/.next'
        Contents: '**'
        TargetFolder: '$(build.ArtifactStagingDirectory)/deploy/.next'
        OverWrite: true
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(build.ArtifactStagingDirectory)/deploy'
        ArtifactName: deploy
        publishLocation: 'Container'
    
  2. 在部署阶段添加依赖安装步骤:
    使用Azure DevOps的部署任务或自定义脚本,在将工件部署到IIS服务器后,执行yarn install --production(仅安装生产依赖,减少体积)。确保部署用户拥有服务器构建目录的读写权限。

方案2:构建阶段打包生产依赖(不推荐,依赖体积大)

如果必须在构建阶段完成依赖打包,可以在流水线中添加ArchiveFiles任务,将.next、node_modules、必要配置文件一起打包成压缩包发布。但此方案会增大工件体积,且依赖更新时需要重新构建整个工件,灵活性较差。

额外检查点

  • 确认IIS应用池的身份用户拥有构建目录的读写权限,确保yarn install能正常写入文件
  • 检查web.config中的iisnode配置,确保指向正确的server.js路径
  • 确认服务器上安装了对应版本的Node.js和yarn,避免版本不兼容问题

内容的提问来源于stack exchange,提问作者Tim van Dam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 06:24:56