缓存

在编写 Rspack 插件时,可以使用 compiler.getCache(name: string)compilation.getCache(name: string) 获取缓存对象,该对象可以在构建过程中共享数据。缓存数据存储在 Compiler 上,因此可以在监视模式下的多个 Compilation 中使用。

注意
  • 仅在 cache: true 时可用,默认情况下它在 mode="development" 中启用。
  • 仅用于 JavaScript 插件,无法访问 Rust 缓存。
  • 目前仅提供内存缓存,不支持持久化缓存。

示例

以下代码找出 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);
  });
});

方法

缓存

get/getPromise

异步获取缓存数据,通过函数或 Promise 回调。

  • 类型
    • get: <T>(identifier: string, etag: Etag | null, callback: (err: Error, result: T) => void): void
    • getPromise: <T>(identifier: string, etag: Etag | null): Promise<T>;
  • 参数
    • identifier: 数据项的 ID
    • etag: 数据项的 Etag,可以通过 getLazyHashedEtag 生成

store/storePromise

异步存储缓存数据,通过函数或 Promise 回调。

  • 类型
    • store: <T>(identifier: string, etag: Etag | null, data: T, callback: (err: Error) => void): void;
    • storePromise: <T>(identifier: string, etag: Etag | null): Promise<T>;
  • 参数
    • identifier: 数据项的 ID
    • etag: 数据项的 Etag,可以通过 getLazyHashedEtag 生成

provide/providePromise

尝试异步获取缓存数据,当不存在时调用计算机函数生成,通过函数或 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>;
  • 参数
    • identifier: 数据项的 ID
    • etag: 数据项的 Etag,可以通过 getLazyHashedEtag 生成
    • computer: 当缓存不存在时调用的生成函数
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
});
输出
undefined
only called once
[ 'main.js' ]

getLazyHashedEtag/mergeEtags

通过使用 getLazyHashedEtagmergeEtags 方法,可以创建一个 Etag 作为数据项的唯一标识符。它不会在创建时立即计算,而是延迟到使用时,并且也可以被缓存。这可以用于在使用复杂数据对象作为唯一标识符时提高性能。

  • getLazyHashedEtag: (obj: HashableObject): Etag,计算对象的哈希值以生成 Etag 作为数据标识符,对象需要实现 updateHash(hash: Hash)
  • mergeEtags: (a: Etag, b: Etag): Etag,将两个 Etag 合并为一个。
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));
输出
only called once
cached value

getItemCache

通过使用 getItemCache 方法,可以创建一个用于单个数据项的缓存对象。该缓存对象提供简化的数据访问方法,不再需要标识符和 Etag 作为参数。

  • 类型: (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());
输出
cached value

getChildCache

通过使用 getChildCache 方法,可以生成一个子缓存对象,其接口完全一致,可以在需要对大量缓存进行分组存储时使用。

  • 类型: (name: string): CacheFacade