返回

IIS部署Nuxt.js避坑指南:端口冲突、配置详解

vue.js

IIS 部署 Nuxt.js 项目避坑指南

想用 IIS 部署 Nuxt.js 项目?结果卡住了?用 npm run start 倒是能在服务器上跑起来,但问题是 80 端口已经被其他项目(比如 .NET 的管理后台和 API)占用了。IIS 的目录结构也和本地开发不一样,直接把项目丢进去肯定不行。别急,这篇博客就来手把手教你解决这些问题。

问题出在哪?

简单来说,问题主要集中在这几点:

  1. 端口冲突: 默认情况下,Nuxt.js 开发服务器和你的其他项目都可能尝试使用 80 端口。
  2. IISNode 配置: IISNode 需要正确配置才能处理 Nuxt.js 应用,原有的 web.config 可能存在问题。
  3. 运行环境差异: 直接 npm run start 和通过 IISNode 运行,环境配置可能不一样,导致一些意料之外的错误。比如ES6语法支持的问题。
  4. Nuxt.js 构建: 确保正确构建了生产环境可以使用的代码包.

解决方案:搞定 Nuxt.js 的 IIS 部署

针对上面提到的问题,我们可以分几个步骤来解决:

1. 修改 Nuxt.js 的默认端口

既然 80 端口冲突,那就给 Nuxt.js 应用换个端口。

原理: Nuxt.js 允许通过配置来指定运行端口。

操作:

  • 打开 nuxt.config.js 文件(或者 nuxt.config.ts,如果你用 TypeScript)。
  • 找到 server 部分(如果没有,就手动添加):
// nuxt.config.js
export default {
  // ... 其他配置
  server: {
    port: 3001, // 或者任何你喜欢的未被占用的端口
    host: '0.0.0.0' // 监听所有 IPv4 地址,确保可以通过服务器 IP 访问
  },
  // ... 其他配置
}
  • 保存文件。
  • 现在如果你使用 npm run dev,开发服务就会使用3001作为端口

2. 正确配置 IISNode

你的 web.config 文件里有些地方需要修改,IISNode 才能正确接管 Nuxt.js 应用。

原理: IISNode 通过 web.config 文件来了解如何启动和管理 Node.js 进程。

操作:

  • 创建一个新的web.config,使用以下内容来替换你现有 web.config 文件的内容:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="iisnode" path="server.js" verb="*" modules="iisnode" />
    </handlers>
    <rewrite>
      <rules>
        <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
            <match url="^server.js\/debug[\/]?" />
        </rule>
        <rule name="StaticContent">
          <action type="Rewrite" url="public{REQUEST_URI}" />
        </rule>
        <rule name="DynamicContent">
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
          </conditions>
          <action type="Rewrite" url="server.js" />
        </rule>
      </rules>
    </rewrite>
    <iisnode
        nodeProcessCommandLine="&quot;%programfiles%\nodejs\node.exe&quot;"
        watchedFiles="web.config;*.js;server\*.js;nuxt.config.js"
        nodeProcessCountPerApplication="1"
        maxConcurrentRequestsPerProcess="1024"
        maxNamedPipeConnectionRetry="100"
        namedPipeConnectionRetryDelay="250"
        maxNamedPipeConnectionPoolSize="512"
        maxNamedPipePooledConnectionAge="30000"
        asyncCompletionThreadCount="0"
        initialRequestBufferSize="4096"
        maxRequestBufferSize="65536"
        uncFileChangesPollingInterval="5000"
        gracefulShutdownTimeout="60000"
        loggingEnabled="true"
        logDirectoryNameSuffix="logs"
        debuggingEnabled="false"
        debugHeaderEnabled="false"
        debuggerPortRange="5058-6058"
        debuggerPathSegment="debug"
        maxLogFileSizeInKB="128"
        maxTotalLogFileSizeInKB="1024"
        maxLogFiles="20"
        devErrorsEnabled="true"
        flushResponse="false"
        enableXFF="false"
        promoteServerVars=""
        configOverrides="iisnode.yml"
    />

    <security>
      <requestFiltering>
        <hiddenSegments>
          <remove segment="bin" />
          <add segment="node_modules" />
          <add segment="server" />
        </hiddenSegments>
      </requestFiltering>
    </security>
        <httpErrors existingResponse="PassThrough" />
  </system.webServer>
</configuration>
  • 注意几个关键点:

    • path="server.js": 这表示 IISNode 会尝试运行 server.js 文件。 之后我们会创建这个文件。
    • watchedFiles: 添加了你希望监听变化后自动重启应用的文件,包括nuxt.config.js。
    • hiddenSegments:隐藏server目录.
    • <iisnode nodeProcessCommandLine...>: 这部分配置是直接配置 iisnode,可以精细控制 iisnode 的行为。nodeProcessCommandLine 指定 Node.js 可执行文件的路径(确保路径正确!)。

3. 适配服务器环境:创建启动脚本(server.js

IISNode 通过 server.js 来启动 Nuxt.js,因此要创建一个文件来启动Nuxt服务.

原理: 通过自定义的服务端入口来启动Nuxt服务。

操作:

  1. 在项目根目录创建一个 server.js 文件。
  2. 将下面的代码添加到server.js中:
const { loadNuxt, build } = require('nuxt')

const isDev = process.env.NODE_ENV !== 'production'
const config = require('./nuxt.config.js')

async function start() {
  const nuxt = await loadNuxt(isDev ? 'dev' : 'start')

    if (isDev) {
        build(nuxt)
    }

  const {
    host = process.env.HOST || '127.0.0.1',
    port = process.env.PORT || 3000
  } = nuxt.options.server

  await nuxt.listen(port, host)
  console.log(`Server listening on http://${host}:${port}`)

}

start()

解释一下:
* 加载nuxt: 代码先加载 Nuxt.js。
* 判断环境: 根据 NODE_ENV 环境变量判断是否为开发环境.
* 构建应用(开发环境):如果是开发环境,会进行 Nuxt.js 构建。
* 获取端口和主机:从 Nuxt.js 配置或环境变量中获取端口和主机。
* 启动监听:在指定端口和主机上启动 Nuxt.js 服务器。

4. 执行构建

在部署之前,确保已经为生产环境构建了 Nuxt.js 应用。

原理: 构建过程会优化代码、打包静态资源,为生产环境做好准备。

操作:

  • 在你的项目根目录打开命令行或终端。
  • 运行以下命令:
npm run build

或者 如果使用 yarn:

yarn build

5. 将项目部署到 IIS

现在,可以将你的 Nuxt.js 项目部署到 IIS 了。

操作:

  1. 创建站点: 在 IIS 管理器中,创建一个新的网站,或者使用现有网站下的一个应用程序。
  2. 设置物理路径: 将网站或应用程序的物理路径指向你的 Nuxt.js 项目的根目录(包含 package.jsonnuxt.config.jsserver.js 等文件的那个目录)。确保也包括.nuxt目录, 因为构建的文件存储于这个文件夹.
  3. 应用程序池: 确保网站或应用程序使用的应用程序池的 .NET CLR 版本设置为“无托管代码”。
  4. 复制文件: 将包括.nuxt 在内的文件都拷贝到IIS服务器.
  5. 重启站点: 在IIS重启动该站点。

进阶技巧 & 额外建议

  • 环境变量: 可以利用环境变量(例如在 web.configappSettings 部分)来设置 NODE_ENVproduction,并配置其他生产环境特定的参数。

  • HTTPS: 给你的网站配置 SSL 证书,启用 HTTPS。 可以在 IIS 管理器中进行配置。

  • URL 重写: 通过在web.config设置规则, 实现比如伪静态等需求。

  • 使用 PM2 (推荐): 如果你可以在服务器上安装 Node.js 环境,并且希望更灵活地管理 Nuxt.js 进程(例如自动重启、负载均衡),可以考虑使用 PM2。这种情况下可以绕过 IISNode。配置会更简单, 直接 pm2 start npm -- run start 来启动服务。然后在 IIS 中设置反向代理到 PM2 管理的端口。

    • 安装 PM2

         npm install pm2 -g
      

      启动Nuxt

      pm2 start npm --name "your-app-name" -- run start
      
      
    • IIS 反向代理设置,只需要在web.config中配置如下

       <configuration>
           <system.webServer>
               <rewrite>
                   <rules>
                       <rule name="Reverse Proxy to Nuxt" stopProcessing="true">
                           <match url="(.*)" />
                           <action type="Rewrite" url="http://localhost:3001/{R:1}" />
                       </rule>
                   </rules>
               </rewrite>
           </system.webServer>
       </configuration>
      

      这里假定Nuxt 运行在3001端口,通过上述设置,实现了从IIS到PM2的反向代理。

  • 错误日志 IISNode的错误日志可以提供更多的错误信息,检查 iisnode.yml或者在 web.config 指定的位置查看日志,帮助你诊断问题。

希望这个详细的指南可以帮你顺利地将 Nuxt.js 部署到IIS!