Repository: nuxt/nuxt
File: packages/nuxt/src/core/nitro.ts (TypeScript)

Code before:
    if (nuxt.options.dev) {
      await build(nitro)
    } else {
      await prepare(nitro)
      await copyPublicAssets(nitro)
      await nuxt.callHook('nitro:build:public-assets', nitro)

      // Add pages prerendered but not covered by route rules
      const prerenderedRoutes = new Set<string>()
      const routeRulesMatcher = toRouteMatcher(
        createRadixRouter({ routes: nitro.options.routeRules })
      )
      const payloadSuffix = nuxt.options.experimental.renderJsonPayloads ? '/_payload.json' : '/_payload.js'
      nitro.hooks.hook('prerender:route', (route) => {
        if (!route.error && route.route.endsWith(payloadSuffix)) {
          const url = route.route.slice(0, -payloadSuffix.length) || '/'
          const rules = defu({}, ...routeRulesMatcher.matchAll(url).reverse()) as Record<string, any>
          if (!rules.prerender) {
            prerenderedRoutes.add(url)
          }
        }
      })
      await prerender(nitro)

      for (const file of ['latest.json', `meta.${buildId}.json`]) {
        const manifestFile = join(nitro.options.output.publicDir, '_builds', file)
        const manifest = await fsp.readFile(manifestFile, 'utf-8')
        await fsp.writeFile(manifestFile, manifest.replace(/['"]__NUXT_PRERENDERED_ROUTES__['"]/, JSON.stringify([...prerenderedRoutes])))
      }

      logger.restoreAll()
      await build(nitro)
      logger.wrapAll()

      if (nitro.options.static) {
        const distDir = resolve(nuxt.options.rootDir, 'dist')
        if (!existsSync(distDir)) {
          await fsp.symlink(nitro.options.output.publicDir, distDir, 'junction').catch(() => {})
        }
      }
    }
  })

  // nuxt dev
  if (nuxt.options.dev) {
    nuxt.hook('webpack:compile', ({ compiler }) => { compiler.outputFileSystem = { ...fsExtra, join } as any })
    nuxt.hook('webpack:compiled', () => { nuxt.server.reload() })
    nuxt.hook('vite:compiled', () => { nuxt.server.reload() })

    nuxt.hook('server:devHandler', (h) => { devMiddlewareHandler.set(h) })
    nuxt.server = createDevServer(nitro)

Review comment (suggestion):
Does it makes sense to prefix it with `_nuxt` or `_nuxt_builds` ? 🙏🏼 This way introducing similar feature in nitro and switching would be much easier without worrying to break nuxt (however i think for nitro we should also support custom name so it is nuxt compatible)

Code after:
  const devMiddlewareHandler = dynamicEventHandler()
  nitro.options.devHandlers.unshift({ handler: devMiddlewareHandler })
  nitro.options.devHandlers.push(...nuxt.options.devServerHandlers)
  nitro.options.handlers.unshift({
    route: '/__nuxt_error',
    lazy: true,
    handler: resolve(distDir, 'core/runtime/nitro/renderer')
  })

  if (!nuxt.options.dev && nuxt.options.experimental.noVueServer) {
    nitro.hooks.hook('rollup:before', (nitro) => {
      if (nitro.options.preset === 'nitro-prerender') { return }
      const nuxtErrorHandler = nitro.options.handlers.findIndex(h => h.route === '/__nuxt_error')
      if (nuxtErrorHandler >= 0) {
        nitro.options.handlers.splice(nuxtErrorHandler, 1)
      }

      nitro.options.renderer = undefined
      nitro.options.errorHandler = '#internal/nitro/error'
    })
  }

  // Add typed route responses
  nuxt.hook('prepare:types', async (opts) => {
    if (!nuxt.options.dev) {
      await scanHandlers(nitro)
      await writeTypes(nitro)
    }
    // Exclude nitro output dir from typescript
    opts.tsConfig.exclude = opts.tsConfig.exclude || []
    opts.tsConfig.exclude.push(relative(nuxt.options.buildDir, resolve(nuxt.options.rootDir, nitro.options.output.dir)))
    opts.references.push({ path: resolve(nuxt.options.buildDir, 'types/nitro.d.ts') })
  })

  if (nitro.options.static) {
    nitro.hooks.hook('prerender:routes', (routes) => {
      for (const route of [nuxt.options.ssr ? '/' : '/index.html', '/200.html', '/404.html']) {
        routes.add(route)
      }
    })
  }

  // nuxt build/dev
  nuxt.hook('build:done', async () => {
    await nuxt.callHook('nitro:build:before', nitro)
    if (nuxt.options.dev) {
      await build(nitro)
    } else {
      await prepare(nitro)
      await copyPublicAssets(nitro)
      await nuxt.callHook('nitro:build:public-assets', nitro)