Skip to content

Commit

Permalink
refactor: resolve circular dependency (#2283)
Browse files Browse the repository at this point in the history
  • Loading branch information
btea authored Apr 24, 2023
1 parent f3d3332 commit 87d309c
Show file tree
Hide file tree
Showing 4 changed files with 253 additions and 226 deletions.
235 changes: 11 additions & 224 deletions src/node/config.ts
Original file line number Diff line number Diff line change
@@ -1,214 +1,31 @@
import type { Options as VuePluginOptions } from '@vitejs/plugin-vue'
import _debug from 'debug'
import fg from 'fast-glob'
import fs from 'fs-extra'
import path from 'path'
import c from 'picocolors'
import {
createLogger,
loadConfigFromFile,
mergeConfig as mergeViteConfig,
normalizePath,
type Logger,
type UserConfig as ViteConfig
normalizePath
} from 'vite'
import { DEFAULT_THEME_PATH } from './alias'
import type { MarkdownOptions } from './markdown/markdown'
import {
dynamicRouteRE,
resolveDynamicRoutes,
type ResolvedRouteConfig
} from './plugins/dynamicRoutesPlugin'
import { resolveRewrites } from './plugins/rewritesPlugin'
import { resolvePages } from './plugins/dynamicRoutesPlugin'
import {
APPEARANCE_KEY,
type Awaitable,
type DefaultTheme,
type HeadConfig,
type LocaleConfig,
type LocaleSpecificConfig,
type PageData,
type SiteData,
type SSGContext
type SiteData
} from './shared'
import {
type UserConfig,
type RawConfigExports,
type SiteConfig
} from './siteConfig'

const debug = _debug('vitepress:config')

export interface UserConfig<ThemeConfig = any>
extends LocaleSpecificConfig<ThemeConfig> {
extends?: RawConfigExports<ThemeConfig>

base?: string
srcDir?: string
srcExclude?: string[]
outDir?: string
cacheDir?: string

shouldPreload?: (link: string, page: string) => boolean

locales?: LocaleConfig<ThemeConfig>

appearance?: boolean | 'dark'
lastUpdated?: boolean

/**
* MarkdownIt options
*/
markdown?: MarkdownOptions
/**
* Options to pass on to `@vitejs/plugin-vue`
*/
vue?: VuePluginOptions
/**
* Vite config
*/
vite?: ViteConfig

/**
* Configure the scroll offset when the theme has a sticky header.
* Can be a number or a selector element to get the offset from.
* Can also be an array of selectors in case some elements will be
* invisible due to responsive layout. VitePress will fallback to the next
* selector if a selector fails to match, or the matched element is not
* currently visible in viewport.
*/
scrollOffset?: number | string | string[]

/**
* Enable MPA / zero-JS mode.
* @experimental
*/
mpa?: boolean

/**
* Don't fail builds due to dead links.
*
* @default false
*/
ignoreDeadLinks?:
| boolean
| 'localhostLinks'
| (string | RegExp | ((link: string) => boolean))[]

/**
* Don't force `.html` on URLs.
*
* @default false
*/
cleanUrls?: boolean

/**
* Use web fonts instead of emitting font files to dist.
* The used theme should import a file named `fonts.(s)css` for this to work.
* If you are a theme author, to support this, place your web font import
* between `webfont-marker-begin` and `webfont-marker-end` comments.
*
* @default true in webcontainers, else false
*/
useWebFonts?: boolean

/**
* @experimental
*
* source -> destination
*/
rewrites?: Record<string, string>

/**
* Build end hook: called when SSG finish.
* @param siteConfig The resolved configuration.
*/
buildEnd?: (siteConfig: SiteConfig) => Awaitable<void>

/**
* Render end hook: called when SSR rendering is done.
*/
postRender?: (context: SSGContext) => Awaitable<SSGContext | void>

/**
* Head transform hook: runs before writing HTML to dist.
*
* This build hook will allow you to modify the head adding new entries that cannot be statically added.
*/
transformHead?: (context: TransformContext) => Awaitable<HeadConfig[] | void>

/**
* HTML transform hook: runs before writing HTML to dist.
*/
transformHtml?: (
code: string,
id: string,
ctx: TransformContext
) => Awaitable<string | void>

/**
* PageData transform hook: runs when rendering markdown to vue
*/
transformPageData?: (
pageData: PageData,
ctx: TransformPageContext
) => Awaitable<Partial<PageData> | { [key: string]: any } | void>
}

export interface TransformPageContext {
siteConfig: SiteConfig
}

export interface TransformContext {
page: string
siteConfig: SiteConfig
siteData: SiteData
pageData: PageData
title: string
description: string
head: HeadConfig[]
content: string
assets: string[]
}

export type RawConfigExports<ThemeConfig = any> =
| Awaitable<UserConfig<ThemeConfig>>
| (() => Awaitable<UserConfig<ThemeConfig>>)
export * from './siteConfig'
export { resolvePages } from './plugins/dynamicRoutesPlugin'

export interface SiteConfig<ThemeConfig = any>
extends Pick<
UserConfig,
| 'markdown'
| 'vue'
| 'vite'
| 'shouldPreload'
| 'mpa'
| 'lastUpdated'
| 'ignoreDeadLinks'
| 'cleanUrls'
| 'useWebFonts'
| 'postRender'
| 'buildEnd'
| 'transformHead'
| 'transformHtml'
| 'transformPageData'
> {
root: string
srcDir: string
site: SiteData<ThemeConfig>
configPath: string | undefined
configDeps: string[]
themeDir: string
outDir: string
cacheDir: string
tempDir: string
pages: string[]
dynamicRoutes: {
routes: ResolvedRouteConfig[]
fileToModulesMap: Record<string, Set<string>>
}
rewrites: {
map: Record<string, string | undefined>
inv: Record<string, string | undefined>
}
logger: Logger
userConfig: UserConfig
}
const debug = _debug('vitepress:config')

const resolve = (root: string, file: string) =>
normalizePath(path.resolve(root, `.vitepress`, file))
Expand Down Expand Up @@ -438,33 +255,3 @@ function resolveSiteDataHead(userConfig?: UserConfig): HeadConfig[] {

return head
}

export async function resolvePages(srcDir: string, userConfig: UserConfig) {
// Important: fast-glob doesn't guarantee order of the returned files.
// 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 fg(['**.md'], {
cwd: srcDir,
ignore: ['**/node_modules', ...(userConfig.srcExclude || [])]
})
).sort()

const pages = allMarkdownFiles.filter((p) => !dynamicRouteRE.test(p))
const dynamicRouteFiles = allMarkdownFiles.filter((p) =>
dynamicRouteRE.test(p)
)
const dynamicRoutes = await resolveDynamicRoutes(srcDir, dynamicRouteFiles)
pages.push(...dynamicRoutes.routes.map((r) => r.path))

const rewrites = resolveRewrites(pages, userConfig.rewrites)

return {
pages,
dynamicRoutes,
rewrites
}
}
34 changes: 33 additions & 1 deletion src/node/plugins/dynamicRoutesPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,42 @@ import {
import fs from 'fs-extra'
import c from 'picocolors'
import path from 'path'
import { resolvePages, type SiteConfig } from '../config'
import fg from 'fast-glob'
import { type SiteConfig, type UserConfig } from '../siteConfig'
import { resolveRewrites } from './rewritesPlugin'

export const dynamicRouteRE = /\[(\w+?)\]/g

export async function resolvePages(srcDir: string, userConfig: UserConfig) {
// Important: fast-glob doesn't guarantee order of the returned files.
// 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 fg(['**.md'], {
cwd: srcDir,
ignore: ['**/node_modules', ...(userConfig.srcExclude || [])]
})
).sort()

const pages = allMarkdownFiles.filter((p) => !dynamicRouteRE.test(p))
const dynamicRouteFiles = allMarkdownFiles.filter((p) =>
dynamicRouteRE.test(p)
)
const dynamicRoutes = await resolveDynamicRoutes(srcDir, dynamicRouteFiles)
pages.push(...dynamicRoutes.routes.map((r) => r.path))

const rewrites = resolveRewrites(pages, userConfig.rewrites)

return {
pages,
dynamicRoutes,
rewrites
}
}

interface UserRouteConfig {
params: Record<string, string>
content?: string
Expand Down
2 changes: 1 addition & 1 deletion src/node/plugins/rewritesPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Plugin } from 'vite'
import { compile, match } from 'path-to-regexp'
import type { SiteConfig, UserConfig } from '../config'
import type { SiteConfig, UserConfig } from '../siteConfig'

export function resolveRewrites(
pages: string[],
Expand Down
Loading

0 comments on commit 87d309c

Please sign in to comment.