Cache
When writing Rspack plugins, you can use compiler.getCache(name: string)
or compilation.getCache(name: string)
to get the cache object which can share data in the build process. The cache data is stored on the Compiler
, so it can be used in multiple Compilation
s in the watch mode.
Notice
- Only available when cache: true which it is enabled in
mode="development"
by default.
- Only used for the JavaScript plugins, the Rust cache cannot be accessed.
- Only memory cache is provided, persistent cache is not supported yet.
Example
The following code finds out the newly added assets in the 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);
});
});
Methods
Caching
get/getPromise
Get cache data asynchronously, callback by function or promise.
- Type:
get
: <T>(identifier: string, etag: Etag | null, callback: (err: Error, result: T) => void): void
getPromise
: <T>(identifier: string, etag: Etag | null): Promise<T>;
- Arguments:
- identifier: ID of data item
- etag: Etag of the data item, can be generated by
getLazyHashedEtag
store/storePromise
Store cache data asynchronously, callback by function or promise.
- Type:
store
: <T>(identifier: string, etag: Etag | null, data: T, callback: (err: Error) => void): void;
storePromise
: <T>(identifier: string, etag: Etag | null): Promise<T>;
- Arguments:
- identifier: ID of data item
- etag: Etag of the data item, can be generated by
getLazyHashedEtag
provide/providePromise
Try to get cache data asynchronously, call the computer function to generate when not exists, callback by function or promise.
- Type:
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>;
- Arguments:
- identifier: ID of data item
- etag: Etag of the data item, can be generated by
getLazyHashedEtag
- computer: The called generating function when cache is not exists
MyPlugin.js
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
});
Output
undefined
only called once
[ 'main.js' ]
getLazyHashedEtag/mergeEtags
By using the getLazyHashedEtag
and mergeEtags
methods, an etag can be created as the unique identifier of the data item. It will not be calculated immediately when created, but rather delayed until it is used, and also can be cached. This can be used to improve performance when complex data objects are used as the unique identifier.
getLazyHashedEtag
: (obj: HashableObject): Etag
, calculates the hash of the object to generate the etag as the data identifier, the object needs to implement the updateHash(hash: Hash)
.
mergeEtags
: (a: Etag, b: Etag): Etag
, merges two etags to one.
MyPlugin.js
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));
Output
only called once
cached value
getItemCache
By using the getItemCache
method, a cache object for a single data item can be created. This cache object provides simplified data access methods, do not need identifier and etag as arguments any more.
- Type:
(identifier, etag): ItemCacheFacade
type ItemCacheFacade = {
get<T>(callback: (err: Error, result: T) => void): void; // async data getter, callback by function
getPromise<T>(): Promise<T>; // async data getter, callback by promise
store<T>(data: T, callback: (err: Error, result: T) => void): void; // async data setter, callback by function
storePromise<T>(data: T): Promise<void>; // async data setter, callback by promise
provide<T>( // try to get the data, use function to compute if not exists, callback by function
computer: (fn: (err: Error, result: T) => void) => void,
callback: (err: Error, result: T) => void,
): void;
providePromise<T>( // try to get the data, use function to compute if not exists, callback by promise
computer: (fn: (err: Error, result: T) => void) => void,
): Promise<T>;
};
MyPlugin.js
const cache = compilation.getCache('MyPlugin');
const itemCache = cache.getItemCache('item');
await itemCache.storePromise('cached value');
console.log(await itemCache.getPromise());
getChildCache
By using the getChildCache
method, a child cache object can be generated, with its interface being completely consistent, and it can be utilized when there are numerous caches that require grouping for storage.
- Type:
(name: string): CacheFacade