mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
feat(nuxt): use build plugin to access nuxt route injection (#21585)
This commit is contained in:
parent
f4ee12e6ba
commit
305d6de030
@ -1,6 +1,6 @@
|
||||
import { existsSync, readdirSync } from 'node:fs'
|
||||
import { mkdir, readFile } from 'node:fs/promises'
|
||||
import { addComponent, addPlugin, addTemplate, addVitePlugin, addWebpackPlugin, defineNuxtModule, findPath, updateTemplates } from '@nuxt/kit'
|
||||
import { addBuildPlugin, addComponent, addPlugin, addTemplate, addVitePlugin, addWebpackPlugin, defineNuxtModule, findPath, updateTemplates } from '@nuxt/kit'
|
||||
import { dirname, join, relative, resolve } from 'pathe'
|
||||
import { genImport, genObjectFromRawEntries, genString } from 'knitwork'
|
||||
import { joinURL } from 'ufo'
|
||||
@ -13,6 +13,7 @@ import { distDir } from '../dirs'
|
||||
import { normalizeRoutes, resolvePagesRoutes } from './utils'
|
||||
import type { PageMetaPluginOptions } from './page-meta'
|
||||
import { PageMetaPlugin } from './page-meta'
|
||||
import { RouteInjectionPlugin } from './route-injection'
|
||||
|
||||
const OPTIONAL_PARAM_RE = /^\/?:.*(\?|\(\.\*\)\*)$/
|
||||
|
||||
@ -253,6 +254,11 @@ export default defineNuxtModule({
|
||||
// Add prefetching support for middleware & layouts
|
||||
addPlugin(resolve(runtimeDir, 'plugins/prefetch.client'))
|
||||
|
||||
// Add build plugin to ensure template $route is kept in sync with `<NuxtPage>`
|
||||
if (nuxt.options.experimental.templateRouteInjection) {
|
||||
addBuildPlugin(RouteInjectionPlugin(nuxt), { server: false })
|
||||
}
|
||||
|
||||
// Add router plugin
|
||||
addPlugin(resolve(runtimeDir, 'plugins/router'))
|
||||
|
||||
|
39
packages/nuxt/src/pages/route-injection.ts
Normal file
39
packages/nuxt/src/pages/route-injection.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { createUnplugin } from 'unplugin'
|
||||
import MagicString from 'magic-string'
|
||||
import type { Nuxt } from '@nuxt/schema'
|
||||
import { isVue } from '../core/utils'
|
||||
|
||||
const INJECTION_RE = /\b_ctx\.\$route\b/g
|
||||
const INJECTION_SINGLE_RE = /\b_ctx\.\$route\b/
|
||||
|
||||
export const RouteInjectionPlugin = (nuxt: Nuxt) => createUnplugin(() => {
|
||||
return {
|
||||
name: 'nuxt:route-injection-plugin',
|
||||
enforce: 'post',
|
||||
transformInclude (id) {
|
||||
return isVue(id, { type: ['template', 'script'] })
|
||||
},
|
||||
transform (code) {
|
||||
if (!INJECTION_SINGLE_RE.test(code)) { return }
|
||||
|
||||
let replaced = false
|
||||
const s = new MagicString(code)
|
||||
s.replace(INJECTION_RE, () => {
|
||||
replaced = true
|
||||
return '_ctx._.provides[__nuxt_route_symbol]'
|
||||
})
|
||||
if (replaced) {
|
||||
s.prepend('import { PageRouteSymbol as __nuxt_route_symbol } from \'#app/components/injections\';\n')
|
||||
}
|
||||
|
||||
if (s.hasChanged()) {
|
||||
return {
|
||||
code: s.toString(),
|
||||
map: nuxt.options.sourcemap.client || nuxt.options.sourcemap.server
|
||||
? s.generateMap({ hires: true })
|
||||
: undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
@ -58,6 +58,17 @@ export default defineUntypedSchema({
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* By default the route object returned by the auto-imported `useRoute()` composable
|
||||
* is kept in sync with the current page in view in `<NuxtPage>`. This is not true for
|
||||
* `vue-router`'s exported `useRoute` or for the default `$route` object available in your
|
||||
* Vue templates.
|
||||
*
|
||||
* By enabling this option a mixin will be injected to keep the `$route` template object
|
||||
* in sync with Nuxt's managed `useRoute()`.
|
||||
*/
|
||||
templateRouteInjection: true,
|
||||
|
||||
/**
|
||||
* Whether to restore Nuxt app state from `sessionStorage` when reloading the page
|
||||
* after a chunk error or manual `reloadNuxtApp()` call.
|
||||
|
Loading…
Reference in New Issue
Block a user