Skip to content

Commit

Permalink
Merge branch 'main' into replace-vueuse-head-with-unhead-vue
Browse files Browse the repository at this point in the history
  • Loading branch information
wattanx committed Jun 21, 2023
2 parents 12bad6b + 6e82e2d commit 1bd4413
Show file tree
Hide file tree
Showing 25 changed files with 2,173 additions and 2,452 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@
"engines": {
"node": "^14.16.0 || ^16.11.0 || >=17.0.0"
},
"packageManager": "[email protected].2"
"packageManager": "[email protected].3"
}
2 changes: 1 addition & 1 deletion packages/bridge-schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"vite": "~4.3.9"
},
"dependencies": {
"c12": "^1.4.1",
"c12": "^1.4.2",
"create-require": "^1.1.1",
"defu": "^6.1.2",
"jiti": "^1.18.2",
Expand Down
11 changes: 6 additions & 5 deletions packages/bridge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@nuxt/kit": "3.5.3",
"@nuxt/postcss8": "^1.1.3",
"@nuxt/schema": "3.5.3",
"@nuxt/ui-templates": "^1.1.1",
"@nuxt/ui-templates": "^1.2.0",
"@unhead/ssr": "^1.1.27",
"@unhead/vue": "^1.1.27",
"@vitejs/plugin-legacy": "^4.0.4",
Expand All @@ -43,12 +43,12 @@
"externality": "^1.0.2",
"fs-extra": "^10.1.0",
"get-port-please": "^3.0.1",
"globby": "^13.1.4",
"globby": "^13.2.0",
"h3": "^1.6.6",
"hash-sum": "^2.0.0",
"knitwork": "^1.0.0",
"magic-string": "^0.30.0",
"mlly": "^1.3.0",
"mlly": "^1.4.0",
"nitropack": "^2.4.1",
"node-fetch": "^3.3.1",
"nuxi": "3.5.3",
Expand All @@ -64,13 +64,14 @@
"scule": "^1.0.0",
"semver": "^7.5.2",
"std-env": "^3.3.3",
"terser": "^5.18.0",
"terser": "^5.18.1",
"ufo": "^1.1.2",
"unctx": "^2.3.1",
"unimport": "^3.0.8",
"unplugin": "^1.3.1",
"untyped": "^1.3.2",
"vite": "~4.3.9",
"vite-node": "^0.32.2",
"vue-bundle-renderer": "^1.0.3"
},
"devDependencies": {
Expand All @@ -88,5 +89,5 @@
"engines": {
"node": "^14.16.0 || ^16.11.0 || >=17.0.0"
},
"packageManager": "[email protected].2"
"packageManager": "[email protected].3"
}
25 changes: 18 additions & 7 deletions packages/bridge/src/runtime/composables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { sendRedirect } from 'h3'
import { defu } from 'defu'
import { useRouter as useVueRouter, useRoute as useVueRoute } from 'vue-router/composables'
import { hasProtocol, joinURL, parseURL } from 'ufo'
import { useNuxtApp } from './app'
import { useNuxtApp, callWithNuxt } from './app'
import { createError, showError } from './error'
import type { NuxtError } from './error'

export { useLazyAsyncData, refreshNuxtData } from './asyncData'
export { useLazyFetch } from './fetch'
Expand Down Expand Up @@ -163,7 +165,10 @@ export interface AddRouteMiddlewareOptions {
/** internal */
function convertToLegacyMiddleware (middleware) {
return async (ctx: any) => {
const result = await middleware(ctx.route, ctx.from)
// because the middleware is executed before the plugin
ctx.$_nuxtApp._processingMiddleware = true
const result = await callWithNuxt(ctx.$_nuxtApp, middleware, [ctx.route, ctx.from])
delete ctx.$_nuxtApp._processingMiddleware
if (result instanceof Error) {
return ctx.error(result)
}
Expand Down Expand Up @@ -229,14 +234,20 @@ export const navigateTo = (to: RawLocation | undefined | null, options?: Navigat
}

/** This will abort navigation within a Nuxt route middleware handler. */
export const abortNavigation = (err?: Error | string) => {
export const abortNavigation = (err?: string | Partial<NuxtError>) => {
if (process.dev && !isProcessingMiddleware()) {
throw new Error('abortNavigation() is only usable inside a route middleware handler.')
}
if (err) {
throw err instanceof Error ? err : new Error(err)
if (!err) { return false }

err = createError(err)

if (err.fatal) {
const nuxtApp = useNuxtApp()
callWithNuxt(nuxtApp, showError, [err as NuxtError])
}
return false

throw err
}

type RouteMiddlewareReturn = void | Error | string | Location | boolean
Expand All @@ -245,7 +256,7 @@ export interface RouteMiddleware {
(to: Route, from: Route): RouteMiddlewareReturn | Promise<RouteMiddlewareReturn>
}

export const defineNuxtRouteMiddleware = (middleware: RouteMiddleware) => middleware
export const defineNuxtRouteMiddleware = (middleware: RouteMiddleware) => convertToLegacyMiddleware(middleware)

interface AddRouteMiddleware {
(name: string, middleware: RouteMiddleware, options?: AddRouteMiddlewareOptions): void
Expand Down
4 changes: 3 additions & 1 deletion packages/bridge/src/vite/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { devStyleSSRPlugin } from './plugins/dev-ssr-css'
import { jsxPlugin } from './plugins/jsx'
import { ViteBuildContext, ViteOptions } from './types'
import { prepareManifests } from './manifest'
import { viteNodePlugin } from './vite-node'

export async function buildClient (ctx: ViteBuildContext) {
const alias = {
Expand Down Expand Up @@ -62,7 +63,8 @@ export async function buildClient (ctx: ViteBuildContext) {
devStyleSSRPlugin({
srcDir: ctx.nuxt.options.srcDir,
buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir)
})
}),
viteNodePlugin(ctx)
],
appType: 'custom',
server: {
Expand Down
44 changes: 42 additions & 2 deletions packages/bridge/src/vite/dev-bundler.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { pathToFileURL } from 'url'
import { existsSync } from 'fs'
import { builtinModules } from 'module'
import { isAbsolute, resolve } from 'pathe'
import { isAbsolute, resolve, normalize } from 'pathe'
import { ExternalsOptions, isExternal as _isExternal, ExternalsDefaults } from 'externality'
import { genDynamicImport, genObjectFromRawEntries } from 'knitwork'
import type { ViteDevServer } from 'vite'
import { hashId, uniq } from './utils'
import fse from 'fs-extra'
import { debounce } from 'perfect-debounce'
import { logger, isIgnored } from '@nuxt/kit'
import { hashId, isCSS, uniq } from './utils'
import { ViteBuildContext } from './types'
import { createIsExternal } from './utils/external'
import { generateDevSSRManifest } from './manifest'

export interface TransformChunk {
id: string,
Expand All @@ -23,6 +29,7 @@ export interface SSRTransformResult {

export interface TransformOptions {
viteServer: ViteDevServer
isExternal(id: string): ReturnType<typeof isExternal>
}

function isExternal (opts: TransformOptions, id: string) {
Expand Down Expand Up @@ -221,3 +228,36 @@ async function __instantiateModule__(url, urlStack) {
ids: chunks.map(i => i.id)
}
}

export async function initViteDevBundler (ctx: ViteBuildContext, onBuild: () => Promise<any>) {
const viteServer = ctx.ssrServer!
const options: TransformOptions = {
viteServer,
isExternal: createIsExternal(viteServer, ctx.nuxt.options.rootDir)
}

// Build and watch
const _doBuild = async () => {
const start = Date.now()
const { code, ids } = await bundleRequest(options, '/.nuxt/server.js')
await fse.writeFile(resolve(ctx.nuxt.options.buildDir, 'dist/server/server.mjs'), code, 'utf-8')
// Have CSS in the manifest to prevent FOUC on dev SSR
await generateDevSSRManifest(ctx, ids.filter(isCSS).map(i => i.slice(1)))
const time = (Date.now() - start)
logger.success(`Vite server built in ${time}ms`)
await onBuild()
}
const doBuild = debounce(_doBuild)

// Initial build
await _doBuild()

// Watch
viteServer.watcher.on('all', (_event, file) => {
file = normalize(file) // Fix windows paths
if (file.indexOf(ctx.nuxt.options.buildDir) === 0 || isIgnored(file)) { return }
doBuild()
})
// ctx.nuxt.hook('builder:watch', () => doBuild())
ctx.nuxt.hook('app:templatesGenerated', () => doBuild())
}
9 changes: 9 additions & 0 deletions packages/bridge/src/vite/dirs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { fileURLToPath } from 'node:url'
import { dirname, resolve } from 'pathe'

let _distDir = dirname(fileURLToPath(import.meta.url))
if (_distDir.match(/(chunks|shared)$/)) {
_distDir = dirname(_distDir)
}
export const distDir = _distDir
export const pkgDir = resolve(distDir, '..')
52 changes: 52 additions & 0 deletions packages/bridge/src/vite/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,55 @@ export async function writeClientManifest (clientManifest: any, buildDir: string
await fse.writeFile(resolve(buildDir, 'dist/server/client.manifest.json'), clientManifestJSON, 'utf-8')
await fse.writeFile(resolve(buildDir, 'dist/server/client.manifest.mjs'), `export default ${clientManifestJSON}`, 'utf-8')
}

export async function writeManifest (ctx: ViteBuildContext, css: string[] = []) {
// Write client manifest for use in vue-bundle-renderer
const clientDist = resolve(ctx.nuxt.options.buildDir, 'dist/client')
const serverDist = resolve(ctx.nuxt.options.buildDir, 'dist/server')

const devClientManifest: Manifest = {
'@vite/client': {
isEntry: true,
file: '@vite/client',
css,
module: true,
resourceType: 'script'
},
'entry.mjs': {
isEntry: true,
file: 'entry.mjs',
module: true,
resourceType: 'script'
}
}

const clientManifest = ctx.nuxt.options.dev
? devClientManifest
: await fse.readJSON(resolve(clientDist, 'manifest.json'))

const buildAssetsDir = withTrailingSlash(withoutLeadingSlash(ctx.nuxt.options.app.buildAssetsDir))
const BASE_RE = new RegExp(`^${escapeRE(buildAssetsDir)}`)

for (const key in clientManifest) {
if (clientManifest[key].file) {
clientManifest[key].file = clientManifest[key].file.replace(BASE_RE, '')
}
for (const item of ['css', 'assets']) {
if (clientManifest[key][item]) {
clientManifest[key][item] = clientManifest[key][item].map((i: string) => i.replace(BASE_RE, ''))
}
}
}

await fse.mkdirp(serverDist)

const manifest = normalizeViteManifest(clientManifest)
await ctx.nuxt.callHook('build:manifest', manifest)

await fse.writeFile(resolve(serverDist, 'client.manifest.json'), JSON.stringify(manifest, null, 2), 'utf8')
await fse.writeFile(resolve(serverDist, 'client.manifest.mjs'), 'export default ' + JSON.stringify(manifest, null, 2), 'utf8')

if (!ctx.nuxt.options.dev) {
await fse.rm(resolve(clientDist, 'manifest.json'), { force: true })
}
}
4 changes: 3 additions & 1 deletion packages/bridge/src/vite/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ export default defineNuxtModule<ViteOptions>({
name: 'nuxt-bridge:vite',
configKey: 'vite'
},
defaults: {},
defaults: {
},
setup (viteOptions, nuxt) {
nuxt.options.vite = viteOptions
nuxt.options.cli.badgeMessages.push(`⚡ Vite Mode Enabled (v${version})`)

if (viteOptions.experimentWarning !== false && !nuxt.options.test) {
Expand Down
4 changes: 4 additions & 0 deletions packages/bridge/src/vite/runtime/client.manifest.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// @ts-check
import { viteNodeFetch } from './vite-node-shared.mjs'

export default () => viteNodeFetch('/manifest')
13 changes: 13 additions & 0 deletions packages/bridge/src/vite/runtime/vite-node-shared.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// @ts-check
import { Agent as HTTPSAgent } from 'node:https'
import { $fetch } from 'ofetch'

export const viteNodeOptions = JSON.parse(process.env.NUXT_VITE_NODE_OPTIONS || '{}')

export const viteNodeFetch = $fetch.create({
baseURL: viteNodeOptions.baseURL,
// @ts-expect-error https://github.com/node-fetch/node-fetch#custom-agent
agent: viteNodeOptions.baseURL.startsWith('https://')
? new HTTPSAgent({ rejectUnauthorized: false })
: null
})
Loading

0 comments on commit 1bd4413

Please sign in to comment.