mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-19 01:45:53 +00:00
feat(nuxt): exclude page chunks from being prefetched (#6662)
This commit is contained in:
parent
3730ba88f5
commit
94214d6b32
@ -1,6 +1,6 @@
|
||||
import { existsSync } from 'node:fs'
|
||||
import { defineNuxtModule, addTemplate, addPlugin, addVitePlugin, addWebpackPlugin, findPath } from '@nuxt/kit'
|
||||
import { resolve } from 'pathe'
|
||||
import { relative, resolve } from 'pathe'
|
||||
import { genString, genImport, genObjectFromRawEntries } from 'knitwork'
|
||||
import escapeRE from 'escape-string-regexp'
|
||||
import type { NuxtApp, NuxtPage } from '@nuxt/schema'
|
||||
@ -99,6 +99,24 @@ export default defineNuxtModule({
|
||||
// Add router plugin
|
||||
addPlugin(resolve(runtimeDir, 'router'))
|
||||
|
||||
const getSources = (pages: NuxtPage[]): string[] => pages.flatMap(p =>
|
||||
[relative(nuxt.options.srcDir, p.file), ...getSources(p.children || [])]
|
||||
)
|
||||
|
||||
// Do not prefetch page chunks
|
||||
nuxt.hook('build:manifest', async (manifest) => {
|
||||
const pages = await resolvePagesRoutes()
|
||||
await nuxt.callHook('pages:extend', pages)
|
||||
|
||||
const sourceFiles = getSources(pages)
|
||||
for (const key in manifest) {
|
||||
if (manifest[key].isEntry) {
|
||||
manifest[key].dynamicImports =
|
||||
manifest[key].dynamicImports?.filter(i => !sourceFiles.includes(i))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Add routes template
|
||||
addTemplate({
|
||||
filename: 'routes.mjs',
|
||||
|
@ -21,6 +21,7 @@ export default defineBuildConfig({
|
||||
// Type imports
|
||||
'vue-meta',
|
||||
'vue-router',
|
||||
'vue-bundle-renderer',
|
||||
'vue',
|
||||
'hookable',
|
||||
'nitropack',
|
||||
|
@ -3,6 +3,7 @@ import type { Server as HttpsServer } from 'node:https'
|
||||
import type { Compiler, Configuration, Stats } from 'webpack'
|
||||
import type { TSConfig } from 'pkg-types'
|
||||
import type { InlineConfig as ViteInlineConfig, ViteDevServer } from 'vite'
|
||||
import type { Manifest } from 'vue-bundle-renderer'
|
||||
import type { ModuleContainer } from './module'
|
||||
import type { NuxtTemplate, Nuxt, NuxtApp } from './nuxt'
|
||||
import type { Preset as ImportPreset, Import } from 'unimport'
|
||||
@ -72,6 +73,7 @@ export interface NuxtHooks {
|
||||
'app:templatesGenerated': (app: NuxtApp) => HookResult
|
||||
'builder:generateApp': () => HookResult
|
||||
'pages:extend': (pages: NuxtPage[]) => HookResult
|
||||
'build:manifest': (manifest: Manifest) => HookResult
|
||||
|
||||
// Auto imports
|
||||
'autoImports:sources': (presets: ImportPresetWithDeprecation[]) => HookResult
|
||||
|
@ -2,7 +2,8 @@ import fse from 'fs-extra'
|
||||
import { resolve } from 'pathe'
|
||||
import { withoutLeadingSlash, withTrailingSlash } from 'ufo'
|
||||
import escapeRE from 'escape-string-regexp'
|
||||
import { normalizeViteManifest, Manifest } from 'vue-bundle-renderer'
|
||||
import { normalizeViteManifest } from 'vue-bundle-renderer'
|
||||
import type { Manifest } from 'vue-bundle-renderer'
|
||||
import type { ViteBuildContext } from './vite'
|
||||
|
||||
export async function writeManifest (ctx: ViteBuildContext, css: string[] = []) {
|
||||
@ -45,7 +46,10 @@ export async function writeManifest (ctx: ViteBuildContext, css: string[] = [])
|
||||
}
|
||||
|
||||
await fse.mkdirp(serverDist)
|
||||
|
||||
const manifest = normalizeViteManifest(clientManifest)
|
||||
await ctx.nuxt.callHook('build:manifest', manifest)
|
||||
|
||||
await fse.writeFile(resolve(serverDist, 'client.manifest.json'), JSON.stringify(manifest, null, 2), 'utf8')
|
||||
await fse.writeFile(resolve(serverDist, 'client.manifest.mjs'), 'export default ' + JSON.stringify(manifest, null, 2), 'utf8')
|
||||
}
|
||||
|
@ -9,14 +9,18 @@ import hash from 'hash-sum'
|
||||
import { uniq } from 'lodash-es'
|
||||
import fse from 'fs-extra'
|
||||
|
||||
import type { Nuxt } from '@nuxt/schema'
|
||||
import { isJS, isCSS, isHotUpdate } from './util'
|
||||
|
||||
export default class VueSSRClientPlugin {
|
||||
options: {
|
||||
filename: string
|
||||
}
|
||||
interface PluginOptions {
|
||||
filename: string
|
||||
nuxt: Nuxt
|
||||
}
|
||||
|
||||
constructor (options = {}) {
|
||||
export default class VueSSRClientPlugin {
|
||||
options: PluginOptions
|
||||
|
||||
constructor (options: PluginOptions) {
|
||||
this.options = Object.assign({
|
||||
filename: null
|
||||
}, options)
|
||||
@ -53,7 +57,7 @@ export default class VueSSRClientPlugin {
|
||||
assetsMapping[componentHash].push(name)
|
||||
})
|
||||
|
||||
const manifest = {
|
||||
const webpackManifest = {
|
||||
publicPath: stats.publicPath,
|
||||
all: allFiles,
|
||||
initial: initialFiles,
|
||||
@ -64,7 +68,7 @@ export default class VueSSRClientPlugin {
|
||||
|
||||
const { entrypoints, namedChunkGroups } = stats
|
||||
const assetModules = stats.modules.filter(m => m.assets.length)
|
||||
const fileToIndex = file => manifest.all.indexOf(file)
|
||||
const fileToIndex = file => webpackManifest.all.indexOf(file)
|
||||
stats.modules.forEach((m) => {
|
||||
// Ignore modules duplicated in multiple chunks
|
||||
if (m.chunks.length === 1) {
|
||||
@ -88,15 +92,15 @@ export default class VueSSRClientPlugin {
|
||||
}
|
||||
|
||||
const files = Array.from(filesSet)
|
||||
manifest.modules[hash(id)] = files
|
||||
webpackManifest.modules[hash(id)] = files
|
||||
|
||||
// In production mode, modules may be concatenated by scope hoisting
|
||||
// Include ConcatenatedModule for not losing module-component mapping
|
||||
if (Array.isArray(m.modules)) {
|
||||
for (const concatenatedModule of m.modules) {
|
||||
const id = hash(concatenatedModule.identifier.replace(/\s\w+$/, ''))
|
||||
if (!manifest.modules[id]) {
|
||||
manifest.modules[id] = files
|
||||
if (!webpackManifest.modules[id]) {
|
||||
webpackManifest.modules[id] = files
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -110,7 +114,10 @@ export default class VueSSRClientPlugin {
|
||||
}
|
||||
})
|
||||
|
||||
const src = JSON.stringify(normalizeWebpackManifest(manifest), null, 2)
|
||||
const manifest = normalizeWebpackManifest(webpackManifest)
|
||||
await this.options.nuxt.callHook('build:manifest', manifest)
|
||||
|
||||
const src = JSON.stringify(manifest, null, 2)
|
||||
|
||||
await fse.mkdirp(dirname(this.options.filename))
|
||||
await fse.writeFile(this.options.filename, src)
|
||||
|
@ -22,7 +22,8 @@ export function vue (ctx: WebpackConfigContext) {
|
||||
|
||||
if (ctx.isClient) {
|
||||
config.plugins.push(new VueSSRClientPlugin({
|
||||
filename: resolve(options.buildDir, 'dist/server', `${ctx.name}.manifest.json`)
|
||||
filename: resolve(options.buildDir, 'dist/server', `${ctx.name}.manifest.json`),
|
||||
nuxt: ctx.nuxt
|
||||
}))
|
||||
} else {
|
||||
config.plugins.push(new VueSSRServerPlugin({
|
||||
|
Loading…
Reference in New Issue
Block a user