Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new Rsdoctor official plugin #10588

Merged
merged 5 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/docusaurus-plugin-rsdoctor/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.tsbuildinfo*
tsconfig*
__tests__
7 changes: 7 additions & 0 deletions packages/docusaurus-plugin-rsdoctor/README.md
Original file line number Diff line number Diff line change
@@ -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 changes: 35 additions & 0 deletions packages/docusaurus-plugin-rsdoctor/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
102 changes: 102 additions & 0 deletions packages/docusaurus-plugin-rsdoctor/src/__tests__/options.test.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 55 additions & 0 deletions packages/docusaurus-plugin-rsdoctor/src/index.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 34 additions & 0 deletions packages/docusaurus-plugin-rsdoctor/src/options.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 8 additions & 0 deletions packages/docusaurus-plugin-rsdoctor/src/types.d.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 8 additions & 0 deletions packages/docusaurus-plugin-rsdoctor/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"noEmit": false
},
"include": ["src"],
"exclude": ["**/__tests__/**"]
}
57 changes: 57 additions & 0 deletions website/docs/api/plugins/plugin-rsdoctor.mdx
Original file line number Diff line number Diff line change
@@ -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',
},
},
],
],
};
```
23 changes: 21 additions & 2 deletions website/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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>';
Expand Down Expand Up @@ -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',
{
Expand Down
3 changes: 1 addition & 2 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
Loading