-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bb739df
commit 215ea2e
Showing
13 changed files
with
263 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Change Log | ||
|
||
All notable changes to this project will be documented in this file. | ||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
{ | ||
"name": "@vuepress/plugin-cache", | ||
"version": "2.0.0-rc.37", | ||
"description": "VuePress plugin - cache", | ||
"keywords": [ | ||
"vuepress-plugin", | ||
"vuepress", | ||
"plugin", | ||
"cache" | ||
], | ||
"homepage": "https://ecosystem.vuejs.press/plugins/tools/cache.html", | ||
"bugs": { | ||
"url": "https://github.com/vuepress/ecosystem/issues" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/vuepress/ecosystem.git", | ||
"directory": "plugins/tools/plugin-cache" | ||
}, | ||
"license": "MIT", | ||
"author": "pengzhanbo", | ||
"type": "module", | ||
"exports": { | ||
".": "./lib/node/index.js", | ||
"./package.json": "./package.json" | ||
}, | ||
"main": "./lib/node/index.js", | ||
"types": "./lib/node/index.d.ts", | ||
"files": [ | ||
"lib" | ||
], | ||
"scripts": { | ||
"build": "tsc -b tsconfig.build.json", | ||
"clean": "rimraf --glob ./lib ./*.tsbuildinfo" | ||
}, | ||
"peerDependencies": { | ||
"vuepress": "2.0.0-rc.14" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import type { Plugin } from 'vuepress/core' | ||
import { highlightCache } from './highlightCache.js' | ||
import { renderCache } from './renderCache.js' | ||
|
||
/** | ||
* Cache markdown rendering, optimize compilation speed. | ||
* | ||
* This plugin is recommended to be placed after all other plugins to ensure maximum utilization of the cache. | ||
*/ | ||
export const cachePlugin = (): Plugin => { | ||
return { | ||
name: '@vuepress/plugin-cache', | ||
|
||
async extendsMarkdown(md, app) { | ||
highlightCache(md, app) | ||
await renderCache(md, app) | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/** | ||
* Code highlight is a relatively time-consuming operation, | ||
* especially in `shiki` where enabling numerous transformers can significantly impact performance. | ||
* This effect is particularly noticeable with tools like `twoslash`, | ||
* which require type compilation and may lead to individual code blocks taking over 500ms to process. | ||
* | ||
* When there are multiple code blocks, focusing only on modifying parts of the code blocks while | ||
* still compiling all code blocks entirely can lead to unnecessary overhead. | ||
* Therefore, using the LRU cache algorithm can help by storing unchanged code blocks' | ||
* highlighted results and only processing the parts that have been modified. | ||
*/ | ||
import type { App } from 'vuepress' | ||
import type { Markdown } from 'vuepress/markdown' | ||
import { LRUCache } from './lru.js' | ||
import { hash } from './utils.js' | ||
|
||
const cache = new LRUCache<string, string>(64) | ||
|
||
export const highlightCache = (md: Markdown, app: App): void => { | ||
/** | ||
* Cache is only needed in development mode to enhance the development experience. | ||
*/ | ||
if (!app.env.isDev) return | ||
|
||
const highlight = md.options.highlight | ||
|
||
md.options.highlight = (...args) => { | ||
const key = hash(args.join('')) | ||
const cached = cache.get(key) | ||
|
||
if (cached) return cached | ||
|
||
const content = highlight?.(...args) ?? '' | ||
cache.set(key, content) | ||
|
||
return content | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './cachePlugin.js' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// adapted from https://stackoverflow.com/a/46432113/11613622 | ||
|
||
export class LRUCache<K, V> { | ||
private max: number | ||
private cache: Map<K, V> | ||
|
||
constructor(max = 10) { | ||
this.max = max | ||
this.cache = new Map<K, V>() | ||
} | ||
|
||
get(key: K): V | undefined { | ||
const item = this.cache.get(key) | ||
if (item !== undefined) { | ||
// refresh key | ||
this.cache.delete(key) | ||
this.cache.set(key, item) | ||
} | ||
return item | ||
} | ||
|
||
set(key: K, val: V): void { | ||
// refresh key | ||
if (this.cache.has(key)) this.cache.delete(key) | ||
// evict oldest | ||
else if (this.cache.size === this.max) this.cache.delete(this.first()!) | ||
this.cache.set(key, val) | ||
} | ||
|
||
first(): K | undefined { | ||
return this.cache.keys().next().value | ||
} | ||
|
||
clear(): void { | ||
this.cache.clear() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/** | ||
* When various features are added to markdown, the compilation speed of a single markdown file | ||
* will become slower, especially when there are many pages in the project, | ||
* causing the startup of the vuepress development service to become very slow and time-consuming. | ||
* This plugin will cache the `markdown render` result during the initial compilation process. | ||
* During subsequent compilations, if the content has not been modified, | ||
* compilation will be skipped directly, thus speeding up the second startup of vuepress. | ||
*/ | ||
import type { App } from 'vuepress' | ||
import type { Markdown, MarkdownEnv } from 'vuepress/markdown' | ||
import { fs } from 'vuepress/utils' | ||
import { hash, readFile, writeFile } from './utils.js' | ||
|
||
export interface CacheDta { | ||
content: string | ||
env: MarkdownEnv | ||
} | ||
|
||
// { [filepath]: CacheDta } | ||
export type Cache = Record<string, CacheDta> | ||
|
||
// { [filepath]: hash } | ||
export type Metadata = Record<string, string> | ||
|
||
const CACHE_DIR = 'markdown/rendered' | ||
const META_FILE = '_metadata.json' | ||
const CACHE_FILE = '_cache.json' | ||
|
||
export const renderCache = async (md: Markdown, app: App): Promise<void> => { | ||
if (app.env.isBuild && !fs.existsSync(app.dir.cache(CACHE_DIR))) { | ||
return | ||
} | ||
|
||
const basename = app.dir.cache(CACHE_DIR) | ||
const metaFilepath = `${basename}/${META_FILE}` | ||
const cacheFilepath = `${basename}/${CACHE_FILE}` | ||
|
||
await fs.ensureDir(basename) | ||
|
||
const [metadata, cache] = await Promise.all([ | ||
readFile<Metadata>(metaFilepath), | ||
readFile<Cache>(cacheFilepath), | ||
]) | ||
|
||
let timer: ReturnType<typeof setTimeout> | null = null | ||
const update = async (): Promise<void> => { | ||
timer && clearTimeout(timer) | ||
timer = setTimeout( | ||
async () => | ||
await Promise.all([ | ||
writeFile(metaFilepath, metadata), | ||
writeFile(cacheFilepath, cache), | ||
]), | ||
200, | ||
) | ||
} | ||
|
||
const rawRender = md.render | ||
md.render = (input, env: MarkdownEnv) => { | ||
const filepath = env.filePathRelative | ||
|
||
if (!filepath) { | ||
return rawRender(input, env) | ||
} | ||
|
||
const key = hash(input) | ||
if (metadata[filepath] === key && cache[filepath]) { | ||
const cached = cache[filepath] | ||
Object.assign(env, cached.env) | ||
return cached.content | ||
} | ||
|
||
const content = rawRender(input, env) | ||
metadata[filepath] = key | ||
cache[filepath] = { content, env } | ||
|
||
update() | ||
|
||
return content | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { createHash } from 'node:crypto' | ||
import { fs } from 'vuepress/utils' | ||
|
||
export const hash = (data: string): string => | ||
createHash('md5').update(data).digest('hex') | ||
|
||
export const readFile = async <T = any>(filepath: string): Promise<T> => { | ||
try { | ||
const content = await fs.readFile(filepath, 'utf-8') | ||
return JSON.parse(content) as T | ||
} catch { | ||
return {} as T | ||
} | ||
} | ||
|
||
export const writeFile = async <T = any>( | ||
filepath: string, | ||
data: T, | ||
): Promise<void> => await fs.writeFile(filepath, JSON.stringify(data), 'utf-8') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"extends": "../../../tsconfig.build.json", | ||
"compilerOptions": { | ||
"rootDir": "./src", | ||
"outDir": "./lib" | ||
}, | ||
"include": ["./src"] | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters