diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.ts similarity index 99% rename from docs/.vitepress/config.js rename to docs/.vitepress/config.ts index b1db23935bd7..b680ece55161 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.ts @@ -1,4 +1,4 @@ -module.exports = { +export default { lang: 'en-US', title: 'VitePress', description: 'Vite & Vue powered static site generator.', diff --git a/src/node/build/build.ts b/src/node/build/build.ts index a8934b1e08fd..7ed05aeaef8e 100644 --- a/src/node/build/build.ts +++ b/src/node/build/build.ts @@ -13,7 +13,7 @@ export async function build( const start = Date.now() process.env.NODE_ENV = 'production' - const siteConfig = await resolveConfig(root) + const siteConfig = await resolveConfig(root, 'build', 'production') if (buildOptions.mpa) { siteConfig.mpa = true diff --git a/src/node/config.ts b/src/node/config.ts index d48e0ddc1df5..4fdc21171a71 100644 --- a/src/node/config.ts +++ b/src/node/config.ts @@ -6,7 +6,8 @@ import { normalizePath, AliasOptions, UserConfig as ViteConfig, - mergeConfig as mergeViteConfig + mergeConfig as mergeViteConfig, + loadConfigFromFile } from 'vite' import { Options as VuePluginOptions } from '@vitejs/plugin-vue' import { @@ -63,7 +64,7 @@ export interface SiteConfig { root: string srcDir: string site: SiteData - configPath: string + configPath: string | undefined themeDir: string outDir: string tempDir: string @@ -78,10 +79,19 @@ export interface SiteConfig { const resolve = (root: string, file: string) => normalizePath(path.resolve(root, `.vitepress`, file)) +/** + * Type config helper + */ +export function defineConfig(config: RawConfigExports) { + return config +} + export async function resolveConfig( - root: string = process.cwd() + root: string = process.cwd(), + command: 'serve' | 'build' = 'serve', + mode = 'development' ): Promise { - const userConfig = await resolveUserConfig(root) + const [userConfig, configPath] = await resolveUserConfig(root, command, mode) const site = await resolveSiteData(root, userConfig) const srcDir = path.resolve(root, userConfig.srcDir || '.') @@ -110,7 +120,7 @@ export async function resolveConfig( site, themeDir, pages, - configPath: resolve(root, 'config.js'), + configPath, outDir: resolve(root, 'dist'), tempDir: path.resolve(APP_PATH, 'temp'), markdown: userConfig.markdown, @@ -123,19 +133,43 @@ export async function resolveConfig( return config } -export async function resolveUserConfig(root: string): Promise { +const supportedConfigExtensions = ['js', 'ts', '.mjs', 'mts'] + +async function resolveUserConfig( + root: string, + command: 'serve' | 'build', + mode: string +): Promise<[UserConfig, string | undefined]> { // load user config - const configPath = resolve(root, 'config.js') - const hasUserConfig = await fs.pathExists(configPath) - // always delete cache first before loading config - delete require.cache[require.resolve(configPath)] - const userConfig: RawConfigExports = hasUserConfig ? require(configPath) : {} - if (hasUserConfig) { + let configPath + for (const ext of supportedConfigExtensions) { + const p = resolve(root, `config.${ext}`) + if (await fs.pathExists(p)) { + configPath = p + break + } + } + + const userConfig: RawConfigExports = configPath + ? (( + await loadConfigFromFile( + { + command, + mode + }, + configPath, + root + ) + )?.config as any) + : {} + + if (configPath) { debug(`loaded config at ${chalk.yellow(configPath)}`) } else { debug(`no config file found.`) } - return resolveConfigExtends(userConfig) + + return [await resolveConfigExtends(userConfig), configPath] } async function resolveConfigExtends( @@ -180,9 +214,11 @@ function isObject(value: unknown): value is Record { export async function resolveSiteData( root: string, - userConfig?: UserConfig + userConfig?: UserConfig, + command: 'serve' | 'build' = 'serve', + mode = 'development' ): Promise { - userConfig = userConfig || (await resolveUserConfig(root)) + userConfig = userConfig || (await resolveUserConfig(root, command, mode))[0] return { lang: userConfig.lang || 'en-US', title: userConfig.title || 'VitePress', diff --git a/src/node/plugin.ts b/src/node/plugin.ts index e3ce80ae9356..6f1751e72530 100644 --- a/src/node/plugin.ts +++ b/src/node/plugin.ts @@ -154,7 +154,9 @@ export function createVitePressPlugin( }, configureServer(server) { - server.watcher.add(configPath) + if (configPath) { + server.watcher.add(configPath) + } // serve our index.html after vite history fallback return () => { diff --git a/src/node/serve/serve.ts b/src/node/serve/serve.ts index 81b57c3af24c..fe84e965aea2 100644 --- a/src/node/serve/serve.ts +++ b/src/node/serve/serve.ts @@ -10,7 +10,7 @@ export interface ServeOptions { export async function serve(options: ServeOptions = {}) { const port = options.port !== undefined ? options.port : 5000 - const site = await resolveConfig(options.root) + const site = await resolveConfig(options.root, 'serve', 'production') const compress = compression() const serve = sirv(site.outDir, {