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,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
name: {
|
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
|
default: null
|
||||||
},
|
},
|
||||||
fallback: {
|
fallback: {
|
||||||
|
@ -8,7 +8,6 @@ import type { Nuxt, NuxtApp, NuxtPage } from 'nuxt/schema'
|
|||||||
import { createRoutesContext } from 'unplugin-vue-router'
|
import { createRoutesContext } from 'unplugin-vue-router'
|
||||||
import { resolveOptions } from 'unplugin-vue-router/options'
|
import { resolveOptions } from 'unplugin-vue-router/options'
|
||||||
import type { EditableTreeNode, Options as TypedRouterOptions } from 'unplugin-vue-router'
|
import type { EditableTreeNode, Options as TypedRouterOptions } from 'unplugin-vue-router'
|
||||||
|
|
||||||
import type { NitroRouteConfig } from 'nitropack'
|
import type { NitroRouteConfig } from 'nitropack'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import { distDir } from '../dirs'
|
import { distDir } from '../dirs'
|
||||||
@ -322,7 +321,8 @@ export default defineNuxtModule({
|
|||||||
// Extract macros from pages
|
// Extract macros from pages
|
||||||
const pageMetaOptions: PageMetaPluginOptions = {
|
const pageMetaOptions: PageMetaPluginOptions = {
|
||||||
dev: nuxt.options.dev,
|
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', () => {
|
nuxt.hook('modules:done', () => {
|
||||||
addVitePlugin(() => PageMetaPlugin.vite(pageMetaOptions))
|
addVitePlugin(() => PageMetaPlugin.vite(pageMetaOptions))
|
||||||
@ -364,7 +364,18 @@ export default defineNuxtModule({
|
|||||||
filename: 'routes.mjs',
|
filename: 'routes.mjs',
|
||||||
getContents ({ app }) {
|
getContents ({ app }) {
|
||||||
const { routes, imports } = normalizeRoutes(app.pages)
|
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 { walk } from 'estree-walker'
|
||||||
import MagicString from 'magic-string'
|
import MagicString from 'magic-string'
|
||||||
import { isAbsolute } from 'pathe'
|
import { isAbsolute } from 'pathe'
|
||||||
import { logger } from '@nuxt/kit'
|
import { logger, updateTemplates as _updateTemplate } from '@nuxt/kit'
|
||||||
|
import { } from "vite"
|
||||||
export interface PageMetaPluginOptions {
|
export interface PageMetaPluginOptions {
|
||||||
dev?: boolean
|
dev?: boolean
|
||||||
sourcemap?: boolean
|
sourcemap?: boolean
|
||||||
|
updateTemplates: typeof _updateTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
const HAS_MACRO_RE = /\bdefinePageMeta\s*\(\s*/
|
const HAS_MACRO_RE = /\bdefinePageMeta\s*\(\s*/
|
||||||
@ -26,7 +27,7 @@ const CODE_HMR = `
|
|||||||
// Vite
|
// Vite
|
||||||
if (import.meta.hot) {
|
if (import.meta.hot) {
|
||||||
import.meta.hot.accept(mod => {
|
import.meta.hot.accept(mod => {
|
||||||
Object.assign(__nuxt_page_meta, mod)
|
import.meta.hot.invalidate()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// webpack
|
// webpack
|
||||||
@ -40,15 +41,15 @@ export const PageMetaPlugin = createUnplugin((options: PageMetaPluginOptions) =>
|
|||||||
return {
|
return {
|
||||||
name: 'nuxt:pages-macros-transform',
|
name: 'nuxt:pages-macros-transform',
|
||||||
enforce: 'post',
|
enforce: 'post',
|
||||||
transformInclude (id) {
|
transformInclude(id) {
|
||||||
return !!parseMacroQuery(id).macro
|
return !!parseMacroQuery(id).macro
|
||||||
},
|
},
|
||||||
transform (code, id) {
|
transform(code, id) {
|
||||||
const query = parseMacroQuery(id)
|
const query = parseMacroQuery(id)
|
||||||
if (query.type && query.type !== 'script') { return }
|
if (query.type && query.type !== 'script') { return }
|
||||||
|
|
||||||
const s = new MagicString(code)
|
const s = new MagicString(code)
|
||||||
function result () {
|
function result() {
|
||||||
if (s.hasChanged()) {
|
if (s.hasChanged()) {
|
||||||
return {
|
return {
|
||||||
code: s.toString(),
|
code: s.toString(),
|
||||||
@ -116,7 +117,7 @@ export const PageMetaPlugin = createUnplugin((options: PageMetaPluginOptions) =>
|
|||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
ecmaVersion: 'latest'
|
ecmaVersion: 'latest'
|
||||||
}) as Node, {
|
}) as Node, {
|
||||||
enter (_node) {
|
enter(_node) {
|
||||||
if (_node.type !== 'CallExpression' || (_node as CallExpression).callee.type !== 'Identifier') { return }
|
if (_node.type !== 'CallExpression' || (_node as CallExpression).callee.type !== 'Identifier') { return }
|
||||||
const node = _node as CallExpression & { start: number, end: number }
|
const node = _node as CallExpression & { start: number, end: number }
|
||||||
const name = 'name' in node.callee && node.callee.name
|
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 : '')
|
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)) {
|
if (name && importMap.has(name)) {
|
||||||
const importValue = importMap.get(name)!.code
|
const importValue = importMap.get(name)!.code
|
||||||
if (!addedImports.has(importValue)) {
|
if (!addedImports.has(importValue)) {
|
||||||
@ -137,7 +138,7 @@ export const PageMetaPlugin = createUnplugin((options: PageMetaPluginOptions) =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
walk(meta, {
|
walk(meta, {
|
||||||
enter (_node) {
|
enter(_node) {
|
||||||
if (_node.type === 'CallExpression') {
|
if (_node.type === 'CallExpression') {
|
||||||
const node = _node as CallExpression & { start: number, end: number }
|
const node = _node as CallExpression & { start: number, end: number }
|
||||||
addImport('name' in node.callee && node.callee.name)
|
addImport('name' in node.callee && node.callee.name)
|
||||||
@ -162,11 +163,22 @@ export const PageMetaPlugin = createUnplugin((options: PageMetaPluginOptions) =>
|
|||||||
vite: {
|
vite: {
|
||||||
handleHotUpdate: {
|
handleHotUpdate: {
|
||||||
order: 'pre',
|
order: 'pre',
|
||||||
handler: ({ modules }) => {
|
handler: async (ctx) => {
|
||||||
|
const { modules } = ctx
|
||||||
// Remove macro file from modules list to prevent HMR overrides
|
// Remove macro file from modules list to prevent HMR overrides
|
||||||
const index = modules.findIndex(i => i.id?.includes('?macro=true'))
|
const index = modules.findIndex(i => i.id?.includes('?macro=true'))
|
||||||
if (index !== -1) {
|
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/vuejs/vue-loader/pull/1911
|
||||||
// https://github.com/vitejs/vite/issues/8473
|
// 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/, ''))
|
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 { search } = parseURL(decodeURIComponent(isAbsolute(id) ? pathToFileURL(id).href : id).replace(/\?macro=true$/, ''))
|
||||||
const query = parseQuery(search)
|
const query = parseQuery(search)
|
||||||
if (id.includes('?macro=true')) {
|
if (id.includes('?macro=true')) {
|
||||||
@ -189,6 +201,6 @@ function parseMacroQuery (id: string) {
|
|||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
function getQuotedSpecifier (id: string) {
|
function getQuotedSpecifier(id: string) {
|
||||||
return id.match(/(["']).*\1/)?.[0]
|
return id.match(/(["']).*\1/)?.[0]
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,40 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({
|
|||||||
previousRoute.value = from
|
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', {
|
Object.defineProperty(nuxtApp.vueApp.config.globalProperties, 'previousRoute', {
|
||||||
get: () => previousRoute.value
|
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: {
|
compilerOptions: {
|
||||||
isCustomElement: (tag) => {
|
isCustomElement: (tag) => {
|
||||||
return tag === 'custom-component'
|
return tag === 'custom-component'
|
||||||
}
|
},
|
||||||
}
|
prefixIdentifiers: false,
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
experimental: {
|
experimental: {
|
||||||
typedPages: true,
|
typedPages: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user