Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

Commit

Permalink
feat(nuxt): exclude page chunks from being prefetched (#6662)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe authored Aug 16, 2022
1 parent 3730ba8 commit 94214d6
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 13 deletions.
20 changes: 19 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 } 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'
Expand Down Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions packages/schema/build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export default defineBuildConfig({
// Type imports
'vue-meta',
'vue-router',
'vue-bundle-renderer',
'vue',
'hookable',
'nitropack',
Expand Down
2 changes: 2 additions & 0 deletions packages/schema/src/types/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion packages/vite/src/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = []) {
Expand Down Expand Up @@ -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')
}
27 changes: 17 additions & 10 deletions packages/webpack/src/plugins/vue/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

interface PluginOptions {
filename: string
nuxt: Nuxt
}

export default class VueSSRClientPlugin {
options: {
filename: string
}
options: PluginOptions

constructor (options = {}) {
constructor (options: PluginOptions) {
this.options = Object.assign({
filename: null
}, options)
Expand Down Expand Up @@ -53,7 +57,7 @@ export default class VueSSRClientPlugin {
assetsMapping[componentHash].push(name)
})

const manifest = {
const webpackManifest = {
publicPath: stats.publicPath,
all: allFiles,
initial: initialFiles,
Expand All @@ -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) {
Expand All @@ -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
}
}
}
Expand All @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion packages/webpack/src/presets/vue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down

0 comments on commit 94214d6

Please sign in to comment.