diff --git a/src/loaders/markdown/index.ts b/src/loaders/markdown/index.ts index a44ae35370..63aafc2e19 100644 --- a/src/loaders/markdown/index.ts +++ b/src/loaders/markdown/index.ts @@ -1,8 +1,8 @@ import { isTabRouteFile } from '@/features/tabs'; import type { IThemeLoadResult } from '@/features/theme/loader'; -import { getCache } from '@/utils'; +import { getCache, getContentHash } from '@/utils'; import fs from 'fs'; -import { lodash, Mustache, winPath } from 'umi/plugin-utils'; +import { Mustache, lodash, winPath } from 'umi/plugin-utils'; import transform, { type IMdTransformerOptions, type IMdTransformerResult, @@ -135,9 +135,11 @@ export default DumiMarkdownContent;`; } } -function getDepsCacheKey(deps: typeof depsMapping['0'] = []) { +function getDepsCacheKey(deps: (typeof depsMapping)['0'] = []) { return JSON.stringify( - deps.map((file) => `${file}:${fs.statSync(file).mtimeMs}`), + deps.map( + (file) => `${file}:${getContentHash(fs.readFileSync(file, 'utf-8'))}`, + ), ); } @@ -149,13 +151,13 @@ export default function mdLoader(this: any, content: string) { const cb = this.async(); const cache = getCache('md-loader'); - // format: {path:mtime:loaderOpts} + // format: {path:contenthash:loaderOpts} const baseCacheKey = [ this.resourcePath, - fs.statSync(this.resourcePath).mtimeMs, + getContentHash(content), JSON.stringify(lodash.omit(opts, ['mode', 'builtins', 'onResolveDemos'])), ].join(':'); - // format: {baseCacheKey:{deps:mtime}[]} + // format: {baseCacheKey:{deps:contenthash}[]} const cacheKey = [ baseCacheKey, getDepsCacheKey(depsMapping[this.resourcePath]), diff --git a/src/utils.ts b/src/utils.ts index b0e422c239..14b6d9c417 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,4 @@ +import { createHash } from 'crypto'; import Cache from 'file-system-cache'; import fs from 'fs'; import yaml from 'js-yaml'; @@ -82,7 +83,7 @@ export function parseCodeFrontmatter(raw: string) { */ const caches: Record> = {}; const CACHE_PATH = 'node_modules/.cache/dumi'; -export function getCache(ns: string): typeof caches['0'] { +export function getCache(ns: string): (typeof caches)['0'] { // return fake cache if cache disabled if (process.env.DUMI_CACHE === 'none') { return { set() {}, get() {}, setSync() {}, getSync() {} } as any; @@ -156,3 +157,10 @@ export function getProjectRoot(cwd: string) { return winPath(cwd); } + +/** + * generate hash for string + */ +export function getContentHash(content: string, length = 8) { + return createHash('md5').update(content).digest('hex').slice(0, length); +}