Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

fix(nuxt): pass and format vite-node build errors #6683

Merged
merged 13 commits into from
Sep 3, 2022
77 changes: 66 additions & 11 deletions packages/vite/src/runtime/vite-node.mjs
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import { performance } from 'node:perf_hooks'
import { createError } from 'h3'
import { ViteNodeRunner } from 'vite-node/client'
import { $fetch } from 'ohmyfetch'
import consola from 'consola'
import { getViteNodeOptions } from './vite-node-shared.mjs'

const viteNodeOptions = getViteNodeOptions()

const runner = new ViteNodeRunner({
root: viteNodeOptions.root, // Equals to Nuxt `srcDir`
base: viteNodeOptions.base,
async fetchModule (id) {
return await $fetch('/module/' + encodeURI(id), {
baseURL: viteNodeOptions.baseURL
})
}
})

const runner = createRunner()
let render

export default async (ssrContext) => {
Expand All @@ -40,3 +31,67 @@ export default async (ssrContext) => {
const result = await render(ssrContext)
return result
}

function createRunner () {
return new ViteNodeRunner({
root: viteNodeOptions.root, // Equals to Nuxt `srcDir`
base: viteNodeOptions.base,
async fetchModule (id) {
return await $fetch('/module/' + encodeURI(id), {
baseURL: viteNodeOptions.baseURL
}).catch((err) => {
const errorData = err?.data?.data
if (!errorData) {
throw err
}
try {
const { message, stack } = formatViteError(errorData)
throw createError({
statusMessage: 'Vite Error',
message,
stack
})
} catch (err) {
// This should not happen unless there is an internal error with formatViteError!
consola.error('Error while formatting vite error:', errorData)
throw createError({
statusMessage: 'Vite Error',
message: errorData.message || 'Vite Error',
stack: 'Vite Error\nat [check console]'
})
}
})
}
})
}

function formatViteError (errorData) {
const errorCode = errorData.name || errorData.reasonCode || errorData.code
const frame = errorData.frame || errorData.source || errorData.pluginCode

const getLocId = (locObj = {}) => locObj.file || locObj.id || locObj.url || ''
const getLocPos = (locObj = {}) => locObj.line ? `${locObj.line}:${locObj.column || 0}` : ''
const locId = getLocId(errorData.loc) || getLocId(errorData.location) || getLocId(errorData.input) || getLocId(errorData)
const locPos = getLocPos(errorData.loc) || getLocPos(errorData.location) || getLocPos(errorData.input) || getLocPos(errorData)
const loc = locId.replace(process.cwd(), '.') + (locPos ? `:${locPos}` : '')

const message = [
'[vite-node]',
errorData.plugin && `[plugin:${errorData.plugin}]`,
errorCode && `[${errorCode}]`,
loc,
errorData.reason && `: ${errorData.reason}`,
frame && `<br><pre>${frame.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</pre><br>`
].filter(Boolean).join(' ')

const stack = [
message,
'at ' + loc,
errorData.stack
].filter(Boolean).join('\n')

return {
message,
stack
}
}
10 changes: 6 additions & 4 deletions packages/vite/src/vite-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createApp, createError, defineEventHandler, defineLazyEventHandler } fr
import { ViteNodeServer } from 'vite-node/server'
import fse from 'fs-extra'
import { resolve } from 'pathe'
import { addServerMiddleware } from '@nuxt/kit'
import { addDevServerHandler } from '@nuxt/kit'
import type { ModuleNode, Plugin as VitePlugin } from 'vite'
import { normalizeViteManifest } from 'vue-bundle-renderer'
import { resolve as resolveModule } from 'mlly'
Expand Down Expand Up @@ -41,7 +41,7 @@ export function viteNodePlugin (ctx: ViteBuildContext): VitePlugin {
}

export function registerViteNodeMiddleware (ctx: ViteBuildContext) {
addServerMiddleware({
addDevServerHandler({
route: '/__nuxt_vite_node__/',
handler: createViteNodeMiddleware(ctx)
})
Expand Down Expand Up @@ -112,12 +112,14 @@ function createViteNodeMiddleware (ctx: ViteBuildContext, invalidates: Set<strin
if (moduleId === '/') {
throw createError({ statusCode: 400 })
}
const module = await node.fetchModule(moduleId) as any
const module = await node.fetchModule(moduleId).catch((err) => {
throw createError({ data: err })
})
return module
}
}))

return app.nodeHandler
return app
}

export async function initViteNodeServer (ctx: ViteBuildContext) {
Expand Down
3 changes: 1 addition & 2 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { defineNuxtConfig } from 'nuxt'

export default defineNuxtConfig({
})
export default defineNuxtConfig({})