refactor(build): use async fs in build entry

Replace the remaining sync writes and the tempDir removal in
build()/generateMetadataScript() with fs/promises, and switch
linkVue to the async packageDirectory lookup with an async unlink.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pull/5342/head
Divyansh Singh 1 month ago
parent d963e6ce0e
commit 479b984a27

@ -1,10 +1,11 @@
import { getIconsCSS } from '@iconify/utils' import { getIconsCSS } from '@iconify/utils'
import { createHash } from 'node:crypto' import { createHash } from 'node:crypto'
import fs from 'node:fs' import fs from 'node:fs'
import { mkdir, rm, symlink, unlink, writeFile } from 'node:fs/promises'
import { createRequire } from 'node:module' import { createRequire } from 'node:module'
import path from 'node:path' import path from 'node:path'
import pMap from 'p-map' import pMap from 'p-map'
import { packageDirectorySync } from 'package-directory' import { packageDirectory } from 'package-directory'
import type { BuildOptions, Rolldown } from 'vite' import type { BuildOptions, Rolldown } from 'vite'
import { resolveConfig, type SiteConfig } from '../config' import { resolveConfig, type SiteConfig } from '../config'
import { clearCache } from '../markdownToVue' import { clearCache } from '../markdownToVue'
@ -35,7 +36,7 @@ export async function build(
await buildOptions.onAfterConfigResolve?.(siteConfig) await buildOptions.onAfterConfigResolve?.(siteConfig)
delete buildOptions.onAfterConfigResolve delete buildOptions.onAfterConfigResolve
const unlinkVue = linkVue() const unlinkVue = await linkVue()
if (buildOptions.base) { if (buildOptions.base) {
siteConfig.site.base = buildOptions.base siteConfig.site.base = buildOptions.base
@ -105,7 +106,10 @@ export async function build(
// ---- // ----
const additionalHeadTags: HeadConfig[] = [] const additionalHeadTags: HeadConfig[] = []
const metadataScript = generateMetadataScript(pageToHashMap, siteConfig) const metadataScript = await generateMetadataScript(
pageToHashMap,
siteConfig
)
if (isDefaultTheme) { if (isDefaultTheme) {
const fontURL = assets.find((file) => const fontURL = assets.find((file) =>
@ -156,19 +160,19 @@ export async function build(
mode: 'mask' mode: 'mask'
}).replace(/[^]*?}\n*/, '') }).replace(/[^]*?}\n*/, '')
fs.writeFileSync(path.join(siteConfig.outDir, 'vp-icons.css'), iconsCss) await writeFile(path.join(siteConfig.outDir, 'vp-icons.css'), iconsCss)
}) })
// emit page hash map for the case where a user session is open // emit page hash map for the case where a user session is open
// when the site got redeployed (which invalidates current hash map) // when the site got redeployed (which invalidates current hash map)
fs.writeFileSync( await writeFile(
path.join(siteConfig.outDir, 'hashmap.json'), path.join(siteConfig.outDir, 'hashmap.json'),
JSON.stringify(pageToHashMap) JSON.stringify(pageToHashMap)
) )
} finally { } finally {
unlinkVue() await unlinkVue()
if (!process.env.DEBUG) { if (!process.env.DEBUG) {
fs.rmSync(siteConfig.tempDir, { await rm(siteConfig.tempDir, {
recursive: true, recursive: true,
force: true, force: true,
maxRetries: 10 maxRetries: 10
@ -185,27 +189,25 @@ export async function build(
) )
} }
function linkVue() { async function linkVue() {
const root = packageDirectorySync() const root = await packageDirectory()
if (root) { if (root) {
const dest = path.resolve(root, 'node_modules/vue') const dest = path.resolve(root, 'node_modules/vue')
// if user did not install vue by themselves, link VitePress' version // if user did not install vue by themselves, link VitePress' version
if (!fs.existsSync(dest)) { if (!fs.existsSync(dest)) {
const src = path.dirname(createRequire(import.meta.url).resolve('vue')) const src = path.dirname(createRequire(import.meta.url).resolve('vue'))
fs.mkdirSync(path.dirname(dest), { recursive: true }) await mkdir(path.dirname(dest), { recursive: true })
fs.symlinkSync(src, dest, 'junction') await symlink(src, dest, 'junction')
return () => { return () => unlink(dest)
fs.unlinkSync(dest)
} }
} }
} return async () => {}
return () => {}
} }
function generateMetadataScript( async function generateMetadataScript(
pageToHashMap: Record<string, string>, pageToHashMap: Record<string, string>,
config: SiteConfig config: SiteConfig
) { ): Promise<{ html: string; inHead: boolean }> {
if (config.mpa) { if (config.mpa) {
return { html: '', inHead: false } return { html: '', inHead: false }
} }
@ -237,8 +239,8 @@ function generateMetadataScript(
const resolvedMetadataFile = path.join(config.outDir, metadataFile) const resolvedMetadataFile = path.join(config.outDir, metadataFile)
const metadataFileURL = slash(`${config.site.base}${metadataFile}`) const metadataFileURL = slash(`${config.site.base}${metadataFile}`)
fs.mkdirSync(path.dirname(resolvedMetadataFile), { recursive: true }) await mkdir(path.dirname(resolvedMetadataFile), { recursive: true })
fs.writeFileSync(resolvedMetadataFile, metadataContent) await writeFile(resolvedMetadataFile, metadataContent)
return { return {
html: `<script type="module" src="${metadataFileURL}"></script>`, html: `<script type="module" src="${metadataFileURL}"></script>`,

Loading…
Cancel
Save