From 10ec0c213f76dd20208524abd9003c1470f45636 Mon Sep 17 00:00:00 2001 From: slorber Date: Mon, 31 Aug 2020 16:13:18 +0200 Subject: [PATCH 1/4] docs options.onlyIncludeVersions --- .../src/__tests__/versions.test.ts | 58 ++++++++++++++++++- .../src/options.ts | 1 + .../src/types.ts | 1 + .../src/versions.ts | 56 ++++++++++++++++-- website/docs/using-plugins.md | 5 ++ website/docusaurus.config.js | 4 ++ yarn.lock | 4 +- 7 files changed, 121 insertions(+), 8 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts index c8c2f1cb35cb..321c06b32ead 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts @@ -146,7 +146,7 @@ describe('simple site', () => { context: defaultContext, }), ).toThrowErrorMatchingInlineSnapshot( - `"Docs versions option provided configuration for unknown versions: unknownVersionName1,unknownVersionName2. Available version names are: current"`, + `"Bad docs options.versions: unknown versions found: unknownVersionName1,unknownVersionName2. Available version names are: current"`, ); }); @@ -297,6 +297,19 @@ describe('versioned site, pluginId=default', () => { ]); }); + test('readVersionsMetadata versioned site with onlyIncludeVersions option', () => { + const versionsMetadata = readVersionsMetadata({ + options: { + ...defaultOptions, + // Order reversed on purpose: should not have any impact + onlyIncludeVersions: [vwithSlugs.versionName, v101.versionName], + }, + context: defaultContext, + }); + + expect(versionsMetadata).toEqual([v101, vwithSlugs]); + }); + test('readVersionsMetadata versioned site with disableVersioning', () => { const versionsMetadata = readVersionsMetadata({ options: {...defaultOptions, disableVersioning: true}, @@ -323,6 +336,49 @@ describe('versioned site, pluginId=default', () => { ); }); + test('readVersionsMetadata versioned site with empty onlyIncludeVersions', () => { + expect(() => + readVersionsMetadata({ + options: { + ...defaultOptions, + onlyIncludeVersions: [], + }, + context: defaultContext, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Bad docs options.onlyIncludeVersions: an empty array is not allowed, at least one version is needed"`, + ); + }); + + test('readVersionsMetadata versioned site with unknown versions in onlyIncludeVersions', () => { + expect(() => + readVersionsMetadata({ + options: { + ...defaultOptions, + onlyIncludeVersions: ['unknownVersion1', 'unknownVersion2'], + }, + context: defaultContext, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Bad docs options.onlyIncludeVersions: unknown versions found: unknownVersion1,unknownVersion2. unknownVersion1,unknownVersion2"`, + ); + }); + + test('readVersionsMetadata versioned site with lastVersion not in onlyIncludeVersions', () => { + expect(() => + readVersionsMetadata({ + options: { + ...defaultOptions, + lastVersion: '1.0.1', + onlyIncludeVersions: ['current', '1.0.0'], + }, + context: defaultContext, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Bad docs options.lastVersion: if you use both the onlyIncludeVersions and lastVersion options, then lastVersion must be present in the provided onlyIncludeVersions array"`, + ); + }); + test('readVersionsMetadata versioned site with invalid versions.json file', () => { const mock = jest.spyOn(JSON, 'parse').mockImplementationOnce(() => { return { diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index 867a69d9e9a5..f1911bb127da 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -68,6 +68,7 @@ export const OptionsSchema = Joi.object({ includeCurrentVersion: Joi.bool().default( DEFAULT_OPTIONS.includeCurrentVersion, ), + onlyIncludeVersions: Joi.array().items(Joi.string().required()).optional(), disableVersioning: Joi.bool().default(DEFAULT_OPTIONS.disableVersioning), lastVersion: Joi.string().optional(), versions: VersionsOptionsSchema, diff --git a/packages/docusaurus-plugin-content-docs/src/types.ts b/packages/docusaurus-plugin-content-docs/src/types.ts index fbb0b9593087..674eaf0053eb 100644 --- a/packages/docusaurus-plugin-content-docs/src/types.ts +++ b/packages/docusaurus-plugin-content-docs/src/types.ts @@ -47,6 +47,7 @@ export type VersionOptions = { export type VersionsOptions = { lastVersion?: string; versions: Record; + onlyIncludeVersions?: string[]; }; export type PluginOptions = MetadataOptions & diff --git a/packages/docusaurus-plugin-content-docs/src/versions.ts b/packages/docusaurus-plugin-content-docs/src/versions.ts index 04e3a19c00dd..b1e3a487dfbc 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions.ts @@ -257,17 +257,60 @@ function checkVersionsOptions( `Docs option lastVersion=${options.lastVersion} is invalid. ${availableVersionNamesMsg}`, ); } - const unknownVersionNames = difference( + const unknownVersionConfigNames = difference( Object.keys(options.versions), availableVersionNames, ); - if (unknownVersionNames.length > 0) { + if (unknownVersionConfigNames.length > 0) { throw new Error( - `Docs versions option provided configuration for unknown versions: ${unknownVersionNames.join( + `Bad docs options.versions: unknown versions found: ${unknownVersionConfigNames.join( ',', )}. ${availableVersionNamesMsg}`, ); } + + if (options.onlyIncludeVersions) { + if (options.onlyIncludeVersions.length === 0) { + throw new Error( + `Bad docs options.onlyIncludeVersions: an empty array is not allowed, at least one version is needed`, + ); + } + const unknownOnlyIncludeVersionNames = difference( + options.onlyIncludeVersions, + availableVersionNames, + ); + if (unknownOnlyIncludeVersionNames.length > 0) { + throw new Error( + `Bad docs options.onlyIncludeVersions: unknown versions found: ${unknownOnlyIncludeVersionNames.join( + ',', + )}. ${unknownOnlyIncludeVersionNames}`, + ); + } + if ( + options.lastVersion && + !options.onlyIncludeVersions.includes(options.lastVersion) + ) { + throw new Error( + `Bad docs options.lastVersion: if you use both the onlyIncludeVersions and lastVersion options, then lastVersion must be present in the provided onlyIncludeVersions array`, + ); + } + } +} + +// Filter versions according to provided options +// Note: we preserve the order in which versions are provided +// the order of the onlyIncludeVersions array does not matter +function filterVersions( + versionNamesUnfiltered: string[], + options: Pick, +) { + if (options.onlyIncludeVersions) { + return versionNamesUnfiltered.filter((name) => + options.onlyIncludeVersions!.includes(name), + ); + } else { + return versionNamesUnfiltered; + } } export function readVersionsMetadata({ @@ -285,11 +328,14 @@ export function readVersionsMetadata({ | 'disableVersioning' | 'lastVersion' | 'versions' + | 'onlyIncludeVersions' >; }): VersionMetadata[] { - const versionNames = readVersionNames(context.siteDir, options); + const versionNamesUnfiltered = readVersionNames(context.siteDir, options); + + checkVersionsOptions(versionNamesUnfiltered, options); - checkVersionsOptions(versionNames, options); + const versionNames = filterVersions(versionNamesUnfiltered, options); const lastVersionName = options.lastVersion ?? getDefaultLastVersionName(versionNames); diff --git a/website/docs/using-plugins.md b/website/docs/using-plugins.md index 1249c8d47b51..d01a9992782c 100644 --- a/website/docs/using-plugins.md +++ b/website/docs/using-plugins.md @@ -362,6 +362,11 @@ module.exports = { }, */ }, + /** + * Sometimes you only want to include a subset of all available versions. + * Tip: limit to 2 or 3 versions to improve startup and build time in dev and deploy previews + */ + onlyIncludeVersions: undefined, // ex: ["current", "1.0.0", "2.0.0"] }, ], ], diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 3f81e10e248a..75675e00ccbe 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -178,6 +178,10 @@ module.exports = { remarkPlugins: [require('./src/plugins/remark-npm2yarn')], disableVersioning: isVersioningDisabled, lastVersion: isDev || isDeployPreview ? 'current' : undefined, + onlyIncludeVersions: + isDev || isDeployPreview + ? ['current', ...versions.slice(0, 2)] + : undefined, versions: { current: { // path: isDev || isDeployPreview ? '' : 'next', diff --git a/yarn.lock b/yarn.lock index d8c76bff5181..f32848ee48f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17722,7 +17722,7 @@ react-dev-utils@^9.1.0: strip-ansi "5.2.0" text-table "0.2.0" -react-dom@^16.10.2, react-dom@^16.8.4: +react-dom@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag== @@ -17902,7 +17902,7 @@ react-waypoint@^9.0.2: prop-types "^15.0.0" react-is "^16.6.3" -react@^16.10.2, react@^16.8.4: +react@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== From 960045f41556e1855f8902e5b3c3c3a6ac6df8ca Mon Sep 17 00:00:00 2001 From: slorber Date: Mon, 31 Aug 2020 16:28:03 +0200 Subject: [PATCH 2/4] adapt docsVersionDropdown if we render a single version --- .../DocsVersionDropdownNavbarItem.tsx | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx index 7701f9d83516..d7fd5a073292 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx @@ -26,19 +26,28 @@ export default function DocsVersionDropdownNavbarItem({ const versions = useVersions(docsPluginId); const latestVersion = useLatestVersion(docsPluginId); - const items = versions.map((version) => { - // We try to link to the same doc, in another version - // When not possible, fallback to the "main doc" of the version - const versionDoc = - activeDocContext?.alternateDocVersions[version.name] || - getVersionMainDoc(version); - return { - isNavLink: true, - label: version.label, - to: versionDoc.path, - isActive: () => version === activeDocContext?.activeVersion, - }; - }); + function getItems() { + // We don't want to render a version dropdown with 0 or 1 item + // If we build the site with a single docs version (onlyIncludeVersions: ['1.0.0']) + // We'd rather render a buttonb instead of a dropdown + if (versions.length <= 2) { + return undefined; + } + + return versions.map((version) => { + // We try to link to the same doc, in another version + // When not possible, fallback to the "main doc" of the version + const versionDoc = + activeDocContext?.alternateDocVersions[version.name] || + getVersionMainDoc(version); + return { + isNavLink: true, + label: version.label, + to: versionDoc.path, + isActive: () => version === activeDocContext?.activeVersion, + }; + }); + } const dropdownVersion = activeDocContext.activeVersion ?? latestVersion; @@ -54,7 +63,7 @@ export default function DocsVersionDropdownNavbarItem({ mobile={mobile} label={dropdownLabel} to={dropdownTo} - items={items} + items={getItems()} /> ); } From 6c53ff8c36a7c855c7b8cc757ab0ed1165bd2b60 Mon Sep 17 00:00:00 2001 From: slorber Date: Mon, 31 Aug 2020 16:43:28 +0200 Subject: [PATCH 3/4] fix bad error message --- .../src/__tests__/versions.test.ts | 2 +- packages/docusaurus-plugin-content-docs/src/versions.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts index 321c06b32ead..db8bbd2086a2 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts @@ -360,7 +360,7 @@ describe('versioned site, pluginId=default', () => { context: defaultContext, }), ).toThrowErrorMatchingInlineSnapshot( - `"Bad docs options.onlyIncludeVersions: unknown versions found: unknownVersion1,unknownVersion2. unknownVersion1,unknownVersion2"`, + `"Bad docs options.onlyIncludeVersions: unknown versions found: unknownVersion1,unknownVersion2. Available version names are: current, 1.0.1, 1.0.0, withSlugs"`, ); }); diff --git a/packages/docusaurus-plugin-content-docs/src/versions.ts b/packages/docusaurus-plugin-content-docs/src/versions.ts index b1e3a487dfbc..74495c3134ca 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions.ts @@ -283,7 +283,7 @@ function checkVersionsOptions( throw new Error( `Bad docs options.onlyIncludeVersions: unknown versions found: ${unknownOnlyIncludeVersionNames.join( ',', - )}. ${unknownOnlyIncludeVersionNames}`, + )}. ${availableVersionNamesMsg}`, ); } if ( From 27bda1b7235b89477a3af6ab4d562592b3d9466c Mon Sep 17 00:00:00 2001 From: slorber Date: Mon, 31 Aug 2020 16:54:52 +0200 Subject: [PATCH 4/4] fix netlify deploy when versioning is disabled --- website/docusaurus.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 75675e00ccbe..6ec8f7f83dd5 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -179,7 +179,7 @@ module.exports = { disableVersioning: isVersioningDisabled, lastVersion: isDev || isDeployPreview ? 'current' : undefined, onlyIncludeVersions: - isDev || isDeployPreview + !isVersioningDisabled && (isDev || isDeployPreview) ? ['current', ...versions.slice(0, 2)] : undefined, versions: {