diff --git a/.eslintrc b/.eslintrc index 497f082..7663fbf 100644 --- a/.eslintrc +++ b/.eslintrc @@ -22,7 +22,7 @@ ], "rules": { "prettier/prettier": [ - "error", + "warn", { "singleQuote": true, "semi": false, diff --git a/e2e/playground/basic/docs/rpress.config.ts b/e2e/playground/basic/docs/rpress.config.ts new file mode 100644 index 0000000..232e362 --- /dev/null +++ b/e2e/playground/basic/docs/rpress.config.ts @@ -0,0 +1,5 @@ +import { defineConfig } from 'r-press/dist' +export default defineConfig({ + title: 'RPress', + description: 'RPress Playground', +}) diff --git a/e2e/playground/basic/package.json b/e2e/playground/basic/package.json index eb72c85..8f85bbf 100644 --- a/e2e/playground/basic/package.json +++ b/e2e/playground/basic/package.json @@ -1,5 +1,6 @@ { "name": "basic", + "type": "module", "scripts": { "dev": "r-press dev docs", "build": "r-press build docs" diff --git a/src/node/cli.ts b/src/node/cli.ts index 9dd2dcc..eab2410 100644 --- a/src/node/cli.ts +++ b/src/node/cli.ts @@ -3,6 +3,7 @@ import { createDevServer } from './dev' import { build } from './build' import { version } from '../../package.json' +import { resolveConfig } from './config' const cli = cac('r-press').version(version).help() @@ -10,6 +11,7 @@ cli .command('[root]', 'start dev server') .alias('dev') .action(async (root: string) => { + await resolveConfig(root, 'serve', 'development') const server = await createDevServer(root) await server.listen() server.printUrls() @@ -18,6 +20,7 @@ cli cli .command('build [root]', 'build for production') .action(async (root: string) => { + await resolveConfig(root, 'build', 'production') await build(root) }) diff --git a/src/node/config.ts b/src/node/config.ts new file mode 100644 index 0000000..9a5c67e --- /dev/null +++ b/src/node/config.ts @@ -0,0 +1,73 @@ +import path from 'path' +import fs from 'fs-extra' +import { loadConfigFromFile } from 'vite' +import type { SiteConfig, UserConfig } from '../shared/types' + +type RawUserConfig = + | UserConfig + | Promise + | (() => UserConfig | Promise) + +export async function resolveConfig( + root: string, + command: 'serve' | 'build', + mode: 'development' | 'production' +): Promise { + const [configPath, userConfig] = await resolveUserConfig(root, command, mode) + const siteConfig: SiteConfig = { + root, + configPath: configPath, + siteData: resolveSiteData(userConfig as UserConfig), + } + console.log(siteConfig, 'siteConfig') + return siteConfig +} + +export async function resolveUserConfig( + root: string, + command: 'serve' | 'build', + mode: 'development' | 'production' +) { + // 1. 获取配置路径 支持js 和 ts 格式 + const configPath = getUserConfigPath(root) + // 2.解析配置文件 + const { config: rawConfig = {} as RawUserConfig } = await loadConfigFromFile( + { + command, + mode, + }, + configPath, + root + ) + if (rawConfig) { + const config = + typeof rawConfig === 'function' ? await rawConfig() : rawConfig + return [configPath, config] as const + } + return [configPath, {} as UserConfig] as const +} + +export function resolveSiteData(userConfig: UserConfig): UserConfig { + return { + title: userConfig.title || 'Rpress.js', + description: userConfig.description || 'SSG Framework', + themeConfig: userConfig.themeConfig || {}, + vite: userConfig.vite || {}, + } +} + +function getUserConfigPath(root: string) { + const configFileNames = ['rpress.config.ts', 'rpress.config.js'] + try { + const configPath = configFileNames + .map((name) => path.resolve(root, name)) + .find(fs.pathExistsSync) + return configPath + } catch (e) { + console.error('Failed to load config file.', e) + throw e + } +} +export function defineConfig(config: UserConfig): UserConfig { + return config +} diff --git a/src/node/index.ts b/src/node/index.ts new file mode 100644 index 0000000..0f82c41 --- /dev/null +++ b/src/node/index.ts @@ -0,0 +1 @@ +export { defineConfig } from './config' diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts new file mode 100644 index 0000000..98a6f7c --- /dev/null +++ b/src/shared/types/index.ts @@ -0,0 +1,42 @@ +import type { UserConfig as ViteUserConfig } from 'vite' + +// 用户配置的超集 +export interface SiteConfig { + root: string + configPath: string + siteData: UserConfig +} + +export interface UserConfig { + title?: string + description?: string + themeConfig?: ThemeConfig + vite?: ViteUserConfig +} + +// 主题配置:导航栏 侧边栏 +export interface ThemeConfig { + nav?: NavItemWithLink[] + sidebar?: Sidebar + footer?: Footer +} + +type NavItemWithLink = { + text: string + link: string +} +export interface Sidebar { + [path: string]: SidebarGroup[] +} +export interface Footer { + message: string +} + +export interface SidebarGroup { + text: string + items: SidebarItem[] +} +type SidebarItem = { + text: string + link: string +} diff --git a/tsup.config.ts b/tsup.config.ts index fd8a7de..ef0c80c 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from 'tsup' export default defineConfig({ - entryPoints: ['src/node/cli.ts'], + entryPoints: ['src/node/cli.ts', 'src/node/index.ts'], bundle: true, splitting: true, outDir: 'dist',