feat(build): use vite logger (#1899)

Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com>
pull/1931/head
CHOYSEN 2 years ago committed by GitHub
parent 2299b217b6
commit a00bb62143
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -106,7 +106,9 @@ export async function build(
await siteConfig.buildEnd?.(siteConfig) await siteConfig.buildEnd?.(siteConfig)
console.log(`build complete in ${((Date.now() - start) / 1000).toFixed(2)}s.`) siteConfig.logger.info(
`build complete in ${((Date.now() - start) / 1000).toFixed(2)}s.`
)
} }
function linkVue() { function linkVue() {

@ -1,11 +1,16 @@
import c from 'picocolors'
import minimist from 'minimist' import minimist from 'minimist'
import { createServer, build, serve } from '.' import c from 'picocolors'
import { createLogger } from 'vite'
import { build, createServer, serve } from '.'
import { version } from '../../package.json' import { version } from '../../package.json'
const argv: any = minimist(process.argv.slice(2)) const argv: any = minimist(process.argv.slice(2))
console.log(c.cyan(`vitepress v${version}`)) const logVersion = (logger = createLogger()) => {
logger.info(`\n ${c.green(`${c.bold('vitepress')} v${version}`)}\n`, {
clear: !logger.hasWarned
})
}
const command = argv._[0] const command = argv._[0]
const root = argv._[command ? 1 : 0] const root = argv._[command ? 1 : 0]
@ -20,24 +25,27 @@ if (!command || command === 'dev') {
await createDevServer() await createDevServer()
}) })
await server.listen() await server.listen()
console.log() logVersion(server.config.logger)
server.printUrls() server.printUrls()
} }
createDevServer().catch((err) => { createDevServer().catch((err) => {
console.error(c.red(`failed to start server. error:\n`), err) createLogger().error(c.red(`failed to start server. error:\n`), err)
process.exit(1) process.exit(1)
}) })
} else if (command === 'build') { } else {
logVersion()
if (command === 'build') {
build(root, argv).catch((err) => { build(root, argv).catch((err) => {
console.error(c.red(`build error:\n`), err) createLogger().error(c.red(`build error:\n`), err)
process.exit(1) process.exit(1)
}) })
} else if (command === 'serve' || command === 'preview') { } else if (command === 'serve' || command === 'preview') {
serve(argv).catch((err) => { serve(argv).catch((err) => {
console.error(c.red(`failed to start server. error:\n`), err) createLogger().error(c.red(`failed to start server. error:\n`), err)
process.exit(1) process.exit(1)
}) })
} else { } else {
console.log(c.red(`unknown command "${command}".`)) createLogger().error(c.red(`unknown command "${command}".`))
process.exit(1) process.exit(1)
}
} }

@ -3,12 +3,14 @@ import _debug from 'debug'
import fg from 'fast-glob' import fg from 'fast-glob'
import fs from 'fs-extra' import fs from 'fs-extra'
import path from 'path' import path from 'path'
import { match, compile } from 'path-to-regexp' import { compile, match } from 'path-to-regexp'
import c from 'picocolors' import c from 'picocolors'
import { import {
createLogger,
loadConfigFromFile, loadConfigFromFile,
mergeConfig as mergeViteConfig, mergeConfig as mergeViteConfig,
normalizePath, normalizePath,
type Logger,
type UserConfig as ViteConfig type UserConfig as ViteConfig
} from 'vite' } from 'vite'
import { DEFAULT_THEME_PATH } from './alias' import { DEFAULT_THEME_PATH } from './alias'
@ -180,6 +182,7 @@ export interface SiteConfig<ThemeConfig = any>
map: Record<string, string | undefined> map: Record<string, string | undefined>
inv: Record<string, string | undefined> inv: Record<string, string | undefined>
} }
logger: Logger
} }
const resolve = (root: string, file: string) => const resolve = (root: string, file: string) =>
@ -211,6 +214,13 @@ export async function resolveConfig(
command, command,
mode mode
) )
const logger =
userConfig.vite?.customLogger ??
createLogger(userConfig.vite?.logLevel, {
prefix: '[vitepress]',
allowClearScreen: userConfig.vite?.clearScreen
})
const site = await resolveSiteData(root, userConfig) const site = await resolveSiteData(root, userConfig)
const srcDir = path.resolve(root, userConfig.srcDir || '.') const srcDir = path.resolve(root, userConfig.srcDir || '.')
const outDir = userConfig.outDir const outDir = userConfig.outDir
@ -264,6 +274,7 @@ export async function resolveConfig(
configDeps, configDeps,
outDir, outDir,
cacheDir, cacheDir,
logger,
tempDir: resolve(root, '.temp'), tempDir: resolve(root, '.temp'),
markdown: userConfig.markdown, markdown: userConfig.markdown,
lastUpdated: userConfig.lastUpdated, lastUpdated: userConfig.lastUpdated,

@ -1,7 +1,3 @@
import MarkdownIt from 'markdown-it'
import anchorPlugin from 'markdown-it-anchor'
import attrsPlugin from 'markdown-it-attrs'
import emojiPlugin from 'markdown-it-emoji'
import { componentPlugin } from '@mdit-vue/plugin-component' import { componentPlugin } from '@mdit-vue/plugin-component'
import { import {
frontmatterPlugin, frontmatterPlugin,
@ -15,15 +11,20 @@ import { sfcPlugin, type SfcPluginOptions } from '@mdit-vue/plugin-sfc'
import { titlePlugin } from '@mdit-vue/plugin-title' import { titlePlugin } from '@mdit-vue/plugin-title'
import { tocPlugin, type TocPluginOptions } from '@mdit-vue/plugin-toc' import { tocPlugin, type TocPluginOptions } from '@mdit-vue/plugin-toc'
import { slugify } from '@mdit-vue/shared' import { slugify } from '@mdit-vue/shared'
import MarkdownIt from 'markdown-it'
import anchorPlugin from 'markdown-it-anchor'
import attrsPlugin from 'markdown-it-attrs'
import emojiPlugin from 'markdown-it-emoji'
import type { IThemeRegistration } from 'shiki' import type { IThemeRegistration } from 'shiki'
import type { Logger } from 'vite'
import { containerPlugin } from './plugins/containers'
import { highlight } from './plugins/highlight' import { highlight } from './plugins/highlight'
import { highlightLinePlugin } from './plugins/highlightLines' import { highlightLinePlugin } from './plugins/highlightLines'
import { imagePlugin } from './plugins/image'
import { lineNumberPlugin } from './plugins/lineNumbers' import { lineNumberPlugin } from './plugins/lineNumbers'
import { containerPlugin } from './plugins/containers'
import { snippetPlugin } from './plugins/snippet'
import { preWrapperPlugin } from './plugins/preWrapper'
import { linkPlugin } from './plugins/link' import { linkPlugin } from './plugins/link'
import { imagePlugin } from './plugins/image' import { preWrapperPlugin } from './plugins/preWrapper'
import { snippetPlugin } from './plugins/snippet'
export type { Header } from '../shared' export type { Header } from '../shared'
@ -55,14 +56,15 @@ export type MarkdownRenderer = MarkdownIt
export const createMarkdownRenderer = async ( export const createMarkdownRenderer = async (
srcDir: string, srcDir: string,
options: MarkdownOptions = {}, options: MarkdownOptions = {},
base = '/' base = '/',
logger: Pick<Logger, 'warn'> = console
): Promise<MarkdownRenderer> => { ): Promise<MarkdownRenderer> => {
const md = MarkdownIt({ const md = MarkdownIt({
html: true, html: true,
linkify: true, linkify: true,
highlight: highlight:
options.highlight || options.highlight ||
(await highlight(options.theme, options.defaultHighlightLang)), (await highlight(options.theme, options.defaultHighlightLang, logger)),
...options ...options
}) as MarkdownRenderer }) as MarkdownRenderer

@ -11,6 +11,7 @@ import {
getHighlighter, getHighlighter,
type Processor type Processor
} from 'shiki-processor' } from 'shiki-processor'
import type { Logger } from 'vite'
import type { ThemeOptions } from '../markdown' import type { ThemeOptions } from '../markdown'
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10) const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10)
@ -57,7 +58,8 @@ const errorLevelProcessor = defineProcessor({
export async function highlight( export async function highlight(
theme: ThemeOptions = 'material-theme-palenight', theme: ThemeOptions = 'material-theme-palenight',
defaultLang: string = '' defaultLang: string = '',
logger: Pick<Logger, 'warn'> = console
): Promise<(str: string, lang: string, attrs: string) => string> { ): Promise<(str: string, lang: string, attrs: string) => string> {
const hasSingleTheme = typeof theme === 'string' || 'name' in theme const hasSingleTheme = typeof theme === 'string' || 'name' in theme
const getThemeName = (themeValue: IThemeRegistration) => const getThemeName = (themeValue: IThemeRegistration) =>
@ -89,9 +91,9 @@ export async function highlight(
if (lang) { if (lang) {
const langLoaded = highlighter.getLoadedLanguages().includes(lang as any) const langLoaded = highlighter.getLoadedLanguages().includes(lang as any)
if (!langLoaded && lang !== 'ansi') { if (!langLoaded && lang !== 'ansi') {
console.warn( logger.warn(
c.yellow( c.yellow(
`The language '${lang}' is not loaded, falling back to '${ `\nThe language '${lang}' is not loaded, falling back to '${
defaultLang || 'txt' defaultLang || 'txt'
}' for syntax highlighting.` }' for syntax highlighting.`
) )

@ -1,19 +1,19 @@
import { resolveTitleFromToken } from '@mdit-vue/shared'
import _debug from 'debug'
import fs from 'fs' import fs from 'fs'
import LRUCache from 'lru-cache'
import path from 'path' import path from 'path'
import c from 'picocolors' import c from 'picocolors'
import LRUCache from 'lru-cache'
import { resolveTitleFromToken } from '@mdit-vue/shared'
import type { SiteConfig } from './config' import type { SiteConfig } from './config'
import { type PageData, type HeadConfig, EXTERNAL_URL_RE } from './shared'
import { slash } from './utils/slash'
import { getGitTimestamp } from './utils/getGitTimestamp'
import { import {
createMarkdownRenderer, createMarkdownRenderer,
type MarkdownEnv, type MarkdownEnv,
type MarkdownOptions, type MarkdownOptions,
type MarkdownRenderer type MarkdownRenderer
} from './markdown' } from './markdown'
import _debug from 'debug' import { EXTERNAL_URL_RE, type HeadConfig, type PageData } from './shared'
import { getGitTimestamp } from './utils/getGitTimestamp'
import { slash } from './utils/slash'
const debug = _debug('vitepress:md') const debug = _debug('vitepress:md')
const cache = new LRUCache<string, MarkdownCompileResult>({ max: 1024 }) const cache = new LRUCache<string, MarkdownCompileResult>({ max: 1024 })
@ -41,7 +41,12 @@ export async function createMarkdownToVueRenderFn(
cleanUrls = false, cleanUrls = false,
siteConfig: SiteConfig | null = null siteConfig: SiteConfig | null = null
) { ) {
const md = await createMarkdownRenderer(srcDir, options, base) const md = await createMarkdownRenderer(
srcDir,
options,
base,
siteConfig?.logger
)
pages = pages.map((p) => slash(p.replace(/\.md$/, ''))) pages = pages.map((p) => slash(p.replace(/\.md$/, '')))
const replaceRegex = genReplaceRegexp(userDefines, isBuild) const replaceRegex = genReplaceRegexp(userDefines, isBuild)
@ -95,7 +100,7 @@ export async function createMarkdownToVueRenderFn(
// validate data.links // validate data.links
const deadLinks: string[] = [] const deadLinks: string[] = []
const recordDeadLink = (url: string) => { const recordDeadLink = (url: string) => {
console.warn( ;(siteConfig?.logger ?? console).warn(
c.yellow( c.yellow(
`\n(!) Found dead link ${c.cyan(url)} in file ${c.white( `\n(!) Found dead link ${c.cyan(url)} in file ${c.white(
c.dim(file) c.dim(file)

@ -1,5 +1,6 @@
import path from 'path' import path from 'path'
import c from 'picocolors' import c from 'picocolors'
import type { OutputAsset, OutputChunk } from 'rollup'
import { import {
defineConfig, defineConfig,
mergeConfig, mergeConfig,
@ -7,18 +8,17 @@ import {
type Plugin, type Plugin,
type ResolvedConfig type ResolvedConfig
} from 'vite' } from 'vite'
import type { SiteConfig } from './config'
import { createMarkdownToVueRenderFn, clearCache } from './markdownToVue'
import { import {
DIST_CLIENT_PATH,
APP_PATH, APP_PATH,
SITE_DATA_REQUEST_PATH, DIST_CLIENT_PATH,
resolveAliases resolveAliases,
SITE_DATA_REQUEST_PATH
} from './alias' } from './alias'
import { slash } from './utils/slash' import type { SiteConfig } from './config'
import type { OutputAsset, OutputChunk } from 'rollup' import { clearCache, createMarkdownToVueRenderFn } from './markdownToVue'
import { staticDataPlugin } from './staticDataPlugin'
import type { PageDataPayload } from './shared' import type { PageDataPayload } from './shared'
import { staticDataPlugin } from './staticDataPlugin'
import { slash } from './utils/slash'
import { webFontsPlugin } from './webFontsPlugin' import { webFontsPlugin } from './webFontsPlugin'
const hashRE = /\.(\w+)\.js$/ const hashRE = /\.(\w+)\.js$/
@ -290,19 +290,22 @@ export async function createVitePressPlugin(
async handleHotUpdate(ctx) { async handleHotUpdate(ctx) {
const { file, read, server } = ctx const { file, read, server } = ctx
if (file === configPath || configDeps.includes(file)) { if (file === configPath || configDeps.includes(file)) {
console.log( siteConfig.logger.info(
c.green( c.green(
`\n${path.relative( `${path.relative(
process.cwd(), process.cwd(),
file file
)} changed, restarting server...` )} changed, restarting server...\n`
) ),
{ clear: true, timestamp: true }
) )
try { try {
clearCache() clearCache()
await recreateServer?.() await recreateServer?.()
} catch (err) { } catch (err) {
console.error(c.red(`failed to restart server. error:\n`), err) siteConfig.logger.error(
c.red(`\nfailed to restart server. error:\n${err}`)
)
} }
return return
} }

@ -1,6 +1,6 @@
import compression from 'compression'
import fs from 'fs' import fs from 'fs'
import path from 'path' import path from 'path'
import compression from 'compression'
import polka, { type IOptions } from 'polka' import polka, { type IOptions } from 'polka'
import sirv, { type RequestHandler } from 'sirv' import sirv, { type RequestHandler } from 'sirv'
import { resolveConfig } from '../config' import { resolveConfig } from '../config'
@ -54,13 +54,15 @@ export async function serve(options: ServeOptions = {}) {
return polka({ onNoMatch }) return polka({ onNoMatch })
.use(base, compress, serve) .use(base, compress, serve)
.listen(port, () => { .listen(port, () => {
console.log(`Built site served at http://localhost:${port}/${base}/\n`) site.logger.info(
`Built site served at http://localhost:${port}/${base}/`
)
}) })
} else { } else {
return polka({ onNoMatch }) return polka({ onNoMatch })
.use(compress, serve) .use(compress, serve)
.listen(port, () => { .listen(port, () => {
console.log(`Built site served at http://localhost:${port}/\n`) site.logger.info(`Built site served at http://localhost:${port}/`)
}) })
} }
} }

@ -21,8 +21,8 @@ export async function createServer(
root: config.srcDir, root: config.srcDir,
base: config.site.base, base: config.site.base,
cacheDir: config.cacheDir, cacheDir: config.cacheDir,
// logLevel: 'warn',
plugins: await createVitePressPlugin(config, false, {}, {}, recreateServer), plugins: await createVitePressPlugin(config, false, {}, {}, recreateServer),
server: serverOptions server: serverOptions,
customLogger: config.logger
}) })
} }

Loading…
Cancel
Save