From b36a5e25e64aec26d3b847f67b8c900a46933cd9 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 16 Jan 2023 14:08:06 +0100 Subject: [PATCH 1/5] fix(vite): forward registed Vite middleware --- packages/vite/src/client.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/vite/src/client.ts b/packages/vite/src/client.ts index f2d134ec840..d2fb6f00e64 100644 --- a/packages/vite/src/client.ts +++ b/packages/vite/src/client.ts @@ -121,20 +121,17 @@ export async function buildClient (ctx: ViteBuildContext) { const viteServer = await vite.createServer(clientConfig) ctx.clientServer = viteServer await ctx.nuxt.callHook('vite:serverCreated', viteServer, { isClient: true, isServer: false }) - const transformHandler = viteServer.middlewares.stack.findIndex(m => m.handle instanceof Function && m.handle.name === 'viteTransformMiddleware') - viteServer.middlewares.stack.splice(transformHandler, 0, { - route: '', - handle: (req: IncomingMessage & { _skip_transform?: boolean }, res: ServerResponse, next: (err?: any) => void) => { - // 'Skip' the transform middleware - if (req._skip_transform) { req.url = joinURL('/__skip_vite', req.url!) } - next() - } - }) + const viteMiddleware = defineEventHandler(async (event) => { // Workaround: vite devmiddleware modifies req.url const originalURL = event.node.req.url! - // @ts-expect-error _skip_transform is a private property - event.node.req._skip_transform = !originalURL.startsWith(clientConfig.base!) + + // Forward vite middleware + const viteRoutes = viteServer.middlewares.stack.map(m => m.route).filter(r => r.length > 1) + if (!viteRoutes.some(route => originalURL.startsWith(route)) && !originalURL.startsWith(clientConfig.base!)) { + event.node.req.url = joinURL('/__url', originalURL) + } + await new Promise((resolve, reject) => { viteServer.middlewares.handle(event.node.req, event.node.res, (err: Error) => { event.node.req.url = originalURL From 4989e2b7e00732c5e8b1948f10893a1913ada1a7 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 16 Jan 2023 14:11:08 +0100 Subject: [PATCH 2/5] chore: lint --- packages/vite/src/client.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/vite/src/client.ts b/packages/vite/src/client.ts index d2fb6f00e64..755682cd578 100644 --- a/packages/vite/src/client.ts +++ b/packages/vite/src/client.ts @@ -1,4 +1,3 @@ -import type { IncomingMessage, ServerResponse } from 'node:http' import { join, relative, resolve } from 'pathe' import * as vite from 'vite' import vuePlugin from '@vitejs/plugin-vue' From 64dd8619e491dc27b524286afa381ccf21cc94d2 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 16 Jan 2023 14:32:54 +0100 Subject: [PATCH 3/5] chore: try --- packages/vite/src/client.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/client.ts b/packages/vite/src/client.ts index 755682cd578..8e22ce4c654 100644 --- a/packages/vite/src/client.ts +++ b/packages/vite/src/client.ts @@ -1,3 +1,4 @@ +import type { IncomingMessage, ServerResponse } from 'node:http' import { join, relative, resolve } from 'pathe' import * as vite from 'vite' import vuePlugin from '@vitejs/plugin-vue' @@ -120,15 +121,24 @@ export async function buildClient (ctx: ViteBuildContext) { const viteServer = await vite.createServer(clientConfig) ctx.clientServer = viteServer await ctx.nuxt.callHook('vite:serverCreated', viteServer, { isClient: true, isServer: false }) + const transformHandler = viteServer.middlewares.stack.findIndex(m => m.handle instanceof Function && m.handle.name === 'viteTransformMiddleware') + viteServer.middlewares.stack.splice(transformHandler, 0, { + route: '', + handle: (req: IncomingMessage & { _skip_transform?: boolean }, res: ServerResponse, next: (err?: any) => void) => { + // 'Skip' the transform middleware + if (req._skip_transform) { req.url = joinURL('/__skip_vite', req.url!) } + next() + } + }) const viteMiddleware = defineEventHandler(async (event) => { // Workaround: vite devmiddleware modifies req.url const originalURL = event.node.req.url! - // Forward vite middleware const viteRoutes = viteServer.middlewares.stack.map(m => m.route).filter(r => r.length > 1) if (!viteRoutes.some(route => originalURL.startsWith(route)) && !originalURL.startsWith(clientConfig.base!)) { - event.node.req.url = joinURL('/__url', originalURL) + // @ts-expect-error _skip_transform is a private property + event.node.req._skip_transform = true } await new Promise((resolve, reject) => { From cf5ca627510a7b031433e40c735fceee9dd9175c Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 16 Jan 2023 14:33:22 +0100 Subject: [PATCH 4/5] perf --- packages/vite/src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/client.ts b/packages/vite/src/client.ts index 8e22ce4c654..70d6c0dbb2e 100644 --- a/packages/vite/src/client.ts +++ b/packages/vite/src/client.ts @@ -136,7 +136,7 @@ export async function buildClient (ctx: ViteBuildContext) { const originalURL = event.node.req.url! const viteRoutes = viteServer.middlewares.stack.map(m => m.route).filter(r => r.length > 1) - if (!viteRoutes.some(route => originalURL.startsWith(route)) && !originalURL.startsWith(clientConfig.base!)) { + if (!originalURL.startsWith(clientConfig.base!) && !viteRoutes.some(route => originalURL.startsWith(route))) { // @ts-expect-error _skip_transform is a private property event.node.req._skip_transform = true } From 2828a12b6d5f6a8e981756e666200e84d08693de Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 16 Jan 2023 13:39:22 +0000 Subject: [PATCH 5/5] test(vite): add tests for vite plugins --- test/basic.test.ts | 10 ++++++++++ test/fixtures/basic/nuxt.config.ts | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/test/basic.test.ts b/test/basic.test.ts index 2f2e0706c5d..8c812130dc1 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -894,6 +894,16 @@ describe('component islands', () => { }) }) +describe.runIf(process.env.NUXT_TEST_DEV && !process.env.TEST_WITH_WEBPACK)('vite plugins', () => { + it('does not override vite plugins', async () => { + expect(await $fetch('/vite-plugin-without-path')).toBe('vite-plugin without path') + expect(await $fetch('/__nuxt-test')).toBe('vite-plugin with __nuxt prefix') + }) + it('does not allow direct access to nuxt source folder', async () => { + expect(await $fetch('/app.config')).toContain('404') + }) +}) + describe.skipIf(process.env.NUXT_TEST_DEV || isWindows)('payload rendering', () => { it('renders a payload', async () => { const payload = await $fetch('/random/a/_payload.js', { responseType: 'text' }) diff --git a/test/fixtures/basic/nuxt.config.ts b/test/fixtures/basic/nuxt.config.ts index 70e64e90497..7a89abf5607 100644 --- a/test/fixtures/basic/nuxt.config.ts +++ b/test/fixtures/basic/nuxt.config.ts @@ -100,6 +100,28 @@ export default defineNuxtConfig({ export: 'namedExport', filePath: '~/other-components-folder/named-export' }) + }, + 'vite:extendConfig' (config) { + config.plugins!.push({ + name: 'nuxt:server', + configureServer (server) { + server.middlewares.use((req, res, next) => { + if (req.url === '/vite-plugin-without-path') { + res.end('vite-plugin without path') + return + } + next() + }) + + server.middlewares.use((req, res, next) => { + if (req.url === '/__nuxt-test') { + res.end('vite-plugin with __nuxt prefix') + return + } + next() + }) + } + }) } }, experimental: {