Skip to content

Commit

Permalink
feat(kit,nuxt,schema,vite,webpack): nitropack v3 nightly (nuxt#27702)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe authored Jun 26, 2024
1 parent 5f819ab commit 8f95cac
Show file tree
Hide file tree
Showing 48 changed files with 950 additions and 199 deletions.
2 changes: 1 addition & 1 deletion docs/2.guide/3.going-further/2.hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ declare module '#app' {
}
}

declare module 'nitropack' {
declare module 'nitro/types' {
interface NitroRuntimeHooks {
'your-nitro-hook': () => void;
}
Expand Down
2 changes: 1 addition & 1 deletion docs/2.guide/3.going-further/3.modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ export default defineNuxtModule({
interface MyModuleNitroRules {
myModule?: { foo: 'bar' }
}
declare module 'nitropack' {
declare module 'nitro/types' {
interface NitroRouteRules extends MyModuleNitroRules {}
interface NitroRouteConfig extends MyModuleNitroRules {}
}
Expand Down
14 changes: 11 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
"typecheck:docs": "DOCS_TYPECHECK=true pnpm nuxi prepare && nuxt-content-twoslash verify --content-dir docs"
},
"resolutions": {
"nitro": "npm:[email protected]",
"typescript": "5.5.2",
"h3": "npm:[email protected]",
"@nuxt/kit": "workspace:*",
"@nuxt/schema": "workspace:*",
"@nuxt/ui-templates": "workspace:*",
Expand Down Expand Up @@ -69,11 +72,11 @@
"eslint-typegen": "0.2.4",
"execa": "9.3.0",
"globby": "14.0.1",
"h3": "1.12.0",
"h3": "npm:[email protected]",
"happy-dom": "14.12.3",
"jiti": "1.21.6",
"markdownlint-cli": "0.41.0",
"nitropack": "2.9.6",
"nitro": "npm:[email protected]",
"nuxi": "3.12.0",
"nuxt": "workspace:*",
"nuxt-content-twoslash": "0.0.10",
Expand All @@ -95,5 +98,10 @@
"engines": {
"node": "^16.10.0 || >=18.0.0"
},
"version": ""
"version": "",
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
}
}
}
1 change: 1 addition & 0 deletions packages/kit/build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default defineBuildConfig({
externals: [
'@nuxt/schema',
'nitropack',
'nitro',
'webpack',
'vite',
'h3',
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"devDependencies": {
"@types/hash-sum": "1.0.2",
"@types/semver": "7.5.8",
"nitropack": "2.9.6",
"nitro": "npm:[email protected]",
"unbuild": "latest",
"vite": "5.3.1",
"vitest": "1.6.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/kit/src/nitro.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Nitro, NitroDevEventHandler, NitroEventHandler } from 'nitropack'
import type { Nitro, NitroDevEventHandler, NitroEventHandler } from 'nitro/types'
import type { Import } from 'unimport'
import { normalize } from 'pathe'
import { useNuxt } from './context'
Expand All @@ -12,7 +12,7 @@ function normalizeHandlerMethod (handler: NitroEventHandler) {
// retrieve method from handler file name
const [, method = undefined] = handler.handler.match(/\.(get|head|patch|post|put|delete|connect|options|trace)(\.\w+)*$/) || []
return {
method,
method: method as 'get' | 'head' | 'patch' | 'post' | 'put' | 'delete' | 'connect' | 'options' | 'trace' | undefined,
...handler,
handler: normalize(handler.handler),
}
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/pages.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { NuxtHooks, NuxtMiddleware } from '@nuxt/schema'
import type { NitroRouteConfig } from 'nitropack'
import type { NitroRouteConfig } from 'nitro/types'
import { defu } from 'defu'
import { useNuxt } from './context'
import { logger } from './logger'
Expand Down
4 changes: 2 additions & 2 deletions packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@
"escape-string-regexp": "^5.0.0",
"estree-walker": "^3.0.3",
"globby": "^14.0.1",
"h3": "^1.12.0",
"h3": "npm:[email protected]",
"hookable": "^5.5.3",
"ignore": "^5.3.1",
"jiti": "^1.21.6",
"klona": "^2.0.6",
"knitwork": "^1.1.0",
"magic-string": "^0.30.10",
"mlly": "^1.7.1",
"nitropack": "^2.9.6",
"nitro": "npm:[email protected]",
"nuxi": "^3.12.0",
"nypm": "^0.3.8",
"ofetch": "^1.3.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt/src/app/composables/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FetchError, FetchOptions } from 'ofetch'
import type { NitroFetchRequest, TypedInternalResponse, AvailableRouterMethod as _AvailableRouterMethod } from 'nitropack'
import type { NitroFetchRequest, TypedInternalResponse, AvailableRouterMethod as _AvailableRouterMethod } from 'nitro/types'
import type { MaybeRef, Ref } from 'vue'
import { computed, reactive, toValue } from 'vue'
import { hash } from 'ohash'
Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt/src/app/composables/route-announcer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Ref } from 'vue'
import { getCurrentScope, onScopeDispose, ref } from 'vue'
import { injectHead } from '@unhead/vue'
import { useNuxtApp } from '#app'
import { useNuxtApp } from '../nuxt'

export type Politeness = 'assertive' | 'polite' | 'off'

Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt/src/app/nuxt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getContext } from 'unctx'
import type { SSRContext, createRenderer } from 'vue-bundle-renderer/runtime'
import type { EventHandlerRequest, H3Event } from 'h3'
import type { AppConfig, AppConfigInput, RuntimeConfig } from 'nuxt/schema'
import type { RenderResponse } from 'nitropack'
import type { RenderResponse } from 'nitro/types'
import type { LogObject } from 'consola'
import type { MergeHead, VueHeadClient } from '@unhead/vue'

Expand Down
31 changes: 20 additions & 11 deletions packages/nuxt/src/core/nitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { cpus } from 'node:os'
import { join, relative, resolve } from 'pathe'
import { createRouter as createRadixRouter, exportMatcher, toRouteMatcher } from 'radix3'
import { joinURL, withTrailingSlash } from 'ufo'
import { build, copyPublicAssets, createDevServer, createNitro, prepare, prerender, scanHandlers, writeTypes } from 'nitropack'
import type { Nitro, NitroConfig, NitroOptions } from 'nitropack'
import { build, copyPublicAssets, createDevServer, createNitro, prepare, prerender, writeTypes } from 'nitro'
import type { Nitro, NitroConfig, NitroOptions } from 'nitro/types'
import { findPath, logger, resolveAlias, resolveIgnorePatterns, resolveNuxtModule, resolvePath } from '@nuxt/kit'
import escapeRE from 'escape-string-regexp'
import { defu } from 'defu'
Expand Down Expand Up @@ -95,22 +95,18 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
: false,
scanDirs: nuxt.options._layers.map(layer => (layer.config.serverDir || layer.config.srcDir) && resolve(layer.cwd, layer.config.serverDir || resolve(layer.config.srcDir, 'server'))).filter(Boolean),
renderer: resolve(distDir, 'core/runtime/nitro/renderer'),
errorHandler: resolve(distDir, 'core/runtime/nitro/error'),
nodeModulesDirs: nuxt.options.modulesDir,
handlers: nuxt.options.serverHandlers,
devHandlers: [],
baseURL: nuxt.options.app.baseURL,
virtual: {
'#internal/nuxt.config.mjs': () => nuxt.vfs['#build/nuxt.config'],
'#internal/nuxt/app-config': () => nuxt.vfs['#build/app.config'].replace(/\/\*\* client \*\*\/[\s\S]*\/\*\* client-end \*\*\//, ''),
'#spa-template': async () => `export const template = ${JSON.stringify(await spaLoadingTemplate(nuxt))}`,
},
routeRules: {
'/__nuxt_error': { cache: false },
},
appConfig: nuxt.options.appConfig,
appConfigFiles: nuxt.options._layers.map(
layer => resolve(layer.config.srcDir, 'app.config'),
),
typescript: {
strict: true,
generateTsConfig: true,
Expand Down Expand Up @@ -213,6 +209,19 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
logLevel: logLevelMapReverse[nuxt.options.logLevel],
} satisfies NitroConfig)

if (nuxt.options.experimental.serverAppConfig && nitroConfig.imports) {
nitroConfig.imports.imports ||= []
nitroConfig.imports.imports.push({
name: 'useAppConfig',
from: resolve(distDir, 'core/runtime/nitro/app-config'),
})
}

// add error handler
if (!nitroConfig.errorHandler && (nuxt.options.dev || !nuxt.options.experimental.noVueServer)) {
nitroConfig.errorHandler = resolve(distDir, 'core/runtime/nitro/error')
}

// Resolve user-provided paths
nitroConfig.srcDir = resolve(nuxt.options.rootDir, nuxt.options.srcDir, nitroConfig.srcDir!)
nitroConfig.ignore = [...(nitroConfig.ignore || []), ...resolveIgnorePatterns(nitroConfig.srcDir), `!${join(nuxt.options.buildDir, 'dist/client', nuxt.options.app.buildAssetsDir, '**/*')}`]
Expand Down Expand Up @@ -383,7 +392,6 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {

// Init nitro
const nitro = await createNitro(nitroConfig, {
// @ts-expect-error this will be valid in a future version of Nitro
compatibilityDate: nuxt.options.compatibilityDate,
})

Expand Down Expand Up @@ -463,21 +471,22 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {

if (!nuxt.options.dev && nuxt.options.experimental.noVueServer) {
nitro.hooks.hook('rollup:before', (nitro) => {
if (nitro.options.preset === 'nitro-prerender') { return }
if (nitro.options.preset === 'nitro-prerender') {
nitro.options.errorHandler = resolve(distDir, 'core/runtime/nitro/error')
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
Expand Down
1 change: 1 addition & 0 deletions packages/nuxt/src/core/nuxt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export function createNuxt (options: NuxtOptions): Nuxt {

const nightlies = {
'nitropack': 'nitropack-nightly',
'nitro': 'nitro-nightly',
'h3': 'h3-nightly',
'nuxt': 'nuxt-nightly',
'@nuxt/schema': '@nuxt/schema-nightly',
Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt/src/core/plugins/import-protection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const nuxtImportProtections = (nuxt: { options: NuxtOptions }, options: {
])
}

for (const i of [/(^|node_modules\/)@nuxt\/(kit|test-utils)/, /(^|node_modules\/)nuxi/, /(^|node_modules\/)nuxt\/(config|kit|schema)/, 'nitropack']) {
for (const i of [/(^|node_modules\/)@nuxt\/(kit|test-utils)/, /(^|node_modules\/)nuxi/, /(^|node_modules\/)nitro(?:pack)?(?:-nightly)?(?:$|\/)(?!(?:dist\/)?runtime|types)/, /(^|node_modules\/)nuxt\/(config|kit|schema)/]) {
patterns.push([i, 'This module cannot be imported' + (options.isNitro ? ' in server runtime.' : ' in the Vue part of your app.')])
}

Expand Down
38 changes: 38 additions & 0 deletions packages/nuxt/src/core/runtime/nitro/app-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { H3Event } from 'h3'
import { klona } from 'klona'

// @ts-expect-error virtual file
import _inlineAppConfig from '#internal/nuxt/app-config'

// App config
const _sharedAppConfig = _deepFreeze(klona(_inlineAppConfig))
export function useAppConfig (event?: H3Event) {
// Backwards compatibility with ambient context
if (!event) {
return _sharedAppConfig
}
if (!event.context.nuxt) {
event.context.nuxt = {}
}
// Reuse cached app config from event context
if (event.context.nuxt.appConfig) {
return event.context.nuxt.appConfig
}
// Prepare app config for event context
const appConfig = klona(_inlineAppConfig)
event.context.nuxt.appConfig = appConfig
return appConfig
}

// --- Utils ---

function _deepFreeze (object: Record<string, any>) {
const propNames = Object.getOwnPropertyNames(object)
for (const name of propNames) {
const value = object[name]
if (value && typeof value === 'object') {
_deepFreeze(value)
}
}
return Object.freeze(object)
}
2 changes: 1 addition & 1 deletion packages/nuxt/src/core/runtime/nitro/dev-server-logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { withTrailingSlash } from 'ufo'
import { getContext } from 'unctx'

import { isVNode } from 'vue'
import type { NitroApp } from '#internal/nitro/app'
import type { NitroApp } from 'nitro/types'

// @ts-expect-error virtual file
import { rootDir } from '#internal/dev-server-logs-options'
Expand Down
72 changes: 66 additions & 6 deletions packages/nuxt/src/core/runtime/nitro/error.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { joinURL, withQuery } from 'ufo'
import type { NitroErrorHandler } from 'nitropack'
import type { H3Error } from 'h3'
import { getRequestHeaders, send, setResponseHeader, setResponseStatus } from 'h3'
import { useRuntimeConfig } from '#internal/nitro'
import { useNitroApp } from '#internal/nitro/app'
import { isJsonRequest, normalizeError } from '#internal/nitro/utils'
import type { NitroErrorHandler } from 'nitro/types'
import type { H3Error, H3Event } from 'h3'
import { getRequestHeader, getRequestHeaders, send, setResponseHeader, setResponseStatus } from 'h3'
import { useNitroApp, useRuntimeConfig } from 'nitro/runtime'
import type { NuxtPayload } from '#app'

export default <NitroErrorHandler> async function errorhandler (error: H3Error, event) {
Expand Down Expand Up @@ -86,3 +84,65 @@ export default <NitroErrorHandler> async function errorhandler (error: H3Error,

return send(event, html)
}

/**
* Nitro internal functions extracted from https://github.com/unjs/nitro/blob/main/src/runtime/internal/utils.ts
*/

function isJsonRequest (event: H3Event) {
// If the client specifically requests HTML, then avoid classifying as JSON.
if (hasReqHeader(event, 'accept', 'text/html')) {
return false
}
return (
hasReqHeader(event, 'accept', 'application/json') ||
hasReqHeader(event, 'user-agent', 'curl/') ||
hasReqHeader(event, 'user-agent', 'httpie/') ||
hasReqHeader(event, 'sec-fetch-mode', 'cors') ||
event.path.startsWith('/api/') ||
event.path.endsWith('.json')
)
}

function hasReqHeader (event: H3Event, name: string, includes: string) {
const value = getRequestHeader(event, name)
return (
value && typeof value === 'string' && value.toLowerCase().includes(includes)
)
}

function normalizeError (error: any) {
// temp fix for https://github.com/unjs/nitro/issues/759
// TODO: investigate vercel-edge not using unenv pollyfill
const cwd = typeof process.cwd === 'function' ? process.cwd() : '/'
const stack = ((error.stack as string) || '')
.split('\n')
.splice(1)
.filter(line => line.includes('at '))
.map((line) => {
const text = line
.replace(cwd + '/', './')
.replace('webpack:/', '')
.replace('file://', '')
.trim()
return {
text,
internal:
(line.includes('node_modules') && !line.includes('.cache')) ||
line.includes('internal') ||
line.includes('new Promise'),
}
})

const statusCode = error.statusCode || 500
const statusMessage =
error.statusMessage ?? (statusCode === 404 ? 'Not Found' : '')
const message = error.message || error.toString()

return {
stack,
statusCode,
statusMessage,
message,
}
}
2 changes: 1 addition & 1 deletion packages/nuxt/src/core/runtime/nitro/paths.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { joinRelativeURL } from 'ufo'
import { useRuntimeConfig } from '#internal/nitro'
import { useRuntimeConfig } from 'nitro/runtime'

export function baseURL (): string {
// TODO: support passing event to `useRuntimeConfig`
Expand Down
5 changes: 2 additions & 3 deletions packages/nuxt/src/core/runtime/nitro/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
getRequestDependencies,
renderResourceHeaders,
} from 'vue-bundle-renderer/runtime'
import type { RenderResponse } from 'nitropack'
import type { RenderResponse } from 'nitro/types'
import type { Manifest } from 'vite'
import type { H3Event } from 'h3'
import { appendResponseHeader, createError, getQuery, getResponseStatus, getResponseStatusText, readBody, writeEarlyHints } from 'h3'
Expand All @@ -21,8 +21,7 @@ import type { HeadEntryOptions } from '@unhead/schema'
import type { Link, Script, Style } from '@unhead/vue'
import { createServerHead } from '@unhead/vue'

import { defineRenderHandler, getRouteRules, useRuntimeConfig, useStorage } from '#internal/nitro'
import { useNitroApp } from '#internal/nitro/app'
import { defineRenderHandler, getRouteRules, useNitroApp, useRuntimeConfig, useStorage } from 'nitro/runtime'

// @ts-expect-error virtual file
import unheadPlugins from '#internal/unhead-plugins.mjs'
Expand Down
Loading

0 comments on commit 8f95cac

Please sign in to comment.