mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 00:23:53 +00:00
wip
This commit is contained in:
parent
4dcc48f4e6
commit
5aac596833
@ -40,7 +40,7 @@ export default defineComponent({
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
name: {
|
||||
type: [String, Boolean, Object] as unknown as () => unknown extends PageMeta['layout'] ? MaybeRef<string | false> : PageMeta['layout'],
|
||||
type: [String, Boolean, Object] as unknown as () => unknown extends ['layout'] ? MaybeRef<string | false> : PageMeta['layout'],
|
||||
default: null
|
||||
},
|
||||
fallback: {
|
||||
|
@ -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)
|
||||
})
|
||||
}
|
||||
`
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -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]
|
||||
}
|
||||
|
@ -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
|
||||
})
|
||||
|
@ -1,13 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Edit this file to play around with Nuxt but never commit changes! -->
|
||||
<div>
|
||||
Nuxt 3 Playground
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
6
playground/layouts/blue.vue
Normal file
6
playground/layouts/blue.vue
Normal file
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<div class="blue" style="border: solid blue 1px;">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
6
playground/layouts/default.vue
Normal file
6
playground/layouts/default.vue
Normal file
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<div class="red">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
10
playground/pages/index.vue
Normal file
10
playground/pages/index.vue
Normal file
@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div>Index Page</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'blue',
|
||||
});
|
||||
</script>
|
||||
|
7
test/fixtures/basic/nuxt.config.ts
vendored
7
test/fixtures/basic/nuxt.config.ts
vendored
@ -188,8 +188,11 @@ export default defineNuxtConfig({
|
||||
compilerOptions: {
|
||||
isCustomElement: (tag) => {
|
||||
return tag === 'custom-component'
|
||||
}
|
||||
}
|
||||
},
|
||||
prefixIdentifiers: false,
|
||||
|
||||
},
|
||||
|
||||
},
|
||||
experimental: {
|
||||
typedPages: true,
|
||||
|
Loading…
Reference in New Issue
Block a user