在编写 Rspack 插件时,可通过 compiler.getCache(name: string) 或 compilation.getCache(name: string) 获取缓存对象,以在构建流程中共享数据。缓存数据存储在 Compiler 上,因此可在 Watch 模式下的多次 Compilation 中使用。
mode="development" 时默认开启。以下示例在 processAssets 阶段打印此次构建中新增的产物:
compiler.hooks.compilation.tap('MyPlugin', compilation => {
compilation.hooks.processAssets.tapPromise('MyPlugin', async () => {
const cache = compilation.getCache('MyPlugin');
const currentAssets = compilation.getAssets().map(i => i.name);
const lastAssets = await cache.getPromise('assets', null);
if (lastAssets) {
for (const asset of currentAssets) {
if (!lastAssets.includes(asset)) {
console.log(`New asset: ${asset}`);
}
}
}
await cache.storePromise('assets', null, currentAssets);
});
});异步获取缓存数据,提供回调和 Promise 两种形式。
get: <T>(identifier: string, etag: Etag | null, callback: (err: Error, result: T) => void): voidgetPromise: <T>(identifier: string, etag: Etag | null): Promise<T>;getLazyHashedEtag 生成异步存储缓存数据,提供回调和 Promise 两种形式。
store: <T>(identifier: string, etag: Etag | null, data: T, callback: (err: Error) => void): void;storePromise: <T>(identifier: string, etag: Etag | null): Promise<T>;getLazyHashedEtag 生成尝试获取缓存,不存在则通过函数生成并存储,提供回调和 Promise 两种形式。
provide:
provide<T>(
identifier: string,
etag: Etag | null,
computer: (fn: (err: Error, result: T) => void) => void,
callback: () => T | Promise<T>,
): void;providePromise
providePromise<T>(
identifier: string,
etag: Etag | null,
computer: () => T | Promise<T>,
): Promise<T>;getLazyHashedEtag 生成const createAssetsData = async () => {
console.log('only called once');
return compilation.getAssets().map(i => i.name);
};
compilation.hooks.processAssets.tapPromise('MyPlugin', async () => {
const cache = compilation.getCache('MyPlugin');
console.log(await cache.getPromise('assets', null)); // undefined
await cache.providePromise('assets', null, createAssetsData); // call createAssetsData
console.log(await cache.getPromise('assets', null)); // ["main.js"]
await cache.providePromise('assets', null, createAssetsData); // not call
});undefined
only called once
[ 'main.js' ]通过 getLazyHashedEtag 和 mergeEtags 方法可以创建一个 Etag 作为数据项唯一标识,它不会在创建时立即计算,而是在使用的时候延迟计算,并且能够被缓存。需以复杂数据对象作为唯一标识时使用可提升性能。
getLazyHashedEtag: (obj: HashableObject): Etag,计算对象的 hash 以获得 Etag 作为数据标识,对象需要实现 updateHash(hash: Hash) 方法。mergeEtags: (a: Etag, b: Etag): Etag,合并两个 Etag 作为数据标识。const cache = compilation.getCache('MyPlugin');
const dataEtag = cache.getLazyHashedEtag({
content: 'a'.repeat(10000),
updateHash(hash) {
console.log("only called once");
hash.update(this.content);
}
});
const mergedEtag = cache.mergeEtags(dataEtag, "other etag");
await cache.storePromise("assets", mergedEtag, "cached value");
console.log(await cache.getPromise("assets", mergedEtag));only called once
cached value通过 getItemCache 方法可创建一个针对单个数据项的缓存对象,该缓存对象提供了简化的数据存取接口,不再需要传输缓存标识和数据标识。
(identifier, etag): ItemCacheFacadetype ItemCacheFacade = {
get<T>(callback: (err: Error, result: T) => void): void; // 获取数据,通过回调获取结果
getPromise<T>(): Promise<T>; // 获取数据,通过 Promise 获取结果
store<T>(data: T, callback: (err: Error, result: T) => void): void; // 存储数据,通过回调通知结果
storePromise<T>(data: T): Promise<void>; // 存储数据,通过 Promise 获取结果
provide<T>( // 尝试获取缓存,不存在则生成并存储,通过回调获取结果
computer: (fn: (err: Error, result: T) => void) => void,
callback: (err: Error, result: T) => void,
): void;
providePromise<T>( // 尝试获取缓存,不存在则生成并存储,通过 Promise 获取结果
computer: (fn: (err: Error, result: T) => void) => void,
): Promise<T>;
};const cache = compilation.getCache('MyPlugin');
const itemCache = cache.getItemCache('item');
await itemCache.storePromise('cached value');
console.log(await itemCache.getPromise());cached value通过 getChildCache 方法可创建一个子缓存对象,其接口完全一致,可用于在缓存较多需要分组存储时使用。
(name: string): CacheFacade