facebook / facebook/docusaurus
Feature: Enable Plugin loadContent caching, improve plugin reload perf
- Lingua principale
- TypeScript
- Stelle
- 66.2k
- Fork
- 10k
- Merge medio
- 1g 3h
- PR unite (30g)
- 52
Descrizione
## 🚀 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.
Guida per i contributori
Apri la guida per i contributori
Valutazione
Questa issue non è ancora stata valutata.