perf: 优化代码结构
This commit is contained in:
parent
0dc441a0e6
commit
7ab06863e7
@ -1,11 +1,3 @@
|
||||
## scripts/autoInstall
|
||||
|
||||
检查各个 workspace package 中的 vuepress 相关依赖,并更新到最新版本。
|
||||
|
||||
``` sh
|
||||
pnpm autoUpdate
|
||||
```
|
||||
|
||||
## scripts/create
|
||||
|
||||
在 `packages/` 目录下生成一个新的 插件包
|
||||
|
||||
@ -11,7 +11,6 @@ import NotFound from './layouts/NotFound.vue'
|
||||
export default defineClientConfig({
|
||||
enhance({ app, router }) {
|
||||
// global component
|
||||
|
||||
app.component('Badge', Badge)
|
||||
app.component('ExternalLinkIcon', ExternalLinkIcon)
|
||||
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import type { App } from '@vuepress/core'
|
||||
import { resolveLocalePath } from '@vuepress/shared'
|
||||
import type {
|
||||
@ -8,28 +6,13 @@ import type {
|
||||
FrontmatterArray,
|
||||
FrontmatterObject,
|
||||
} from '@vuepress-plume/plugin-auto-frontmatter'
|
||||
import type { NotesItem } from '@vuepress-plume/plugin-notes-data'
|
||||
import { format } from 'date-fns'
|
||||
import { customAlphabet } from 'nanoid'
|
||||
import { uniq } from '@pengzhanbo/utils'
|
||||
import type {
|
||||
PlumeThemeLocaleOptions,
|
||||
PlumeThemePluginOptions,
|
||||
} from '../shared/index.js'
|
||||
|
||||
const nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 8)
|
||||
function getPackage() {
|
||||
let pkg = {} as any
|
||||
try {
|
||||
const content = fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8')
|
||||
pkg = JSON.parse(content)
|
||||
}
|
||||
catch {}
|
||||
return pkg
|
||||
}
|
||||
|
||||
function normalizePath(dir: string) {
|
||||
return dir.replace(/\\+/g, '/')
|
||||
}
|
||||
import { getCurrentDirname, getPackage, nanoid, pathJoin } from './utils.js'
|
||||
|
||||
export default function autoFrontmatter(
|
||||
app: App,
|
||||
@ -38,17 +21,17 @@ export default function autoFrontmatter(
|
||||
): AutoFrontmatterOptions {
|
||||
const sourceDir = app.dir.source()
|
||||
const pkg = getPackage()
|
||||
const articlePrefix = localeOption.article || '/article/'
|
||||
const { locales = {}, avatar, article: articlePrefix = '/article/' } = localeOption
|
||||
const { frontmatter } = options
|
||||
|
||||
const locales = (app.siteData.locales || {}) as PlumeThemeLocaleOptions
|
||||
const localesNotesDirs = Object.keys(locales)
|
||||
const localesNotesDirs = Object.keys(app.siteData.locales || {})
|
||||
.map((locale) => {
|
||||
// fixed: #15
|
||||
const notes = localeOption.locales?.[locale]?.notes
|
||||
const notes = locales[locale]?.notes
|
||||
if (!notes)
|
||||
return ''
|
||||
const dir = notes.dir
|
||||
return dir ? normalizePath(path.join(locale, dir)).replace(/^\//, '') : ''
|
||||
|
||||
return notes.dir ? pathJoin(locale, notes.dir).replace(/^\//, '') : ''
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
@ -58,7 +41,7 @@ export default function autoFrontmatter(
|
||||
return author
|
||||
if (data.friends)
|
||||
return
|
||||
return localeOption.avatar?.name || pkg.author || ''
|
||||
return avatar?.name || pkg.author || ''
|
||||
},
|
||||
createTime(formatTime: string, { createTime }, data: any) {
|
||||
if (formatTime)
|
||||
@ -70,20 +53,20 @@ export default function autoFrontmatter(
|
||||
}
|
||||
|
||||
const resolveLocale = (filepath: string) => {
|
||||
const file = normalizePath(
|
||||
path.join('/', path.relative(sourceDir, filepath)),
|
||||
)
|
||||
const file = pathJoin('/', path.relative(sourceDir, filepath))
|
||||
|
||||
return resolveLocalePath(localeOption.locales!, file)
|
||||
}
|
||||
const notesByLocale = (locale: string) => {
|
||||
const notes = localeOption.locales![locale]?.notes || localeOption.notes
|
||||
const notes = locales[locale]?.notes || localeOption.notes
|
||||
if (notes === false)
|
||||
return undefined
|
||||
return notes
|
||||
}
|
||||
|
||||
const findNote = (filepath: string) => {
|
||||
const file = path.join('/', path.relative(sourceDir, filepath))
|
||||
const locale = resolveLocalePath(localeOption.locales!, normalizePath(file))
|
||||
const file = pathJoin('/', path.relative(sourceDir, filepath))
|
||||
const locale = resolveLocalePath(locales, file)
|
||||
const notes = notesByLocale(locale)
|
||||
if (!notes)
|
||||
return undefined
|
||||
@ -94,22 +77,15 @@ export default function autoFrontmatter(
|
||||
)
|
||||
}
|
||||
|
||||
const getCurrentDirname = (note: NotesItem | undefined, filepath: string) => {
|
||||
const dirList = normalizePath(note?.dir || path.dirname(filepath))
|
||||
.replace(/^\/|\/$/g, '')
|
||||
.split('/')
|
||||
return dirList.length > 0 ? dirList[dirList.length - 1] : ''
|
||||
}
|
||||
return {
|
||||
include: options.frontmatter?.include ?? ['**/*.md'],
|
||||
exclude: options.frontmatter?.exclude ?? ['.vuepress/**/*', 'node_modules'],
|
||||
frontmatter: options.frontmatter?.frontmatter ?? [
|
||||
include: frontmatter?.include ?? ['**/*.md'],
|
||||
exclude: uniq(['.vuepress/**/*', 'node_modules', ...(frontmatter?.exclude ?? [])]),
|
||||
|
||||
frontmatter: [
|
||||
localesNotesDirs.length
|
||||
? {
|
||||
// note 首页链接
|
||||
include: localesNotesDirs.map(dir =>
|
||||
normalizePath(path.join(dir, '**/{readme,README,index}.md')),
|
||||
),
|
||||
include: localesNotesDirs.map(dir => pathJoin(dir, '**/{readme,README,index}.md')),
|
||||
frontmatter: {
|
||||
title(title: string, { filepath }) {
|
||||
if (title)
|
||||
@ -117,7 +93,7 @@ export default function autoFrontmatter(
|
||||
const note = findNote(filepath)
|
||||
if (note?.text)
|
||||
return note.text
|
||||
return getCurrentDirname(note, filepath) || ''
|
||||
return getCurrentDirname(note?.dir, filepath) || ''
|
||||
},
|
||||
...baseFrontmatter,
|
||||
permalink(permalink: string, { filepath }, data: any) {
|
||||
@ -128,13 +104,11 @@ export default function autoFrontmatter(
|
||||
const locale = resolveLocale(filepath)
|
||||
const notes = notesByLocale(locale)
|
||||
const note = findNote(filepath)
|
||||
return normalizePath(
|
||||
path.join(
|
||||
return pathJoin(
|
||||
locale,
|
||||
notes?.link || '',
|
||||
note?.link || getCurrentDirname(note, filepath),
|
||||
note?.link || getCurrentDirname(note?.dir, filepath),
|
||||
'/',
|
||||
),
|
||||
)
|
||||
},
|
||||
},
|
||||
@ -142,9 +116,7 @@ export default function autoFrontmatter(
|
||||
: '',
|
||||
localesNotesDirs.length
|
||||
? {
|
||||
include: localesNotesDirs.map(dir =>
|
||||
normalizePath(path.join(dir, '**/**.md')),
|
||||
),
|
||||
include: localesNotesDirs.map(dir => pathJoin(dir, '**/**.md')),
|
||||
frontmatter: {
|
||||
title(title: string, { filepath }) {
|
||||
if (title)
|
||||
@ -161,14 +133,12 @@ export default function autoFrontmatter(
|
||||
const locale = resolveLocale(filepath)
|
||||
const note = findNote(filepath)
|
||||
const notes = notesByLocale(locale)
|
||||
return normalizePath(
|
||||
path.join(
|
||||
return pathJoin(
|
||||
locale,
|
||||
notes?.link || '',
|
||||
note?.link || getCurrentDirname(note, filepath),
|
||||
note?.link || getCurrentDirname(note?.dir, filepath),
|
||||
nanoid(),
|
||||
'/',
|
||||
),
|
||||
)
|
||||
},
|
||||
},
|
||||
@ -192,9 +162,7 @@ export default function autoFrontmatter(
|
||||
if (permalink)
|
||||
return permalink
|
||||
const locale = resolveLocale(filepath)
|
||||
return normalizePath(
|
||||
path.join(locale, articlePrefix, nanoid(), '/'),
|
||||
)
|
||||
return pathJoin(locale, articlePrefix, nanoid(), '/')
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -18,8 +18,8 @@ import { iconifyPlugin } from '@vuepress-plume/plugin-iconify'
|
||||
import { notesDataPlugin } from '@vuepress-plume/plugin-notes-data'
|
||||
import { shikijiPlugin } from '@vuepress-plume/plugin-shikiji'
|
||||
import { commentPlugin } from 'vuepress-plugin-comment2'
|
||||
import { mdEnhancePlugin } from 'vuepress-plugin-md-enhance'
|
||||
import { useReadingTimePlugin } from 'vuepress-plugin-reading-time2'
|
||||
import { type MarkdownEnhanceOptions, mdEnhancePlugin } from 'vuepress-plugin-md-enhance'
|
||||
import { readingTimePlugin } from 'vuepress-plugin-reading-time2'
|
||||
import { seoPlugin } from 'vuepress-plugin-seo2'
|
||||
import { sitemapPlugin } from 'vuepress-plugin-sitemap2'
|
||||
import type {
|
||||
@ -41,10 +41,7 @@ export function setupPlugins(app: App, options: PlumeThemePluginOptions, localeO
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
if (options.readingTime !== false)
|
||||
useReadingTimePlugin(app, options.readingTime || {}, true)
|
||||
|
||||
return [
|
||||
const plugins: PluginConfig = [
|
||||
palettePlugin({ preset: 'sass' }),
|
||||
|
||||
themeDataPlugin({
|
||||
@ -55,6 +52,7 @@ export function setupPlugins(app: App, options: PlumeThemePluginOptions, localeO
|
||||
: undefined,
|
||||
} as any,
|
||||
}),
|
||||
|
||||
autoFrontmatterPlugin(autoFrontmatter(app, options, localeOptions)),
|
||||
|
||||
blogDataPlugin({
|
||||
@ -85,8 +83,6 @@ export function setupPlugins(app: App, options: PlumeThemePluginOptions, localeO
|
||||
},
|
||||
}),
|
||||
|
||||
localeOptions.notes ? notesDataPlugin(localeOptions.notes) : [],
|
||||
|
||||
iconifyPlugin(),
|
||||
|
||||
activeHeaderLinksPlugin({
|
||||
@ -95,37 +91,45 @@ export function setupPlugins(app: App, options: PlumeThemePluginOptions, localeO
|
||||
delay: 200,
|
||||
offset: 20,
|
||||
}),
|
||||
]
|
||||
|
||||
options.nprogress !== false ? nprogressPlugin() : [],
|
||||
if (options.readingTime !== false)
|
||||
plugins.push(readingTimePlugin(options.readingTime || {}))
|
||||
|
||||
options.git !== false
|
||||
? gitPlugin({
|
||||
if (localeOptions.notes)
|
||||
plugins.push(notesDataPlugin(localeOptions.notes))
|
||||
|
||||
if (options.nprogress !== false)
|
||||
plugins.push(nprogressPlugin())
|
||||
|
||||
if (options.git !== false) {
|
||||
plugins.push(gitPlugin({
|
||||
createdTime: false,
|
||||
updatedTime: localeOptions.lastUpdated !== false,
|
||||
contributors: localeOptions.contributors !== false,
|
||||
})
|
||||
: [],
|
||||
}))
|
||||
}
|
||||
|
||||
options.mediumZoom !== false
|
||||
? mediumZoomPlugin({
|
||||
if (options.mediumZoom !== false) {
|
||||
plugins.push(mediumZoomPlugin({
|
||||
selector: '.plume-content > img, .plume-content :not(a) > img',
|
||||
zoomOptions: {
|
||||
background: 'var(--vp-c-bg)',
|
||||
},
|
||||
delay: 300,
|
||||
})
|
||||
: [],
|
||||
}))
|
||||
}
|
||||
|
||||
options.caniuse !== false
|
||||
? caniusePlugin(
|
||||
if (options.caniuse !== false) {
|
||||
plugins.push(caniusePlugin(
|
||||
options.caniuse || {
|
||||
mode: 'embed',
|
||||
},
|
||||
)
|
||||
: [],
|
||||
))
|
||||
}
|
||||
|
||||
options.externalLinkIcon !== false
|
||||
? externalLinkIconPlugin({
|
||||
if (options.externalLinkIcon !== false) {
|
||||
plugins.push(externalLinkIconPlugin({
|
||||
locales: Object.entries(localeOptions.locales || {}).reduce(
|
||||
(result: Record<string, any>, [key, value]) => {
|
||||
result[key] = {
|
||||
@ -136,33 +140,42 @@ export function setupPlugins(app: App, options: PlumeThemePluginOptions, localeO
|
||||
},
|
||||
{},
|
||||
),
|
||||
})
|
||||
: [],
|
||||
}))
|
||||
}
|
||||
|
||||
options.search !== false ? searchPlugin(options.search) : [],
|
||||
options.docsearch !== false && !options.search
|
||||
? docsearchPlugin(options.docsearch!)
|
||||
: [],
|
||||
if (options.search !== false)
|
||||
plugins.push(searchPlugin(options.search))
|
||||
|
||||
options.shikiji !== false
|
||||
? shikijiPlugin({
|
||||
if (options.docsearch !== false && !options.search) {
|
||||
if (options.docsearch?.appId && options.docsearch?.apiKey) {
|
||||
plugins.push(docsearchPlugin(options.docsearch))
|
||||
}
|
||||
else {
|
||||
console.error(
|
||||
'docsearch plugin: appId and apiKey are both required',
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (options.shikiji !== false) {
|
||||
plugins.push(shikijiPlugin({
|
||||
theme: { light: 'vitesse-light', dark: 'vitesse-dark' },
|
||||
...(options.shikiji ?? {}),
|
||||
})
|
||||
: [],
|
||||
}))
|
||||
}
|
||||
|
||||
options.copyCode !== false
|
||||
? copyCodePlugin({
|
||||
if (options.copyCode !== false) {
|
||||
plugins.push(copyCodePlugin({
|
||||
selector: '.plume-content div[class*="language-"] pre',
|
||||
...options.copyCode,
|
||||
})
|
||||
: [],
|
||||
}))
|
||||
}
|
||||
|
||||
options.markdownEnhance !== false
|
||||
? mdEnhancePlugin(
|
||||
if (options.markdownEnhance !== false) {
|
||||
plugins.push(mdEnhancePlugin(
|
||||
Object.assign(
|
||||
{
|
||||
hint: true, // info note tip warning danger details d
|
||||
hint: true, // info note tip warning danger details
|
||||
codetabs: true,
|
||||
tabs: true,
|
||||
align: true,
|
||||
@ -170,28 +183,32 @@ export function setupPlugins(app: App, options: PlumeThemePluginOptions, localeO
|
||||
tasklist: true,
|
||||
demo: true,
|
||||
attrs: true,
|
||||
},
|
||||
sup: true,
|
||||
sub: true,
|
||||
} as MarkdownEnhanceOptions,
|
||||
options.markdownEnhance || {},
|
||||
),
|
||||
)
|
||||
: [],
|
||||
))
|
||||
}
|
||||
|
||||
options.comment !== false ? commentPlugin(options.comment || {}) : [],
|
||||
if (options.comment !== false)
|
||||
plugins.push(commentPlugin(options.comment || {}))
|
||||
|
||||
options.baiduTongji !== false && options.baiduTongji?.key
|
||||
? baiduTongjiPlugin(options.baiduTongji)
|
||||
: [],
|
||||
if (options.baiduTongji !== false && options.baiduTongji?.key)
|
||||
plugins.push(baiduTongjiPlugin(options.baiduTongji))
|
||||
|
||||
options.sitemap !== false && localeOptions.hostname && isProd
|
||||
? sitemapPlugin({
|
||||
if (options.sitemap !== false && localeOptions.hostname && isProd) {
|
||||
plugins.push(sitemapPlugin({
|
||||
hostname: localeOptions.hostname,
|
||||
})
|
||||
: [],
|
||||
options.seo !== false && localeOptions.hostname && isProd
|
||||
? seoPlugin({
|
||||
}))
|
||||
}
|
||||
|
||||
if (options.seo !== false && localeOptions.hostname && isProd) {
|
||||
plugins.push(seoPlugin({
|
||||
hostname: localeOptions.hostname || '',
|
||||
author: localeOptions.avatar?.name,
|
||||
})
|
||||
: [],
|
||||
]
|
||||
}))
|
||||
}
|
||||
|
||||
return plugins
|
||||
}
|
||||
|
||||
@ -6,10 +6,7 @@ import type {
|
||||
PlumeThemeLocaleOptions,
|
||||
PlumeThemePageData,
|
||||
} from '../shared/index.js'
|
||||
|
||||
function normalizePath(dir: string) {
|
||||
return dir.replace(/\\+/g, '/')
|
||||
}
|
||||
import { normalizePath } from './utils.js'
|
||||
|
||||
export async function setupPage(
|
||||
app: App,
|
||||
|
||||
33
theme/src/node/utils.ts
Normal file
33
theme/src/node/utils.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { customAlphabet } from 'nanoid'
|
||||
|
||||
export const nanoid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 8)
|
||||
|
||||
export function getPackage() {
|
||||
let pkg = {} as any
|
||||
try {
|
||||
const content = fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8')
|
||||
pkg = JSON.parse(content)
|
||||
}
|
||||
catch { }
|
||||
return pkg
|
||||
}
|
||||
|
||||
const RE_SLASH = /\\+/g
|
||||
export function normalizePath(dir: string) {
|
||||
return dir.replace(RE_SLASH, '/')
|
||||
}
|
||||
|
||||
export function pathJoin(...args: string[]) {
|
||||
return normalizePath(path.join(...args))
|
||||
}
|
||||
|
||||
const RE_START_END_SLASH = /^\/|\/$/g
|
||||
export function getCurrentDirname(basePath: string | undefined, filepath: string) {
|
||||
const dirList = normalizePath(basePath || path.dirname(filepath))
|
||||
.replace(RE_START_END_SLASH, '')
|
||||
.split('/')
|
||||
return dirList.length > 0 ? dirList[dirList.length - 1] : ''
|
||||
}
|
||||
@ -50,7 +50,7 @@ export interface PlumeThemePluginOptions {
|
||||
|
||||
baiduTongji?: false | BaiduTongjiOptions
|
||||
|
||||
frontmatter?: AutoFrontmatterOptions
|
||||
frontmatter?: Omit<AutoFrontmatterOptions, 'frontmatter'>
|
||||
|
||||
readingTime?: false | ReadingTimeOptions
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user