mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-03 11:22:30 +02:00
feat: new Rsdoctor official plugin (#10588)
This commit is contained in:
parent
f6a6ca899f
commit
24716787d3
12 changed files with 331 additions and 54 deletions
3
packages/docusaurus-plugin-rsdoctor/.npmignore
Normal file
3
packages/docusaurus-plugin-rsdoctor/.npmignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
.tsbuildinfo*
|
||||
tsconfig*
|
||||
__tests__
|
7
packages/docusaurus-plugin-rsdoctor/README.md
Normal file
7
packages/docusaurus-plugin-rsdoctor/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# `@docusaurus/plugin-rsdoctor`
|
||||
|
||||
[Rsdoctor](https://rsdoctor.dev/) plugin for Docusaurus.
|
||||
|
||||
## Usage
|
||||
|
||||
See [plugin-rsdoctor documentation](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-rsdoctor).
|
35
packages/docusaurus-plugin-rsdoctor/package.json
Normal file
35
packages/docusaurus-plugin-rsdoctor/package.json
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "@docusaurus/plugin-rsdoctor",
|
||||
"version": "3.5.2",
|
||||
"description": "Rsdoctor plugin for Docusaurus.",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsc --build",
|
||||
"watch": "tsc --build --watch"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/docusaurus.git",
|
||||
"directory": "packages/docusaurus-plugin-rsdoctor"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.5.2",
|
||||
"@docusaurus/types": "3.5.2",
|
||||
"@docusaurus/utils-validation": "3.5.2",
|
||||
"@rsdoctor/webpack-plugin": "^0.4.6",
|
||||
"@rsdoctor/rspack-plugin": "^0.4.6",
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {normalizePluginOptions} from '@docusaurus/utils-validation';
|
||||
import {
|
||||
validateOptions,
|
||||
type PluginOptions,
|
||||
type Options,
|
||||
DEFAULT_OPTIONS,
|
||||
} from '../options';
|
||||
import type {Validate} from '@docusaurus/types';
|
||||
|
||||
function validate(options?: Options) {
|
||||
return validateOptions({
|
||||
validate: normalizePluginOptions as Validate<
|
||||
Options | undefined,
|
||||
PluginOptions
|
||||
>,
|
||||
options,
|
||||
});
|
||||
}
|
||||
|
||||
function result(options?: Options) {
|
||||
return {
|
||||
id: 'default',
|
||||
...DEFAULT_OPTIONS,
|
||||
...options,
|
||||
};
|
||||
}
|
||||
|
||||
describe('validateOptions', () => {
|
||||
it('accepts undefined', () => {
|
||||
expect(validate(undefined)).toEqual(result(DEFAULT_OPTIONS));
|
||||
});
|
||||
|
||||
it('accepts empty object', () => {
|
||||
expect(validate({})).toEqual(result(DEFAULT_OPTIONS));
|
||||
});
|
||||
|
||||
it('accepts defaults', () => {
|
||||
expect(validate(DEFAULT_OPTIONS)).toEqual(result(DEFAULT_OPTIONS));
|
||||
});
|
||||
|
||||
it('rejects null', () => {
|
||||
expect(
|
||||
// @ts-expect-error: TS should error
|
||||
() => validate(null),
|
||||
).toThrowErrorMatchingInlineSnapshot(`""value" must be of type object"`);
|
||||
});
|
||||
|
||||
it('rejects number', () => {
|
||||
expect(
|
||||
// @ts-expect-error: TS should error
|
||||
() => validate(42),
|
||||
).toThrowErrorMatchingInlineSnapshot(`""value" must be of type object"`);
|
||||
});
|
||||
|
||||
describe('rsdoctorOptions', () => {
|
||||
it('accepts undefined', () => {
|
||||
expect(validate({rsdoctorOptions: undefined})).toEqual(
|
||||
result(DEFAULT_OPTIONS),
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts empty', () => {
|
||||
expect(validate({rsdoctorOptions: {}})).toEqual(result(DEFAULT_OPTIONS));
|
||||
});
|
||||
|
||||
it('accepts any record', () => {
|
||||
expect(
|
||||
validate({rsdoctorOptions: {any: 'value', evenNumbers: 42}}),
|
||||
).toEqual(
|
||||
result({
|
||||
...DEFAULT_OPTIONS,
|
||||
rsdoctorOptions: {
|
||||
any: 'value',
|
||||
evenNumbers: 42,
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts default', () => {
|
||||
expect(
|
||||
validate({rsdoctorOptions: DEFAULT_OPTIONS.rsdoctorOptions}),
|
||||
).toEqual(result(DEFAULT_OPTIONS));
|
||||
});
|
||||
|
||||
it('rejects number values', () => {
|
||||
expect(() =>
|
||||
// @ts-expect-error: invalid type
|
||||
validate({rsdoctorOptions: 42}),
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
`""rsdoctorOptions" must be of type object"`,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
55
packages/docusaurus-plugin-rsdoctor/src/index.ts
Normal file
55
packages/docusaurus-plugin-rsdoctor/src/index.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {RsdoctorRspackMultiplePlugin} from '@rsdoctor/rspack-plugin';
|
||||
import {RsdoctorWebpackMultiplePlugin} from '@rsdoctor/webpack-plugin';
|
||||
import type {CurrentBundler, LoadContext, Plugin} from '@docusaurus/types';
|
||||
import type {PluginOptions, Options} from './options';
|
||||
|
||||
function createRsdoctorBundlerPlugin({
|
||||
isServer,
|
||||
currentBundler,
|
||||
options,
|
||||
}: {
|
||||
isServer: boolean;
|
||||
currentBundler: CurrentBundler;
|
||||
options: PluginOptions;
|
||||
}) {
|
||||
const RsdoctorPlugin =
|
||||
currentBundler.name === 'rspack'
|
||||
? RsdoctorRspackMultiplePlugin
|
||||
: RsdoctorWebpackMultiplePlugin;
|
||||
|
||||
return new RsdoctorPlugin({
|
||||
name: isServer ? 'server' : 'client',
|
||||
...options.rsdoctorOptions,
|
||||
});
|
||||
}
|
||||
|
||||
export default (async function pluginRsdoctor(
|
||||
context: LoadContext,
|
||||
options: PluginOptions,
|
||||
): Promise<Plugin | null> {
|
||||
return {
|
||||
name: 'docusaurus-plugin-rsdoctor',
|
||||
configureWebpack: (__config, isServer) => {
|
||||
return {
|
||||
plugins: [
|
||||
createRsdoctorBundlerPlugin({
|
||||
isServer,
|
||||
currentBundler: context.currentBundler,
|
||||
options,
|
||||
}),
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export {validateOptions} from './options';
|
||||
|
||||
export type {PluginOptions, Options};
|
34
packages/docusaurus-plugin-rsdoctor/src/options.ts
Normal file
34
packages/docusaurus-plugin-rsdoctor/src/options.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
import {Joi} from '@docusaurus/utils-validation';
|
||||
import type {OptionValidationContext} from '@docusaurus/types';
|
||||
|
||||
export type PluginOptions = {
|
||||
rsdoctorOptions: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type Options = {
|
||||
rsdoctorOptions?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export const DEFAULT_OPTIONS: Partial<PluginOptions> = {
|
||||
rsdoctorOptions: {},
|
||||
};
|
||||
|
||||
const pluginOptionsSchema = Joi.object<PluginOptions>({
|
||||
rsdoctorOptions: Joi.object()
|
||||
.pattern(Joi.string(), Joi.any())
|
||||
.optional()
|
||||
.default(DEFAULT_OPTIONS.rsdoctorOptions),
|
||||
}).default(DEFAULT_OPTIONS);
|
||||
|
||||
export function validateOptions({
|
||||
validate,
|
||||
options,
|
||||
}: OptionValidationContext<Options | undefined, PluginOptions>): PluginOptions {
|
||||
return validate(pluginOptionsSchema, options);
|
||||
}
|
8
packages/docusaurus-plugin-rsdoctor/src/types.d.ts
vendored
Normal file
8
packages/docusaurus-plugin-rsdoctor/src/types.d.ts
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/// <reference types="@docusaurus/module-type-aliases" />
|
8
packages/docusaurus-plugin-rsdoctor/tsconfig.json
Normal file
8
packages/docusaurus-plugin-rsdoctor/tsconfig.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": false
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["**/__tests__/**"]
|
||||
}
|
57
website/docs/api/plugins/plugin-rsdoctor.mdx
Normal file
57
website/docs/api/plugins/plugin-rsdoctor.mdx
Normal file
|
@ -0,0 +1,57 @@
|
|||
---
|
||||
sidebar_position: 7
|
||||
slug: /api/plugins/@docusaurus/plugin-rsdoctor
|
||||
---
|
||||
|
||||
# 📦 plugin-rsdoctor
|
||||
|
||||
import APITable from '@site/src/components/APITable';
|
||||
|
||||
A [Rsdoctor](https://rsdoctor.dev/) plugin can help you troubleshoot the bundling phase of your Docusaurus site, supporting both Webpack and Rspack.
|
||||
|
||||
:::tip
|
||||
|
||||
Use it to figure out which plugin or loader is slowing down the bundler, and focus your efforts on optimizing the bottleneck.
|
||||
|
||||
:::
|
||||
|
||||
## Installation {#installation}
|
||||
|
||||
```bash npm2yarn
|
||||
npm install --save @docusaurus/plugin-rsdoctor
|
||||
```
|
||||
|
||||
## Configuration {#configuration}
|
||||
|
||||
Accepted fields:
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `rsdoctorOptions` | `object` | `{}` | The [Rsdoctor bundler plugin options](https://rsdoctor.dev/config/options/options), forwarded as is |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
### Example configuration {#ex-config}
|
||||
|
||||
You can configure this plugin through plugin options.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
plugins: [
|
||||
[
|
||||
'rsdoctor',
|
||||
{
|
||||
rsdoctorOptions: {
|
||||
mode: 'lite',
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
|
@ -9,7 +9,6 @@ import npm2yarn from '@docusaurus/remark-plugin-npm2yarn';
|
|||
import remarkMath from 'remark-math';
|
||||
import rehypeKatex from 'rehype-katex';
|
||||
import configTabs from './src/remark/configTabs';
|
||||
import RsdoctorPlugin from './src/plugins/rsdoctor/RsdoctorPlugin';
|
||||
|
||||
import versions from './versions.json';
|
||||
import VersionsArchived from './versionsArchived.json';
|
||||
|
@ -129,6 +128,8 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
|||
|
||||
const isVersioningDisabled = !!process.env.DISABLE_VERSIONING || isI18nStaging;
|
||||
|
||||
const isRsdoctor = process.env.RSDOCTOR === 'true';
|
||||
|
||||
/*
|
||||
const TwitterSvg =
|
||||
'<svg style="fill: #1DA1F2; vertical-align: middle; margin-left: 3px;" width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"></path></svg>';
|
||||
|
@ -259,7 +260,25 @@ export default async function createConfigAsync() {
|
|||
],
|
||||
themes: ['live-codeblock', ...dogfoodingThemeInstances],
|
||||
plugins: [
|
||||
RsdoctorPlugin,
|
||||
isRsdoctor && [
|
||||
'rsdoctor',
|
||||
{
|
||||
rsdoctorOptions: {
|
||||
disableTOSUpload: true,
|
||||
supports: {
|
||||
// https://rsdoctor.dev/config/options/options#generatetilegraph
|
||||
generateTileGraph: true,
|
||||
},
|
||||
linter: {
|
||||
// See https://rsdoctor.dev/guide/usage/rule-config
|
||||
rules: {
|
||||
'ecma-version-check': 'off',
|
||||
'duplicate-package': 'off',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
'./src/plugins/changelog/index.js',
|
||||
{
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
"@docusaurus/plugin-client-redirects": "3.5.2",
|
||||
"@docusaurus/plugin-ideal-image": "3.5.2",
|
||||
"@docusaurus/plugin-pwa": "3.5.2",
|
||||
"@docusaurus/plugin-rsdoctor": "3.5.2",
|
||||
"@docusaurus/preset-classic": "3.5.2",
|
||||
"@docusaurus/remark-plugin-npm2yarn": "3.5.2",
|
||||
"@docusaurus/theme-classic": "3.5.2",
|
||||
|
@ -84,8 +85,6 @@
|
|||
"devDependencies": {
|
||||
"@docusaurus/eslint-plugin": "3.5.2",
|
||||
"@docusaurus/tsconfig": "3.5.2",
|
||||
"@rsdoctor/webpack-plugin": "^0.4.6",
|
||||
"@rsdoctor/rspack-plugin": "^0.4.6",
|
||||
"@types/color": "^3.0.4",
|
||||
"@types/jest": "^29.5.3",
|
||||
"cross-env": "^7.0.3",
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import type {PluginConfig} from '@docusaurus/types';
|
||||
|
||||
function createRsdoctorBundlerPlugin({isServer}: {isServer: boolean}) {
|
||||
// TODO Shitty workaround to bypass lib typechecking
|
||||
// package does not work will with skipLibCheck false
|
||||
// // eslint-disable-next-line
|
||||
// const {RsdoctorWebpackMultiplePlugin} = require('@rsdoctor/webpack-plugin');
|
||||
// eslint-disable-next-line
|
||||
const {RsdoctorRspackMultiplePlugin} = require('@rsdoctor/rspack-plugin');
|
||||
|
||||
// return new RsdoctorWebpackMultiplePlugin({
|
||||
return new RsdoctorRspackMultiplePlugin({
|
||||
name: isServer ? 'server' : 'client',
|
||||
disableTOSUpload: true,
|
||||
supports: {
|
||||
// https://rsdoctor.dev/config/options/options#generatetilegraph
|
||||
generateTileGraph: true,
|
||||
},
|
||||
linter: {
|
||||
rules: {
|
||||
'ecma-version-check': 'off',
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export default (async function RsdoctorPlugin() {
|
||||
if (!process.env.RSDOCTOR) {
|
||||
return null;
|
||||
}
|
||||
const pluginClient = await createRsdoctorBundlerPlugin({isServer: false});
|
||||
const pluginServer = await createRsdoctorBundlerPlugin({isServer: true});
|
||||
console.log('Rsdoctor plugin enabled');
|
||||
return {
|
||||
name: 'rsdoctor-plugin',
|
||||
configureWebpack: (__config, isServer) => {
|
||||
const plugin = isServer ? pluginServer : pluginClient;
|
||||
return {
|
||||
plugins: [plugin],
|
||||
};
|
||||
},
|
||||
};
|
||||
} satisfies PluginConfig);
|
Loading…
Add table
Add a link
Reference in a new issue