|
|
|
@ -11,18 +11,29 @@ import {
|
|
|
|
|
import { APP_PATH } from '../alias'
|
|
|
|
|
import type { SiteConfig } from '../config'
|
|
|
|
|
import { createVitePressPlugin } from '../plugin'
|
|
|
|
|
import { sanitizeFileName, slash } from '../shared'
|
|
|
|
|
import { escapeRegExp, sanitizeFileName, slash } from '../shared'
|
|
|
|
|
import { task } from '../utils/task'
|
|
|
|
|
import { buildMPAClient } from './buildMPAClient'
|
|
|
|
|
|
|
|
|
|
// A list of default theme components that should only be loaded on demand.
|
|
|
|
|
const lazyDefaultThemeComponentsRE =
|
|
|
|
|
/VP(HomeSponsors|DocAsideSponsors|TeamPage|TeamMembers|LocalSearchBox|AlgoliaSearchBox|CarbonAds|DocAsideCarbonAds|Sponsors)/
|
|
|
|
|
// https://github.com/vitejs/vite/blob/d2aa0969ee316000d3b957d7e879f001e85e369e/packages/vite/src/node/plugins/splitVendorChunk.ts#L14
|
|
|
|
|
const CSS_LANGS_RE =
|
|
|
|
|
/\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/
|
|
|
|
|
|
|
|
|
|
const clientDir = normalizePath(
|
|
|
|
|
path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../client')
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// these deps are also being used in the client code (outside of the theme)
|
|
|
|
|
// exclude them from the theme chunk so there is no circular dependency
|
|
|
|
|
const excludedModules = [
|
|
|
|
|
'/@siteData',
|
|
|
|
|
'node_modules/@vueuse/core/',
|
|
|
|
|
'node_modules/@vueuse/shared/',
|
|
|
|
|
'node_modules/vue/',
|
|
|
|
|
'node_modules/vue-demi/',
|
|
|
|
|
clientDir
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
// bundles the VitePress app for both client AND server.
|
|
|
|
|
export async function bundle(
|
|
|
|
|
config: SiteConfig,
|
|
|
|
@ -47,6 +58,12 @@ export async function bundle(
|
|
|
|
|
input[slash(alias).replace(/\//g, '_')] = path.resolve(config.srcDir, file)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const themeEntryRE = new RegExp(
|
|
|
|
|
`^${escapeRegExp(
|
|
|
|
|
path.resolve(config.themeDir, 'index.js').replace(/\\/g, '/')
|
|
|
|
|
).slice(0, -2)}m?(j|t)s`
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// resolve options to pass to vite
|
|
|
|
|
const { rollupOptions } = options
|
|
|
|
|
|
|
|
|
@ -109,12 +126,6 @@ export async function bundle(
|
|
|
|
|
: `${config.assetsDir}/chunks/[name].[hash].js`
|
|
|
|
|
},
|
|
|
|
|
manualChunks(id, ctx) {
|
|
|
|
|
if (lazyDefaultThemeComponentsRE.test(id)) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (id.startsWith(`${clientDir}/theme-default`)) {
|
|
|
|
|
return 'theme'
|
|
|
|
|
}
|
|
|
|
|
// move known framework code into a stable chunk so that
|
|
|
|
|
// custom theme changes do not invalidate hash for all pages
|
|
|
|
|
if (id.startsWith('\0vite')) {
|
|
|
|
@ -135,6 +146,19 @@ export async function bundle(
|
|
|
|
|
) {
|
|
|
|
|
return 'framework'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
(id.startsWith(`${clientDir}/theme-default`) ||
|
|
|
|
|
!excludedModules.some((i) => id.includes(i))) &&
|
|
|
|
|
staticImportedByEntry(
|
|
|
|
|
id,
|
|
|
|
|
ctx.getModuleInfo,
|
|
|
|
|
cacheTheme,
|
|
|
|
|
themeEntryRE
|
|
|
|
|
)
|
|
|
|
|
) {
|
|
|
|
|
return 'theme'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
@ -182,6 +206,7 @@ export async function bundle(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const cache = new Map<string, boolean>()
|
|
|
|
|
const cacheTheme = new Map<string, boolean>()
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if a module is statically imported by at least one entry.
|
|
|
|
@ -189,7 +214,7 @@ const cache = new Map<string, boolean>()
|
|
|
|
|
function isEagerChunk(id: string, getModuleInfo: Rollup.GetModuleInfo) {
|
|
|
|
|
if (
|
|
|
|
|
id.includes('node_modules') &&
|
|
|
|
|
!/\.css($|\\?)/.test(id) &&
|
|
|
|
|
!CSS_LANGS_RE.test(id) &&
|
|
|
|
|
staticImportedByEntry(id, getModuleInfo, cache)
|
|
|
|
|
) {
|
|
|
|
|
return true
|
|
|
|
@ -200,6 +225,7 @@ function staticImportedByEntry(
|
|
|
|
|
id: string,
|
|
|
|
|
getModuleInfo: Rollup.GetModuleInfo,
|
|
|
|
|
cache: Map<string, boolean>,
|
|
|
|
|
entryRE: RegExp | null = null,
|
|
|
|
|
importStack: string[] = []
|
|
|
|
|
): boolean {
|
|
|
|
|
if (cache.has(id)) {
|
|
|
|
@ -216,7 +242,7 @@ function staticImportedByEntry(
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mod.isEntry) {
|
|
|
|
|
if (entryRE ? entryRE.test(id) : mod.isEntry) {
|
|
|
|
|
cache.set(id, true)
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
@ -225,6 +251,7 @@ function staticImportedByEntry(
|
|
|
|
|
importer,
|
|
|
|
|
getModuleInfo,
|
|
|
|
|
cache,
|
|
|
|
|
entryRE,
|
|
|
|
|
importStack.concat(id)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|