10000 feat(nuxt): use build plugin to access nuxt route injection by danielroe Β· Pull Request #21585 Β· nuxt/nuxt Β· GitHub
[go: up one dir, main page]

Skip to content

feat(nuxt): use build plugin to access nuxt route injection #21585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion packages/nuxt/src/pages/module.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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 = /^\/?:.*(\?|\(\.\*\)\*)$/

Expand Down Expand Up @@ -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'))

Expand Down
39 changes: 39 additions & 0 deletions packages/nuxt/src/pages/route-injection.ts
Original file line number Diff line number Diff line change
@@ -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
}
}
}
}
})
11 changes: 11 additions & 0 deletions packages/schema/src/config/experimental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
0