Skip to content

Commit 87d309c

Browse files
authored
refactor: resolve circular dependency (#2283)
1 parent f3d3332 commit 87d309c

File tree

4 files changed

+253
-226
lines changed

4 files changed

+253
-226
lines changed

src/node/config.ts

Lines changed: 11 additions & 224 deletions
Original file line numberDiff line numberDiff line change
@@ -1,214 +1,31 @@
1-
import type { Options as VuePluginOptions } from '@vitejs/plugin-vue'
21
import _debug from 'debug'
3-
import fg from 'fast-glob'
42
import fs from 'fs-extra'
53
import path from 'path'
64
import c from 'picocolors'
75
import {
86
createLogger,
97
loadConfigFromFile,
108
mergeConfig as mergeViteConfig,
11-
normalizePath,
12-
type Logger,
13-
type UserConfig as ViteConfig
9+
normalizePath
1410
} from 'vite'
1511
import { DEFAULT_THEME_PATH } from './alias'
16-
import type { MarkdownOptions } from './markdown/markdown'
17-
import {
18-
dynamicRouteRE,
19-
resolveDynamicRoutes,
20-
type ResolvedRouteConfig
21-
} from './plugins/dynamicRoutesPlugin'
22-
import { resolveRewrites } from './plugins/rewritesPlugin'
12+
import { resolvePages } from './plugins/dynamicRoutesPlugin'
2313
import {
2414
APPEARANCE_KEY,
25-
type Awaitable,
2615
type DefaultTheme,
2716
type HeadConfig,
28-
type LocaleConfig,
29-
type LocaleSpecificConfig,
30-
type PageData,
31-
type SiteData,
32-
type SSGContext
17+
type SiteData
3318
} from './shared'
19+
import {
20+
type UserConfig,
21+
type RawConfigExports,
22+
type SiteConfig
23+
} from './siteConfig'
3424

35-
const debug = _debug('vitepress:config')
36-
37-
export interface UserConfig<ThemeConfig = any>
38-
extends LocaleSpecificConfig<ThemeConfig> {
39-
extends?: RawConfigExports<ThemeConfig>
40-
41-
base?: string
42-
srcDir?: string
43-
srcExclude?: string[]
44-
outDir?: string
45-
cacheDir?: string
46-
47-
shouldPreload?: (link: string, page: string) => boolean
48-
49-
locales?: LocaleConfig<ThemeConfig>
50-
51-
appearance?: boolean | 'dark'
52-
lastUpdated?: boolean
53-
54-
/**
55-
* MarkdownIt options
56-
*/
57-
markdown?: MarkdownOptions
58-
/**
59-
* Options to pass on to `@vitejs/plugin-vue`
60-
*/
61-
vue?: VuePluginOptions
62-
/**
63-
* Vite config
64-
*/
65-
vite?: ViteConfig
66-
67-
/**
68-
* Configure the scroll offset when the theme has a sticky header.
69-
* Can be a number or a selector element to get the offset from.
70-
* Can also be an array of selectors in case some elements will be
71-
* invisible due to responsive layout. VitePress will fallback to the next
72-
* selector if a selector fails to match, or the matched element is not
73-
* currently visible in viewport.
74-
*/
75-
scrollOffset?: number | string | string[]
76-
77-
/**
78-
* Enable MPA / zero-JS mode.
79-
* @experimental
80-
*/
81-
mpa?: boolean
82-
83-
/**
84-
* Don't fail builds due to dead links.
85-
*
86-
* @default false
87-
*/
88-
ignoreDeadLinks?:
89-
| boolean
90-
| 'localhostLinks'
91-
| (string | RegExp | ((link: string) => boolean))[]
92-
93-
/**
94-
* Don't force `.html` on URLs.
95-
*
96-
* @default false
97-
*/
98-
cleanUrls?: boolean
99-
100-
/**
101-
* Use web fonts instead of emitting font files to dist.
102-
* The used theme should import a file named `fonts.(s)css` for this to work.
103-
* If you are a theme author, to support this, place your web font import
104-
* between `webfont-marker-begin` and `webfont-marker-end` comments.
105-
*
106-
* @default true in webcontainers, else false
107-
*/
108-
useWebFonts?: boolean
109-
110-
/**
111-
* @experimental
112-
*
113-
* source -> destination
114-
*/
115-
rewrites?: Record<string, string>
116-
117-
/**
118-
* Build end hook: called when SSG finish.
119-
* @param siteConfig The resolved configuration.
120-
*/
121-
buildEnd?: (siteConfig: SiteConfig) => Awaitable<void>
122-
123-
/**
124-
* Render end hook: called when SSR rendering is done.
125-
*/
126-
postRender?: (context: SSGContext) => Awaitable<SSGContext | void>
127-
128-
/**
129-
* Head transform hook: runs before writing HTML to dist.
130-
*
131-
* This build hook will allow you to modify the head adding new entries that cannot be statically added.
132-
*/
133-
transformHead?: (context: TransformContext) => Awaitable<HeadConfig[] | void>
134-
135-
/**
136-
* HTML transform hook: runs before writing HTML to dist.
137-
*/
138-
transformHtml?: (
139-
code: string,
140-
id: string,
141-
ctx: TransformContext
142-
) => Awaitable<string | void>
143-
144-
/**
145-
* PageData transform hook: runs when rendering markdown to vue
146-
*/
147-
transformPageData?: (
148-
pageData: PageData,
149-
ctx: TransformPageContext
150-
) => Awaitable<Partial<PageData> | { [key: string]: any } | void>
151-
}
152-
153-
export interface TransformPageContext {
154-
siteConfig: SiteConfig
155-
}
156-
157-
export interface TransformContext {
158-
page: string
159-
siteConfig: SiteConfig
160-
siteData: SiteData
161-
pageData: PageData
162-
title: string
163-
description: string
164-
head: HeadConfig[]
165-
content: string
166-
assets: string[]
167-
}
168-
169-
export type RawConfigExports<ThemeConfig = any> =
170-
| Awaitable<UserConfig<ThemeConfig>>
171-
| (() => Awaitable<UserConfig<ThemeConfig>>)
25+
export * from './siteConfig'
26+
export { resolvePages } from './plugins/dynamicRoutesPlugin'
17227

173-
export interface SiteConfig<ThemeConfig = any>
174-
extends Pick<
175-
UserConfig,
176-
| 'markdown'
177-
| 'vue'
178-
| 'vite'
179-
| 'shouldPreload'
180-
| 'mpa'
181-
| 'lastUpdated'
182-
| 'ignoreDeadLinks'
183-
| 'cleanUrls'
184-
| 'useWebFonts'
185-
| 'postRender'
186-
| 'buildEnd'
187-
| 'transformHead'
188-
| 'transformHtml'
189-
| 'transformPageData'
190-
> {
191-
root: string
192-
srcDir: string
193-
site: SiteData<ThemeConfig>
194-
configPath: string | undefined
195-
configDeps: string[]
196-
themeDir: string
197-
outDir: string
198-
cacheDir: string
199-
tempDir: string
200-
pages: string[]
201-
dynamicRoutes: {
202-
routes: ResolvedRouteConfig[]
203-
fileToModulesMap: Record<string, Set<string>>
204-
}
205-
rewrites: {
206-
map: Record<string, string | undefined>
207-
inv: Record<string, string | undefined>
208-
}
209-
logger: Logger
210-
userConfig: UserConfig
211-
}
28+
const debug = _debug('vitepress:config')
21229

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

439256
return head
440257
}
441-
442-
export async function resolvePages(srcDir: string, userConfig: UserConfig) {
443-
// Important: fast-glob doesn't guarantee order of the returned files.
444-
// We must sort the pages so the input list to rollup is stable across
445-
// builds - otherwise different input order could result in different exports
446-
// order in shared chunks which in turns invalidates the hash of every chunk!
447-
// JavaScript built-in sort() is mandated to be stable as of ES2019 and
448-
// supported in Node 12+, which is required by Vite.
449-
const allMarkdownFiles = (
450-
await fg(['**.md'], {
451-
cwd: srcDir,
452-
ignore: ['**/node_modules', ...(userConfig.srcExclude || [])]
453-
})
454-
).sort()
455-
456-
const pages = allMarkdownFiles.filter((p) => !dynamicRouteRE.test(p))
457-
const dynamicRouteFiles = allMarkdownFiles.filter((p) =>
458-
dynamicRouteRE.test(p)
459-
)
460-
const dynamicRoutes = await resolveDynamicRoutes(srcDir, dynamicRouteFiles)
461-
pages.push(...dynamicRoutes.routes.map((r) => r.path))
462-
463-
const rewrites = resolveRewrites(pages, userConfig.rewrites)
464-
465-
return {
466-
pages,
467-
dynamicRoutes,
468-
rewrites
469-
}
470-
}

src/node/plugins/dynamicRoutesPlugin.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,42 @@ import {
77
import fs from 'fs-extra'
88
import c from 'picocolors'
99
import path from 'path'
10-
import { resolvePages, type SiteConfig } from '../config'
10+
import fg from 'fast-glob'
11+
import { type SiteConfig, type UserConfig } from '../siteConfig'
12+
import { resolveRewrites } from './rewritesPlugin'
1113

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

16+
export async function resolvePages(srcDir: string, userConfig: UserConfig) {
17+
// Important: fast-glob doesn't guarantee order of the returned files.
18+
// We must sort the pages so the input list to rollup is stable across
19+
// builds - otherwise different input order could result in different exports
20+
// order in shared chunks which in turns invalidates the hash of every chunk!
21+
// JavaScript built-in sort() is mandated to be stable as of ES2019 and
22+
// supported in Node 12+, which is required by Vite.
23+
const allMarkdownFiles = (
24+
await fg(['**.md'], {
25+
cwd: srcDir,
26+
ignore: ['**/node_modules', ...(userConfig.srcExclude || [])]
27+
})
28+
).sort()
29+
30+
const pages = allMarkdownFiles.filter((p) => !dynamicRouteRE.test(p))
31+
const dynamicRouteFiles = allMarkdownFiles.filter((p) =>
32+
dynamicRouteRE.test(p)
33+
)
34+
const dynamicRoutes = await resolveDynamicRoutes(srcDir, dynamicRouteFiles)
35+
pages.push(...dynamicRoutes.routes.map((r) => r.path))
36+
37+
const rewrites = resolveRewrites(pages, userConfig.rewrites)
38+
39+
return {
40+
pages,
41+
dynamicRoutes,
42+
rewrites
43+
}
44+
}
45+
1446
interface UserRouteConfig {
1547
params: Record<string, string>
1648
content?: string

src/node/plugins/rewritesPlugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Plugin } from 'vite'
22
import { compile, match } from 'path-to-regexp'
3-
import type { SiteConfig, UserConfig } from '../config'
3+
import type { SiteConfig, UserConfig } from '../siteConfig'
44

55
export function resolveRewrites(
66
pages: string[],

0 commit comments

Comments
 (0)