pull/4808/head
Divyansh Singh 3 months ago
parent da8fff4aac
commit b25b358805

@ -1,8 +1,7 @@
import fs from 'fs-extra' import fs from 'fs-extra'
import path from 'node:path' import path from 'node:path'
import c from 'picocolors' import c from 'picocolors'
import { isMatch } from 'picomatch' import pm from 'picomatch'
import { glob } from 'tinyglobby'
import { import {
loadConfigFromFile, loadConfigFromFile,
normalizePath, normalizePath,
@ -12,6 +11,11 @@ import {
} from 'vite' } from 'vite'
import type { Awaitable } from '../shared' import type { Awaitable } from '../shared'
import { type SiteConfig, type UserConfig } from '../siteConfig' import { type SiteConfig, type UserConfig } from '../siteConfig'
import {
getWatchedFiles,
normalizeWatchPatterns,
type GlobOptions
} from '../utils/glob'
import { ModuleGraph } from '../utils/moduleGraph' import { ModuleGraph } from '../utils/moduleGraph'
import { resolveRewrites } from './rewritesPlugin' import { resolveRewrites } from './rewritesPlugin'
@ -45,13 +49,15 @@ export interface RouteModule {
| UserRouteConfig[] | UserRouteConfig[]
| ((watchedFiles: string[]) => Awaitable<UserRouteConfig[]>) | ((watchedFiles: string[]) => Awaitable<UserRouteConfig[]>)
transformPageData?: UserConfig['transformPageData'] transformPageData?: UserConfig['transformPageData']
options?: { globOptions?: GlobOptions }
} }
interface ResolvedRouteModule { interface ResolvedRouteModule {
watch: string[] | undefined watch: string[]
routes: ResolvedRouteConfig[] | undefined routes?: ResolvedRouteConfig[]
loader: RouteModule['paths'] loader: RouteModule['paths']
transformPageData?: RouteModule['transformPageData'] transformPageData?: RouteModule['transformPageData']
options: NonNullable<RouteModule['options']>
} }
const dynamicRouteRE = /\[(\w+?)\]/g const dynamicRouteRE = /\[(\w+?)\]/g
@ -63,7 +69,7 @@ let moduleGraph = new ModuleGraph()
/** /**
* Helper for defining routes with type inference * Helper for defining routes with type inference
*/ */
export function defineRoutes(loader: RouteModule) { export function defineRoutes(loader: RouteModule): RouteModule {
return loader return loader
} }
@ -78,23 +84,10 @@ export async function resolvePages(
routeModuleCache.clear() routeModuleCache.clear()
} }
// Important: tinyglobby doesn't guarantee order of the returned files. const allMarkdownFiles = await getWatchedFiles(['**/*.md'], {
// We must sort the pages so the input list to rollup is stable across
// builds - otherwise different input order could result in different exports
// order in shared chunks which in turns invalidates the hash of every chunk!
// JavaScript built-in sort() is mandated to be stable as of ES2019 and
// supported in Node 12+, which is required by Vite.
const allMarkdownFiles = (
await glob(['**/*.md'], {
cwd: srcDir, cwd: srcDir,
ignore: [ ignore: userConfig.srcExclude
'**/node_modules/**',
'**/dist/**',
...(userConfig.srcExclude || [])
],
expandDirectories: false
}) })
).sort()
const pages: string[] = [] const pages: string[] = []
const dynamicRouteFiles: string[] = [] const dynamicRouteFiles: string[] = []
@ -137,9 +130,7 @@ export const dynamicRoutesPlugin = async (
const matched = config.dynamicRoutes.find( const matched = config.dynamicRoutes.find(
(r) => r.fullPath === normalizedId (r) => r.fullPath === normalizedId
) )
if (matched) { if (matched) return normalizedId
return normalizedId
}
}, },
load(id) { load(id) {
@ -180,23 +171,22 @@ export const dynamicRoutesPlugin = async (
for (const id of moduleGraph.delete(normalizedFile)) { for (const id of moduleGraph.delete(normalizedFile)) {
routeModuleCache.delete(id) routeModuleCache.delete(id)
const mod = this.environment.moduleGraph.getModuleById(id) const mod = this.environment.moduleGraph.getModuleById(id)
if (mod) { if (mod) modules.push(mod)
modules.push(mod)
}
} }
// Also check if the file matches any custom watch patterns. // Also check if the file matches any custom watch patterns.
let watchedFileChanged = false let watchedFileChanged = false
for (const [file, route] of routeModuleCache) { for (const [file, route] of routeModuleCache) {
if (route.watch && isMatch(normalizedFile, route.watch)) { if (
route.watch?.length &&
pm(route.watch, route.options.globOptions)(normalizedFile)
) {
route.routes = undefined route.routes = undefined
watchedFileChanged = true watchedFileChanged = true
for (const id of moduleGraph.delete(file)) { for (const id of moduleGraph.delete(file)) {
const mod = this.environment.moduleGraph.getModuleById(id) const mod = this.environment.moduleGraph.getModuleById(id)
if (mod) { if (mod) modules.push(mod)
modules.push(mod)
}
} }
} }
} }
@ -255,7 +245,8 @@ async function resolveDynamicRoutes(
// load the paths loader module // load the paths loader module
let watch: ResolvedRouteModule['watch'] let watch: ResolvedRouteModule['watch']
let loader: ResolvedRouteModule['loader'] let loader: ResolvedRouteModule['loader']
let extras: Partial<ResolvedRouteModule> let transformPageData: ResolvedRouteModule['transformPageData']
let options: ResolvedRouteModule['options']
const loaderPath = normalizePath(pathsFile) const loaderPath = normalizePath(pathsFile)
const existing = routeModuleCache.get(loaderPath) const existing = routeModuleCache.get(loaderPath)
@ -267,7 +258,7 @@ async function resolveDynamicRoutes(
continue continue
} }
;({ watch, loader, ...extras } = existing) ;({ watch, loader, transformPageData, options } = existing)
} else { } else {
let mod let mod
try { try {
@ -294,8 +285,14 @@ async function resolveDynamicRoutes(
continue continue
} }
// @ts-ignore const loaderModule = mod.config as RouteModule
;({ paths: loader, watch, ...extras } = mod.config) watch = normalizeWatchPatterns(
loaderModule.watch,
path.dirname(pathsFile)
)
loader = loaderModule.paths
transformPageData = loaderModule.transformPageData
options = loaderModule.options || {}
if (!loader) { if (!loader) {
logger.warn( logger.warn(
@ -307,15 +304,6 @@ async function resolveDynamicRoutes(
continue continue
} }
watch = typeof watch === 'string' ? [watch] : watch
if (watch) {
watch = watch.map((p) =>
p.startsWith('.')
? normalizePath(path.resolve(path.dirname(pathsFile), p))
: normalizePath(p)
)
}
// record deps for hmr // record deps for hmr
newModuleGraph.add( newModuleGraph.add(
loaderPath, loaderPath,
@ -327,15 +315,7 @@ async function resolveDynamicRoutes(
let pathsData: UserRouteConfig[] let pathsData: UserRouteConfig[]
if (typeof loader === 'function') { if (typeof loader === 'function') {
let watchedFiles: string[] = [] const watchedFiles = await getWatchedFiles(watch, options.globOptions)
if (watch) {
watchedFiles = (
await glob(watch, {
ignore: ['**/node_modules/**', '**/dist/**'],
expandDirectories: false
})
).sort()
}
pathsData = await loader(watchedFiles) pathsData = await loader(watchedFiles)
} else { } else {
pathsData = loader pathsData = loader
@ -355,7 +335,8 @@ async function resolveDynamicRoutes(
} }
}) })
routeModuleCache.set(loaderPath, { ...extras, watch, routes, loader }) const mod = { watch, routes, loader, transformPageData, options }
routeModuleCache.set(loaderPath, mod)
return routes return routes
} }

Loading…
Cancel
Save