diff --git a/packages/nuxt/src/app/components/nuxt-layout.ts b/packages/nuxt/src/app/components/nuxt-layout.ts index 0f470b5307..f7f58f4abb 100644 --- a/packages/nuxt/src/app/components/nuxt-layout.ts +++ b/packages/nuxt/src/app/components/nuxt-layout.ts @@ -40,7 +40,7 @@ export default defineComponent({ inheritAttrs: false, props: { name: { - type: [String, Boolean, Object] as unknown as () => unknown extends PageMeta['layout'] ? MaybeRef : PageMeta['layout'], + type: [String, Boolean, Object] as unknown as () => unknown extends ['layout'] ? MaybeRef : PageMeta['layout'], default: null }, fallback: { diff --git a/packages/nuxt/src/pages/module.ts b/packages/nuxt/src/pages/module.ts index 956cf88c99..6ed276a8ef 100644 --- a/packages/nuxt/src/pages/module.ts +++ b/packages/nuxt/src/pages/module.ts @@ -8,7 +8,6 @@ import type { Nuxt, NuxtApp, NuxtPage } from 'nuxt/schema' import { createRoutesContext } from 'unplugin-vue-router' import { resolveOptions } from 'unplugin-vue-router/options' import type { EditableTreeNode, Options as TypedRouterOptions } from 'unplugin-vue-router' - import type { NitroRouteConfig } from 'nitropack' import { defu } from 'defu' import { distDir } from '../dirs' @@ -322,7 +321,8 @@ export default defineNuxtModule({ // Extract macros from pages const pageMetaOptions: PageMetaPluginOptions = { dev: nuxt.options.dev, - sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client + sourcemap: !!nuxt.options.sourcemap.server || !!nuxt.options.sourcemap.client, + updateTemplates } nuxt.hook('modules:done', () => { addVitePlugin(() => PageMetaPlugin.vite(pageMetaOptions)) @@ -364,7 +364,18 @@ export default defineNuxtModule({ filename: 'routes.mjs', getContents ({ app }) { const { routes, imports } = normalizeRoutes(app.pages) - return [...imports, `export default ${routes}`].join('\n') + return ` + ${ + [...imports, `const routes = ${routes}`, `export default routes`].join('\n') + } + + if (import.meta.hot) { + import.meta.hot.accept((mod) => { + console.log('up', mod.default) + Object.assign(routes, mod.default) + }) + } + ` } }) diff --git a/packages/nuxt/src/pages/plugins/page-meta.ts b/packages/nuxt/src/pages/plugins/page-meta.ts index 07c64ebdf0..ce16dcbca1 100644 --- a/packages/nuxt/src/pages/plugins/page-meta.ts +++ b/packages/nuxt/src/pages/plugins/page-meta.ts @@ -8,11 +8,12 @@ import type { Node } from 'estree-walker' import { walk } from 'estree-walker' import MagicString from 'magic-string' import { isAbsolute } from 'pathe' -import { logger } from '@nuxt/kit' - +import { logger, updateTemplates as _updateTemplate } from '@nuxt/kit' +import { } from "vite" export interface PageMetaPluginOptions { dev?: boolean sourcemap?: boolean + updateTemplates: typeof _updateTemplate } const HAS_MACRO_RE = /\bdefinePageMeta\s*\(\s*/ @@ -26,7 +27,7 @@ const CODE_HMR = ` // Vite if (import.meta.hot) { import.meta.hot.accept(mod => { - Object.assign(__nuxt_page_meta, mod) + import.meta.hot.invalidate() }) } // webpack @@ -40,15 +41,15 @@ export const PageMetaPlugin = createUnplugin((options: PageMetaPluginOptions) => return { name: 'nuxt:pages-macros-transform', enforce: 'post', - transformInclude (id) { + transformInclude(id) { return !!parseMacroQuery(id).macro }, - transform (code, id) { + transform(code, id) { const query = parseMacroQuery(id) if (query.type && query.type !== 'script') { return } const s = new MagicString(code) - function result () { + function result() { if (s.hasChanged()) { return { code: s.toString(), @@ -116,7 +117,7 @@ export const PageMetaPlugin = createUnplugin((options: PageMetaPluginOptions) => sourceType: 'module', ecmaVersion: 'latest' }) as Node, { - enter (_node) { + enter(_node) { if (_node.type !== 'CallExpression' || (_node as CallExpression).callee.type !== 'Identifier') { return } const node = _node as CallExpression & { start: number, end: number } const name = 'name' in node.callee && node.callee.name @@ -126,7 +127,7 @@ export const PageMetaPlugin = createUnplugin((options: PageMetaPluginOptions) => let contents = `const __nuxt_page_meta = ${code!.slice(meta.start, meta.end) || 'null'}\nexport default __nuxt_page_meta` + (options.dev ? CODE_HMR : '') - function addImport (name: string | false) { + function addImport(name: string | false) { if (name && importMap.has(name)) { const importValue = importMap.get(name)!.code if (!addedImports.has(importValue)) { @@ -137,7 +138,7 @@ export const PageMetaPlugin = createUnplugin((options: PageMetaPluginOptions) => } walk(meta, { - enter (_node) { + enter(_node) { if (_node.type === 'CallExpression') { const node = _node as CallExpression & { start: number, end: number } addImport('name' in node.callee && node.callee.name) @@ -162,11 +163,22 @@ export const PageMetaPlugin = createUnplugin((options: PageMetaPluginOptions) => vite: { handleHotUpdate: { order: 'pre', - handler: ({ modules }) => { + handler: async (ctx) => { + const { modules } = ctx // Remove macro file from modules list to prevent HMR overrides const index = modules.findIndex(i => i.id?.includes('?macro=true')) if (index !== -1) { - modules.splice(index, 1) + const [macroFile] = modules.splice(index, 1) + if (macroFile) { + await console.log(await ctx.read()) + debugger + ctx.server.moduleGraph.invalidateModule(macroFile) + ctx.server.reloadModule(macroFile) + + // update the macro file + + } + } } } @@ -176,11 +188,11 @@ export const PageMetaPlugin = createUnplugin((options: PageMetaPluginOptions) => // https://github.com/vuejs/vue-loader/pull/1911 // https://github.com/vitejs/vite/issues/8473 -function rewriteQuery (id: string) { +function rewriteQuery(id: string) { return id.replace(/\?.+$/, r => '?macro=true&' + r.replace(/^\?/, '').replace(/¯o=true/, '')) } -function parseMacroQuery (id: string) { +function parseMacroQuery(id: string) { const { search } = parseURL(decodeURIComponent(isAbsolute(id) ? pathToFileURL(id).href : id).replace(/\?macro=true$/, '')) const query = parseQuery(search) if (id.includes('?macro=true')) { @@ -189,6 +201,6 @@ function parseMacroQuery (id: string) { return query } -function getQuotedSpecifier (id: string) { +function getQuotedSpecifier(id: string) { return id.match(/(["']).*\1/)?.[0] } diff --git a/packages/nuxt/src/pages/runtime/plugins/router.ts b/packages/nuxt/src/pages/runtime/plugins/router.ts index 6b7c9c425b..c2f128851e 100644 --- a/packages/nuxt/src/pages/runtime/plugins/router.ts +++ b/packages/nuxt/src/pages/runtime/plugins/router.ts @@ -91,6 +91,40 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({ previousRoute.value = from }) + + if(import.meta.hot) { + console.log(import.meta.hot) + import.meta.hot.accept( () => { + console.log('hot reload self accept') + + }) + import.meta.hot.accept( '/pages/index.vue?macro=true', () => { + console.log('hot reload') + + }) + import.meta.hot.accept( '/pages/index.vue', () => { + console.log('hot reload') + + }) + import.meta.hot.accept( '/pages/index.vue?macro=true', () => { + console.log('hot reload') + + }) + import.meta.hot.accept( '#build/routes', () => { + console.log('hot reload') + + }) + import.meta.hot.accept( '/@id/virtual:nuxt:G:/repo/nuxt/playground/.nuxt/routes.mjs', () => { + console.log('hot reload') + }) + import.meta.hot.accept( '/@id/virtual:nuxt:G:/repo/nuxt/playground/.nuxt/routes.mjs', () => { + console.log('hot reload') + }) + import.meta.hot.accept("/_nuxt/@id/virtual:nuxt:G:/repo/nuxt/playground/.nuxt/routes.mjs", () => { + console.log('hot reload mod') + }) + } + Object.defineProperty(nuxtApp.vueApp.config.globalProperties, 'previousRoute', { get: () => previousRoute.value }) diff --git a/playground/app.vue b/playground/app.vue deleted file mode 100644 index 17d631007a..0000000000 --- a/playground/app.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/playground/layouts/blue.vue b/playground/layouts/blue.vue new file mode 100644 index 0000000000..4a961a4818 --- /dev/null +++ b/playground/layouts/blue.vue @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/playground/layouts/default.vue b/playground/layouts/default.vue new file mode 100644 index 0000000000..2d4da7171c --- /dev/null +++ b/playground/layouts/default.vue @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/playground/pages/index.vue b/playground/pages/index.vue new file mode 100644 index 0000000000..8081512d68 --- /dev/null +++ b/playground/pages/index.vue @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/test/fixtures/basic/nuxt.config.ts b/test/fixtures/basic/nuxt.config.ts index 5d3a861ead..6d820cccce 100644 --- a/test/fixtures/basic/nuxt.config.ts +++ b/test/fixtures/basic/nuxt.config.ts @@ -188,8 +188,11 @@ export default defineNuxtConfig({ compilerOptions: { isCustomElement: (tag) => { return tag === 'custom-component' - } - } + }, + prefixIdentifiers: false, + + }, + }, experimental: { typedPages: true,