From fe21ca9d41006a01ca5966d37d6e9cc8558e919e Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 17 Oct 2024 14:46:59 +0200 Subject: [PATCH 1/5] Official Rsdoctor plugin --- .../docusaurus-plugin-rsdoctor/.npmignore | 3 + packages/docusaurus-plugin-rsdoctor/README.md | 7 ++ .../docusaurus-plugin-rsdoctor/package.json | 35 ++++++ .../src/__tests__/options.test.ts | 102 ++++++++++++++++++ .../docusaurus-plugin-rsdoctor/src/index.ts | 59 ++++++++++ .../docusaurus-plugin-rsdoctor/src/options.ts | 34 ++++++ .../docusaurus-plugin-rsdoctor/src/types.d.ts | 8 ++ .../docusaurus-plugin-rsdoctor/tsconfig.json | 8 ++ website/docusaurus.config.ts | 19 +++- website/package.json | 3 +- .../src/plugins/rsdoctor/RsdoctorPlugin.ts | 50 --------- 11 files changed, 274 insertions(+), 54 deletions(-) create mode 100644 packages/docusaurus-plugin-rsdoctor/.npmignore create mode 100644 packages/docusaurus-plugin-rsdoctor/README.md create mode 100644 packages/docusaurus-plugin-rsdoctor/package.json create mode 100644 packages/docusaurus-plugin-rsdoctor/src/__tests__/options.test.ts create mode 100644 packages/docusaurus-plugin-rsdoctor/src/index.ts create mode 100644 packages/docusaurus-plugin-rsdoctor/src/options.ts create mode 100644 packages/docusaurus-plugin-rsdoctor/src/types.d.ts create mode 100644 packages/docusaurus-plugin-rsdoctor/tsconfig.json delete mode 100644 website/src/plugins/rsdoctor/RsdoctorPlugin.ts diff --git a/packages/docusaurus-plugin-rsdoctor/.npmignore b/packages/docusaurus-plugin-rsdoctor/.npmignore new file mode 100644 index 000000000000..03c9ae1e1b54 --- /dev/null +++ b/packages/docusaurus-plugin-rsdoctor/.npmignore @@ -0,0 +1,3 @@ +.tsbuildinfo* +tsconfig* +__tests__ diff --git a/packages/docusaurus-plugin-rsdoctor/README.md b/packages/docusaurus-plugin-rsdoctor/README.md new file mode 100644 index 000000000000..88336d6c4f1e --- /dev/null +++ b/packages/docusaurus-plugin-rsdoctor/README.md @@ -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). diff --git a/packages/docusaurus-plugin-rsdoctor/package.json b/packages/docusaurus-plugin-rsdoctor/package.json new file mode 100644 index 000000000000..17a11a918cdd --- /dev/null +++ b/packages/docusaurus-plugin-rsdoctor/package.json @@ -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" + } +} diff --git a/packages/docusaurus-plugin-rsdoctor/src/__tests__/options.test.ts b/packages/docusaurus-plugin-rsdoctor/src/__tests__/options.test.ts new file mode 100644 index 000000000000..f61daad45187 --- /dev/null +++ b/packages/docusaurus-plugin-rsdoctor/src/__tests__/options.test.ts @@ -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"`, + ); + }); + }); +}); diff --git a/packages/docusaurus-plugin-rsdoctor/src/index.ts b/packages/docusaurus-plugin-rsdoctor/src/index.ts new file mode 100644 index 000000000000..e9bf357419f4 --- /dev/null +++ b/packages/docusaurus-plugin-rsdoctor/src/index.ts @@ -0,0 +1,59 @@ +/** + * 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 { + if (!process.env.RSDOCTOR) { + return null; + } + console.log('Rsdoctor plugin enabled'); + return { + name: 'docusaurus-plugin-rsdoctor', + configureWebpack: (__config, isServer) => { + return { + plugins: [ + createRsdoctorBundlerPlugin({ + isServer, + currentBundler: context.currentBundler, + options, + }), + ], + }; + }, + }; +}); + +export {validateOptions} from './options'; + +export type {PluginOptions, Options}; diff --git a/packages/docusaurus-plugin-rsdoctor/src/options.ts b/packages/docusaurus-plugin-rsdoctor/src/options.ts new file mode 100644 index 000000000000..9dcbda2aa50c --- /dev/null +++ b/packages/docusaurus-plugin-rsdoctor/src/options.ts @@ -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; +}; + +export type Options = { + rsdoctorOptions?: Record; +}; + +export const DEFAULT_OPTIONS: Partial = { + rsdoctorOptions: {}, +}; + +const pluginOptionsSchema = Joi.object({ + rsdoctorOptions: Joi.object() + .pattern(Joi.string(), Joi.any()) + .optional() + .default(DEFAULT_OPTIONS.rsdoctorOptions), +}).default(DEFAULT_OPTIONS); + +export function validateOptions({ + validate, + options, +}: OptionValidationContext): PluginOptions { + return validate(pluginOptionsSchema, options); +} diff --git a/packages/docusaurus-plugin-rsdoctor/src/types.d.ts b/packages/docusaurus-plugin-rsdoctor/src/types.d.ts new file mode 100644 index 000000000000..6f6f99f12793 --- /dev/null +++ b/packages/docusaurus-plugin-rsdoctor/src/types.d.ts @@ -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. + */ + +/// diff --git a/packages/docusaurus-plugin-rsdoctor/tsconfig.json b/packages/docusaurus-plugin-rsdoctor/tsconfig.json new file mode 100644 index 000000000000..343f87c70bdc --- /dev/null +++ b/packages/docusaurus-plugin-rsdoctor/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": false + }, + "include": ["src"], + "exclude": ["**/__tests__/**"] +} diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 228aafcbc813..6e582f547f47 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -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'; @@ -259,7 +258,23 @@ export default async function createConfigAsync() { ], themes: ['live-codeblock', ...dogfoodingThemeInstances], plugins: [ - RsdoctorPlugin, + [ + 'rsdoctor', + { + rsdoctorOptions: { + disableTOSUpload: true, + supports: { + // https://rsdoctor.dev/config/options/options#generatetilegraph + generateTileGraph: true, + }, + linter: { + rules: { + 'ecma-version-check': 'off', + }, + }, + }, + }, + ], [ './src/plugins/changelog/index.js', { diff --git a/website/package.json b/website/package.json index a631805ef5d3..770d02245290 100644 --- a/website/package.json +++ b/website/package.json @@ -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", diff --git a/website/src/plugins/rsdoctor/RsdoctorPlugin.ts b/website/src/plugins/rsdoctor/RsdoctorPlugin.ts deleted file mode 100644 index edad0cc00942..000000000000 --- a/website/src/plugins/rsdoctor/RsdoctorPlugin.ts +++ /dev/null @@ -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); From 8a1a31115fb288afd8f7a8fbdfcf532651adb5b1 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 17 Oct 2024 16:53:04 +0200 Subject: [PATCH 2/5] move env variable --- packages/docusaurus-plugin-rsdoctor/src/index.ts | 4 ---- website/docusaurus.config.ts | 6 +++++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/docusaurus-plugin-rsdoctor/src/index.ts b/packages/docusaurus-plugin-rsdoctor/src/index.ts index e9bf357419f4..d43412823bcd 100644 --- a/packages/docusaurus-plugin-rsdoctor/src/index.ts +++ b/packages/docusaurus-plugin-rsdoctor/src/index.ts @@ -34,10 +34,6 @@ export default (async function pluginRsdoctor( context: LoadContext, options: PluginOptions, ): Promise { - if (!process.env.RSDOCTOR) { - return null; - } - console.log('Rsdoctor plugin enabled'); return { name: 'docusaurus-plugin-rsdoctor', configureWebpack: (__config, isServer) => { diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 6e582f547f47..7ae2a4c9b7a2 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -128,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 = ''; @@ -258,7 +260,7 @@ export default async function createConfigAsync() { ], themes: ['live-codeblock', ...dogfoodingThemeInstances], plugins: [ - [ + isRsdoctor && [ 'rsdoctor', { rsdoctorOptions: { @@ -268,8 +270,10 @@ export default async function createConfigAsync() { generateTileGraph: true, }, linter: { + // See https://rsdoctor.dev/guide/usage/rule-config rules: { 'ecma-version-check': 'off', + 'duplicate-package': 'off', }, }, }, From 3f1388408b70c43197b7b6c6b864edd698d6ae47 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 17 Oct 2024 17:01:45 +0200 Subject: [PATCH 3/5] add docs --- website/docs/api/plugins/plugin-rsdoctor.mdx | 51 ++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 website/docs/api/plugins/plugin-rsdoctor.mdx diff --git a/website/docs/api/plugins/plugin-rsdoctor.mdx b/website/docs/api/plugins/plugin-rsdoctor.mdx new file mode 100644 index 000000000000..33710d221784 --- /dev/null +++ b/website/docs/api/plugins/plugin-rsdoctor.mdx @@ -0,0 +1,51 @@ +--- +sidebar_position: 7 +slug: /api/plugins/@docusaurus/plugin-google-gtag +--- + +# 📦 plugin-rsdoctor + +import APITable from '@site/src/components/APITable'; + +A [Rsdoctor](https://rsdoctor.dev/) plugin can help you troubleshoot the bundling of your Docusaurus app. It can help you figure out which plugin or loader is slowing down the bundler, so you can focus your efforts on optimizing what matters. It supports both Webpack and Rspack bundlers. + +## Installation {#installation} + +```bash npm2yarn +npm install --save @docusaurus/plugin-rsdoctor +``` + +## Configuration {#configuration} + +Accepted fields: + +```mdx-code-block + +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `rsdoctorOptions` | `object` | `{}` | The [Rsdoctor options](https://rsdoctor.dev/config/options/options) | + +```mdx-code-block + +``` + +### Example configuration {#ex-config} + +You can configure this plugin through plugin options. + +```js title="docusaurus.config.js" +export default { + plugins: [ + [ + 'rsdoctor', + { + rsdoctorOptions: { + mode: 'lite', + }, + }, + ], + ], +}; +``` From b4d231497cb2fe3a2d7f99432009fc6a5b8fa3a2 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 17 Oct 2024 17:02:37 +0200 Subject: [PATCH 4/5] fix slug --- website/docs/api/plugins/plugin-rsdoctor.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/api/plugins/plugin-rsdoctor.mdx b/website/docs/api/plugins/plugin-rsdoctor.mdx index 33710d221784..2b9efb059034 100644 --- a/website/docs/api/plugins/plugin-rsdoctor.mdx +++ b/website/docs/api/plugins/plugin-rsdoctor.mdx @@ -1,6 +1,6 @@ --- sidebar_position: 7 -slug: /api/plugins/@docusaurus/plugin-google-gtag +slug: /api/plugins/@docusaurus/plugin-rsdoctor --- # 📦 plugin-rsdoctor From 1019fd3ab71793b3386d184626dac217720e86f7 Mon Sep 17 00:00:00 2001 From: sebastien Date: Thu, 17 Oct 2024 17:07:28 +0200 Subject: [PATCH 5/5] docs --- website/docs/api/plugins/plugin-rsdoctor.mdx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/website/docs/api/plugins/plugin-rsdoctor.mdx b/website/docs/api/plugins/plugin-rsdoctor.mdx index 2b9efb059034..100d714893d4 100644 --- a/website/docs/api/plugins/plugin-rsdoctor.mdx +++ b/website/docs/api/plugins/plugin-rsdoctor.mdx @@ -7,7 +7,13 @@ slug: /api/plugins/@docusaurus/plugin-rsdoctor import APITable from '@site/src/components/APITable'; -A [Rsdoctor](https://rsdoctor.dev/) plugin can help you troubleshoot the bundling of your Docusaurus app. It can help you figure out which plugin or loader is slowing down the bundler, so you can focus your efforts on optimizing what matters. It supports both Webpack and Rspack bundlers. +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} @@ -25,7 +31,7 @@ Accepted fields: | Name | Type | Default | Description | | --- | --- | --- | --- | -| `rsdoctorOptions` | `object` | `{}` | The [Rsdoctor options](https://rsdoctor.dev/config/options/options) | +| `rsdoctorOptions` | `object` | `{}` | The [Rsdoctor bundler plugin options](https://rsdoctor.dev/config/options/options), forwarded as is | ```mdx-code-block