facebook / facebook/docusaurus

Feature: Enable Plugin loadContent caching, improve plugin reload perf

Abierto
#5,393 4 comentarios 1 reacción 0 asignados Ver en GitHub
feature
Lenguaje dominante
TypeScript
Estrellas
66.2k
Forks
10k
Merge medio
1 d 3 h
PR fusionados (30 d)
52

Descripción

## 🚀 Feature

This feature request will help to avoid slow builds/hot reloads by allowing plugin authors to cache effectively.

> Do note that this is a plugin author feature request and _not_ for the end-user.

### Have you read the [Contributing Guidelines on issues](https://github.com/facebook/docusaurus/blob/main/CONTRIBUTING.md#reporting-new-issues)?

Yes

### Has this been requested on [Canny](https://docusaurus.io/feedback)?

No

## Motivation

Plugin authors can utilize the `loadContent` life-cycle ([docs](https://docusaurus.io/docs/lifecycle-apis#async-loadcontent)) to async/sync load content needed for the plugin. However, this method is called _every time_ a file is changed while the development server is running.

Typically this is ok and _wanted_ functionality, but if the code within `loadContent` takes a considerable amount of time to process, then the entire experience is degraded. I ran into this while building [docusaurus-plugin-typedoc-api](https://github.com/milesj/docusaurus-plugin-typedoc-api/blob/master/packages/plugin/src/index.ts#L91), as the TypeDoc build process is rather slow (roughly 30 seconds).

To help alleviate this problem we can cache the long processes, _but_ there is no way to invalidate the cache, _or_ know when we should rebuild.

## API Design

My proposal is to pass a "build state" object to the `loadContent` life-cycle method. This object would contain the following properties:

- `firstLoad` (`boolean`) - A flag representing the 1st time `loadContent` is called. Triggered by both `build` and `start`. This will allow authors to effectively cache miss on new builds.
- `changedFiles` (`string[]`) - A list of files that have changed since the last rebuild/reload. This will allow authors to determine whether to cache hit/miss based on file paths/extensions.

Using my TypeDoc problem above, an example of this in practice would look something like.

```ts
async loadContent({ firstLoad, changedFiles }) {
const cachePath = path.join(context.generatedFilesDir, 'typedoc.json');
const hasTsFiles = changedFiles.some(file => file.match(/\.tsx?$/));

// Run TypeDoc and write to cache if first load or TS files have changed
if (firstLoad || hasTsFiles) {
await generateTypeDocJson(cachePath);
}

return import(cachePath);
}
```

## Have you tried building it?

No, not yet...

I have tried to detect whether a rebuild is happening, but there's no way to persist plugin state. For example, the following does not work, it always logs `1`.

```ts
export default function() {
let count = 0;

return {
async loadContent() {
count += 1;
console.log(count);
}
};
}
```

Have also looked into environment variables, but nothing related to rebuilds.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.