|
|
@ -2,6 +2,7 @@ import _debug from 'debug'
|
|
|
|
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 { glob } from 'tinyglobby'
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
createLogger,
|
|
|
|
createLogger,
|
|
|
|
loadConfigFromFile,
|
|
|
|
loadConfigFromFile,
|
|
|
@ -12,10 +13,20 @@ import {
|
|
|
|
import { DEFAULT_THEME_PATH } from './alias'
|
|
|
|
import { DEFAULT_THEME_PATH } from './alias'
|
|
|
|
import type { DefaultTheme } from './defaultTheme'
|
|
|
|
import type { DefaultTheme } from './defaultTheme'
|
|
|
|
import { resolvePages } from './plugins/dynamicRoutesPlugin'
|
|
|
|
import { resolvePages } from './plugins/dynamicRoutesPlugin'
|
|
|
|
import { APPEARANCE_KEY, slash, type HeadConfig, type SiteData } from './shared'
|
|
|
|
import {
|
|
|
|
|
|
|
|
APPEARANCE_KEY,
|
|
|
|
|
|
|
|
VP_SOURCE_KEY,
|
|
|
|
|
|
|
|
isObject,
|
|
|
|
|
|
|
|
slash,
|
|
|
|
|
|
|
|
type AdditionalConfig,
|
|
|
|
|
|
|
|
type Awaitable,
|
|
|
|
|
|
|
|
type HeadConfig,
|
|
|
|
|
|
|
|
type SiteData
|
|
|
|
|
|
|
|
} from './shared'
|
|
|
|
import type { RawConfigExports, SiteConfig, UserConfig } from './siteConfig'
|
|
|
|
import type { RawConfigExports, SiteConfig, UserConfig } from './siteConfig'
|
|
|
|
|
|
|
|
|
|
|
|
export { resolvePages } from './plugins/dynamicRoutesPlugin'
|
|
|
|
export { resolvePages } from './plugins/dynamicRoutesPlugin'
|
|
|
|
|
|
|
|
export { resolveSiteDataByRoute } from './shared'
|
|
|
|
export * from './siteConfig'
|
|
|
|
export * from './siteConfig'
|
|
|
|
|
|
|
|
|
|
|
|
const debug = _debug('vitepress:config')
|
|
|
|
const debug = _debug('vitepress:config')
|
|
|
@ -25,21 +36,40 @@ const resolve = (root: string, file: string) =>
|
|
|
|
|
|
|
|
|
|
|
|
export type UserConfigFn<ThemeConfig> = (
|
|
|
|
export type UserConfigFn<ThemeConfig> = (
|
|
|
|
env: ConfigEnv
|
|
|
|
env: ConfigEnv
|
|
|
|
) => UserConfig<ThemeConfig> | Promise<UserConfig<ThemeConfig>>
|
|
|
|
) => Awaitable<UserConfig<ThemeConfig>>
|
|
|
|
export type UserConfigExport<ThemeConfig> =
|
|
|
|
export type UserConfigExport<ThemeConfig> =
|
|
|
|
| UserConfig<ThemeConfig>
|
|
|
|
| Awaitable<UserConfig<ThemeConfig>>
|
|
|
|
| Promise<UserConfig<ThemeConfig>>
|
|
|
|
|
|
|
|
| UserConfigFn<ThemeConfig>
|
|
|
|
| UserConfigFn<ThemeConfig>
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Type config helper
|
|
|
|
* Type config helper
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export function defineConfig(config: UserConfig<DefaultTheme.Config>) {
|
|
|
|
export function defineConfig<ThemeConfig = DefaultTheme.Config>(
|
|
|
|
|
|
|
|
config: UserConfig<NoInfer<ThemeConfig>>
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
return config
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export type AdditionalConfigFn<ThemeConfig> = (
|
|
|
|
|
|
|
|
env: ConfigEnv
|
|
|
|
|
|
|
|
) => Awaitable<AdditionalConfig<ThemeConfig>>
|
|
|
|
|
|
|
|
export type AdditionalConfigExport<ThemeConfig> =
|
|
|
|
|
|
|
|
| Awaitable<AdditionalConfig<ThemeConfig>>
|
|
|
|
|
|
|
|
| AdditionalConfigFn<ThemeConfig>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Type config helper for additional/locale-specific config
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
export function defineAdditionalConfig<ThemeConfig = DefaultTheme.Config>(
|
|
|
|
|
|
|
|
config: AdditionalConfig<NoInfer<ThemeConfig>>
|
|
|
|
|
|
|
|
) {
|
|
|
|
return config
|
|
|
|
return config
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Type config helper for custom theme config
|
|
|
|
* Type config helper for custom theme config
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @deprecated use `defineConfig` instead
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export function defineConfigWithTheme<ThemeConfig>(
|
|
|
|
export function defineConfigWithTheme<ThemeConfig>(
|
|
|
|
config: UserConfig<ThemeConfig>
|
|
|
|
config: UserConfig<ThemeConfig>
|
|
|
@ -141,6 +171,62 @@ export async function resolveConfig(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const supportedConfigExtensions = ['js', 'ts', 'mjs', 'mts']
|
|
|
|
const supportedConfigExtensions = ['js', 'ts', 'mjs', 'mts']
|
|
|
|
|
|
|
|
const additionalConfigRE = /(?:^|\/|\\)config\.m?[jt]s$/
|
|
|
|
|
|
|
|
const additionalConfigGlob = `**/config.{js,mjs,ts,mts}`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function isAdditionalConfigFile(path: string) {
|
|
|
|
|
|
|
|
return additionalConfigRE.test(path)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function gatherAdditionalConfig(
|
|
|
|
|
|
|
|
root: string,
|
|
|
|
|
|
|
|
command: 'serve' | 'build',
|
|
|
|
|
|
|
|
mode: string,
|
|
|
|
|
|
|
|
srcDir: string = '.',
|
|
|
|
|
|
|
|
srcExclude: string[] = []
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const candidates = await glob(additionalConfigGlob, {
|
|
|
|
|
|
|
|
cwd: path.resolve(root, srcDir),
|
|
|
|
|
|
|
|
dot: false, // conveniently ignores .vitepress/*
|
|
|
|
|
|
|
|
ignore: ['**/node_modules/**', ...srcExclude],
|
|
|
|
|
|
|
|
expandDirectories: false
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const deps: string[][] = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const exports = await Promise.all(
|
|
|
|
|
|
|
|
candidates.map(async (file) => {
|
|
|
|
|
|
|
|
const id = normalizePath(`/${path.dirname(file)}/`)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const configExports = await loadConfigFromFile(
|
|
|
|
|
|
|
|
{ command, mode },
|
|
|
|
|
|
|
|
normalizePath(path.resolve(root, srcDir, file)),
|
|
|
|
|
|
|
|
root
|
|
|
|
|
|
|
|
).catch(console.error) // Skip additionalConfig file if it fails to load
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!configExports) {
|
|
|
|
|
|
|
|
debug(`Failed to load additional config from ${file}`)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
deps.push(
|
|
|
|
|
|
|
|
configExports.dependencies.map((file) =>
|
|
|
|
|
|
|
|
normalizePath(path.resolve(file))
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mode === 'development') {
|
|
|
|
|
|
|
|
;(configExports.config as any)[VP_SOURCE_KEY] = '/' + slash(file)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [id, configExports.config as AdditionalConfig] as const
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [Object.fromEntries(exports.filter((e) => e != null)), deps] as const
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function resolveUserConfig(
|
|
|
|
export async function resolveUserConfig(
|
|
|
|
root: string,
|
|
|
|
root: string,
|
|
|
@ -170,6 +256,18 @@ export async function resolveUserConfig(
|
|
|
|
configDeps = configExports.dependencies.map((file) =>
|
|
|
|
configDeps = configExports.dependencies.map((file) =>
|
|
|
|
normalizePath(path.resolve(file))
|
|
|
|
normalizePath(path.resolve(file))
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
// Auto-generate additional config if user leaves it unspecified
|
|
|
|
|
|
|
|
if (userConfig.additionalConfig === undefined) {
|
|
|
|
|
|
|
|
const [additionalConfig, additionalDeps] = await gatherAdditionalConfig(
|
|
|
|
|
|
|
|
root,
|
|
|
|
|
|
|
|
command,
|
|
|
|
|
|
|
|
mode,
|
|
|
|
|
|
|
|
userConfig.srcDir,
|
|
|
|
|
|
|
|
userConfig.srcExclude
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
userConfig.additionalConfig = additionalConfig
|
|
|
|
|
|
|
|
configDeps = configDeps.concat(...additionalDeps)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
debug(`loaded config at ${c.yellow(configPath)}`)
|
|
|
|
debug(`loaded config at ${c.yellow(configPath)}`)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -213,10 +311,6 @@ export function mergeConfig(a: UserConfig, b: UserConfig, isRoot = true) {
|
|
|
|
return merged
|
|
|
|
return merged
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function isObject(value: unknown): value is Record<string, any> {
|
|
|
|
|
|
|
|
return Object.prototype.toString.call(value) === '[object Object]'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function resolveSiteData(
|
|
|
|
export async function resolveSiteData(
|
|
|
|
root: string,
|
|
|
|
root: string,
|
|
|
|
userConfig?: UserConfig,
|
|
|
|
userConfig?: UserConfig,
|
|
|
@ -241,7 +335,8 @@ export async function resolveSiteData(
|
|
|
|
locales: userConfig.locales || {},
|
|
|
|
locales: userConfig.locales || {},
|
|
|
|
scrollOffset: userConfig.scrollOffset ?? 134,
|
|
|
|
scrollOffset: userConfig.scrollOffset ?? 134,
|
|
|
|
cleanUrls: !!userConfig.cleanUrls,
|
|
|
|
cleanUrls: !!userConfig.cleanUrls,
|
|
|
|
contentProps: userConfig.contentProps
|
|
|
|
contentProps: userConfig.contentProps,
|
|
|
|
|
|
|
|
additionalConfig: userConfig.additionalConfig
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|