From e34690836b2abf1a796a5376cb147cbc8c1f7b8f Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Sat, 22 Mar 2025 00:07:00 +0800 Subject: [PATCH] feat(theme): improve log output (#526) --- theme/src/node/detector/dependency.ts | 30 +++++++++++++++-------- theme/src/node/detector/markdown.ts | 12 ++++++++-- theme/src/node/detector/plugins.ts | 12 ++++++++-- theme/src/node/theme.ts | 3 ++- theme/src/node/utils/index.ts | 1 + theme/src/node/utils/translate.ts | 34 +++++++++++++++++++++++++++ 6 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 theme/src/node/utils/translate.ts diff --git a/theme/src/node/detector/dependency.ts b/theme/src/node/detector/dependency.ts index 7e77660c..f0a20443 100644 --- a/theme/src/node/detector/dependency.ts +++ b/theme/src/node/detector/dependency.ts @@ -3,7 +3,7 @@ import { isEmptyObject, isPlainObject } from '@pengzhanbo/utils' import { isPackageExists } from 'local-pkg' import { getUserAgent, resolveCommand } from 'package-manager-detector' import { colors } from 'vuepress/utils' -import { logger } from '../utils/index.js' +import { createTranslate, logger } from '../utils/index.js' const DEPENDENCIES: Record = { twoslash: ['@vuepress/shiki-twoslash'], @@ -18,6 +18,17 @@ const DEPENDENCIES: Record = { mathjax: ['mathjax-full'], } +const t = createTranslate({ + en: { + notFoundDeps: 'Enabling features such as {{ features }} requires the installation of the following dependencies: {{ dependencies }}', + install: 'Run the command to install: {{ command }}', + }, + zh: { + notFoundDeps: '启用 {{ features }} 等功能需要安装以下依赖: {{ dependencies }}', + install: '运行安装命令: {{ command }}', + }, +}) + /** * 部分功能需要手动安装依赖, * 检查环境中是否缺少依赖 @@ -56,20 +67,19 @@ export function detectDependencies(options: ThemeOptions, plugins: ThemeBuiltinP const features = Object.keys(shouldInstall) const dependencies = Object.values(shouldInstall).flat() - logger.warn(`\nEnabling features such as ${ - features.map(feat => colors.green(feat)).join(', ') - } requires the installation of the following dependencies: ${ - dependencies.map(dep => colors.yellow(dep)).join(', ') - }`) + logger.error(t('notFoundDeps', { + features: features.map(feat => colors.green(feat)).join(', '), + dependencies: dependencies.map(dep => colors.magenta(dep)).join(', '), + })) const agent = getUserAgent() if (agent) { const { command = '', args = [] } = resolveCommand(agent, 'add', dependencies) || {} - logger.info(`Run the command to install:\n ${ - colors.cyan(`${command} ${ + logger.info(t('install', { + command: colors.cyan(`${command} ${ args.join(' ').replace(DEPENDENCIES.twoslash[0], `${DEPENDENCIES.twoslash[0]}@next`) - }`) - }`) + }`), + })) } } diff --git a/theme/src/node/detector/markdown.ts b/theme/src/node/detector/markdown.ts index 6b80331d..b6be4bdf 100644 --- a/theme/src/node/detector/markdown.ts +++ b/theme/src/node/detector/markdown.ts @@ -1,8 +1,13 @@ import type { ThemeOptions } from '../../shared/index.js' import { colors } from 'vuepress/utils' -import { logger } from '../utils/index.js' +import { createTranslate, logger } from '../utils/index.js' import { MARKDOWN_SUPPORT_FIELDS } from './fields.js' +const t = createTranslate({ + en: { message: '{{ markdown }} unsupported fields: {{ unsupported }}, please check your config.' }, + zh: { message: '{{ markdown }} 不支持以下字段: {{ unsupported }}, 请检查你的配置。' }, +}) + export function detectMarkdown(options: ThemeOptions): void { const { markdown } = options @@ -12,6 +17,9 @@ export function detectMarkdown(options: ThemeOptions): void { const unsupported = Object.keys(markdown).filter(key => !MARKDOWN_SUPPORT_FIELDS.includes(key as keyof ThemeOptions['markdown'])) if (unsupported.length) { - logger.warn(`\n${colors.green('markdown')} unsupported fields: ${unsupported.map(field => colors.yellow(`"${field}"`)).join(', ')}, please check your config.`) + logger.warn(t('message', { + markdown: colors.green('markdown'), + unsupported: unsupported.map(field => colors.magenta(`"${field}"`)).join(', '), + })) } } diff --git a/theme/src/node/detector/plugins.ts b/theme/src/node/detector/plugins.ts index 01f31bf7..37d7dc47 100644 --- a/theme/src/node/detector/plugins.ts +++ b/theme/src/node/detector/plugins.ts @@ -1,8 +1,13 @@ import type { ThemeBuiltinPlugins } from '../../shared/index.js' import { colors } from 'vuepress/utils' -import { logger } from '../utils/index.js' +import { createTranslate, logger } from '../utils/index.js' import { PLUGINS_SUPPORTED_FIELDS } from './fields.js' +const t = createTranslate({ + en: { message: '{{ plugins }} unsupported fields: {{ unsupported }}, please check your config.' }, + zh: { message: '{{ plugins }} 不支持以下字段: {{ unsupported }}, 请检查你的配置。' }, +}) + export function detectPlugins(plugins: ThemeBuiltinPlugins) { // 部分用户可能混淆 plugins 选项与 vuepress 的 plugins 选项,误传入插件数组 if (Array.isArray(plugins)) { @@ -13,6 +18,9 @@ export function detectPlugins(plugins: ThemeBuiltinPlugins) { // 传入未知的 插件配置项 if (unsupportedPluginsFields.length) { - logger.warn(`\n${colors.green('plugins')} unsupported fields: ${unsupportedPluginsFields.map(field => colors.yellow(`"${field}"`)).join(', ')}, please check your config.`) + logger.warn(t('message', { + plugins: colors.green('plugins'), + unsupported: unsupportedPluginsFields.map(field => colors.magenta(`"${field}"`)).join(', '), + })) } } diff --git a/theme/src/node/theme.ts b/theme/src/node/theme.ts index f6560cd6..ffc45e01 100644 --- a/theme/src/node/theme.ts +++ b/theme/src/node/theme.ts @@ -18,10 +18,11 @@ import { createPages, extendsPageData } from './pages/index.js' import { setupPlugins } from './plugins/index.js' import { prepareData, watchPrepare } from './prepare/index.js' import { prepareThemeData } from './prepare/prepareThemeData.js' -import { perf, resolve, templates, THEME_NAME } from './utils/index.js' +import { perf, resolve, setTranslateLang, templates, THEME_NAME } from './utils/index.js' export function plumeTheme(options: ThemeOptions = {}): Theme { return (app) => { + setTranslateLang(app.options.lang) perf.init(app.env.isDebug) const { configFile, plugins, themeOptions } = detectThemeOptions(options) diff --git a/theme/src/node/utils/index.ts b/theme/src/node/utils/index.ts index 05b34926..fea79631 100644 --- a/theme/src/node/utils/index.ts +++ b/theme/src/node/utils/index.ts @@ -6,4 +6,5 @@ export * from './logger.js' export * from './package.js' export * from './path.js' export * from './resolveContent.js' +export * from './translate.js' export * from './writeTemp.js' diff --git a/theme/src/node/utils/translate.ts b/theme/src/node/utils/translate.ts new file mode 100644 index 00000000..828e4cce --- /dev/null +++ b/theme/src/node/utils/translate.ts @@ -0,0 +1,34 @@ +/** + * 简单的内置 中 / 英 翻译转换工具, + * 用于在需要 Log 的场景,根据 app.lang 设置输出语言 + */ + +import { isEmptyObject } from '@pengzhanbo/utils' + +type TranslateLang = 'zh' | 'en' +type TranslateLocale = Record + +let lang = 'en' + +export function setTranslateLang(current: string) { + if (['zh-CN', 'zh', 'zh-Hans', 'zh-Hant'].includes(current)) { + lang = 'zh' + } + else { + lang = 'en' + } +} + +export function createTranslate( + locales: Record, +) { + return function t(key: keyof Locale, data?: Record) { + const resolved = locales[lang][key] + if (!resolved) + return key + if (data && !isEmptyObject(data)) { + return resolved.replace(/\{\{\s*(\w+)\s*\}\}/g, (_: string, key: string) => data[key] || _) + } + return resolved + } +}