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

如何在Nuxt生产环境中启用listen hook?

Nuxt生产环境启用listen hook并关联WebSocketServer的解决方案

你的问题出在Nuxt配置中的listen钩子仅作用于开发服务器,执行npm run build && npm run preview时启动的是Nitro生产服务器,这个钩子不会被触发。要在生产环境生效,需要改用Nitro提供的server:listen钩子,以下是两种可行方案:

方案一:在nuxt.config.ts中配置Nitro钩子

直接将原逻辑迁移到nitro.hooks下的server:listen钩子中:

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  nitro: {
    hooks: {
      'server:listen'(server) {
        console.log(server)

        const yogaApp = createYoga({
          graphqlEndpoint: '/api/graphql',
          schema: createSchema({
            typeDefs: /* GraphQL */ `
              type Query {
                  hello: String
              }

              type Subscription {
                  countdown(from: Int!): Int!
              }
            `,
            resolvers: {
              Query: {
                  hello: () => 'world'
              },
              Subscription: {
                  countdown: {
                      subscribe: async function* (_, { from }) {
                          for (let i = from; i >= 0; i--) {
                              await new Promise((resolve) => setTimeout(resolve, 1000))
                              yield { countdown: i }
                          }
                      }
                  }
              }
            }
          }),
          graphiql:{
              subscriptionsProtocol: "WS"
          }
        })

        console.log(yogaApp.graphqlEndpoint)

        const wsServer = new WebSocketServer({
          server,
          path: yogaApp.graphqlEndpoint
        })

        useServer(
          {
              execute: (args: any) => args.rootValue.execute(args),
              subscribe: (args: any) => args.rootValue.subscribe(args),
              onSubscribe: async (ctx, msg) => {
                  const { schema, execute, subscribe, contextFactory, parse, validate } =
                      yogaApp.getEnveloped({
                          ...ctx,
                          req: ctx.extra.request,
                          socket: ctx.extra.socket,
                          params: msg.payload
                      })

                  const args = {
                      schema,
                      operationName: msg.payload.operationName,
                      document: parse(msg.payload.query),
                      variableValues: msg.payload.variables,
                      contextValue: await contextFactory(),
                      rootValue: {
                          execute,
                          subscribe
                      }
                  }

                  const errors = validate(args.schema, args.document)
                  if (errors.length) return errors
                  return args
              }
          },
          wsServer
        )
      }
    }
  }
})

方案二:创建服务器插件(推荐,更模块化)

在项目根目录下创建server/plugins/ws.ts文件,通过Nitro插件注册钩子:

import { createYoga, createSchema } from 'graphql-yoga'
import { WebSocketServer } from 'ws'
import { useServer } from 'graphql-ws/lib/use/ws'

export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('server:listen', (server) => {
    // 原listen钩子中的逻辑完全迁移到这里
    const yogaApp = createYoga({
      graphqlEndpoint: '/api/graphql',
      schema: createSchema({
        typeDefs: /* GraphQL */ `
          type Query {
              hello: String
          }

          type Subscription {
              countdown(from: Int!): Int!
          }
        `,
        resolvers: {
          Query: {
              hello: () => 'world'
          },
          Subscription: {
              countdown: {
                  subscribe: async function* (_, { from }) {
                      for (let i = from; i >= 0; i--) {
                          await new Promise((resolve) => setTimeout(resolve, 1000))
                          yield { countdown: i }
                      }
                  }
              }
          }
        }
      }),
      graphiql:{
          subscriptionsProtocol: "WS"
      }
    })

    console.log(yogaApp.graphqlEndpoint)

    const wsServer = new WebSocketServer({
      server,
      path: yogaApp.graphqlEndpoint
    })

    useServer(
      {
          execute: (args: any) => args.rootValue.execute(args),
          subscribe: (args: any) => args.rootValue.subscribe(args),
          onSubscribe: async (ctx, msg) => {
              const { schema, execute, subscribe, contextFactory, parse, validate } =
                  yogaApp.getEnveloped({
                      ...ctx,
                      req: ctx.extra.request,
                      socket: ctx.extra.socket,
                      params: msg.payload
                  })

              const args = {
                  schema,
                  operationName: msg.payload.operationName,
                  document: parse(msg.payload.query),
                  variableValues: msg.payload.variables,
                  contextValue: await contextFactory(),
                  rootValue: {
                      execute,
                      subscribe
                  }
              }

              const errors = validate(args.schema, args.document)
              if (errors.length) return errors
              return args
          }
      },
      wsServer
    )
  })
})

关键说明

  • Nitro是Nuxt3的后端运行时引擎,server:listen钩子会在开发、生产预览、生产部署三种场景下触发,完美替代原Nuxt开发服务器的listen钩子。
  • 确保已安装所有依赖包:graphql-yoga、ws、graphql-ws,若未安装可执行命令:
    npm install graphql-yoga ws graphql-ws
    

内容的提问来源于stack exchange,提问作者Adri HM

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 09:30:51