fix(v2): alpha 62 doc fixes (#3381)

* deprecated nextVersionLabel option

* useActivePlugin failfast option

* remove deprecated option nextVersionLabel

* routeBasePath: '' should be forbidden

* routeBasePath: '' should be forbidden

* Docs: do not show version badge if there is only 1 version: https://github.com/facebook/docusaurus/issues/3362

* allow sidebars file to not exist: fallback to empty sidebars
https://githu.com/facebook/docusaurus/issues/3366
This commit is contained in:
Sébastien Lorber 2020-09-01 16:31:33 +02:00 committed by GitHub
parent 2a3fe86579
commit a4769e3f30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 80 additions and 35 deletions

View file

@ -115,9 +115,13 @@ describe('loadSidebars', () => {
}); });
test('unexisting path', () => { test('unexisting path', () => {
/*
expect(() => loadSidebars('badpath')).toThrowErrorMatchingInlineSnapshot( expect(() => loadSidebars('badpath')).toThrowErrorMatchingInlineSnapshot(
`"No sidebar file exist at path: badpath"`, `"No sidebar file exist at path: badpath"`,
); );
*/
// See https://github.com/facebook/docusaurus/issues/3366
expect(loadSidebars('badpath')).toEqual({});
}); });
test('undefined path', () => { test('undefined path', () => {

View file

@ -32,6 +32,17 @@ describe('docsClientUtils', () => {
expect(getActivePlugin(data, '/')).toEqual(undefined); expect(getActivePlugin(data, '/')).toEqual(undefined);
expect(getActivePlugin(data, '/xyz')).toEqual(undefined); expect(getActivePlugin(data, '/xyz')).toEqual(undefined);
expect(() =>
getActivePlugin(data, '/', {failfast: true}),
).toThrowErrorMatchingInlineSnapshot(
`"Can't find active docs plugin for pathname=/, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`,
);
expect(() =>
getActivePlugin(data, '/xyz', {failfast: true}),
).toThrowErrorMatchingInlineSnapshot(
`"Can't find active docs plugin for pathname=/xyz, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`,
);
const activePluginIos: ActivePlugin = { const activePluginIos: ActivePlugin = {
pluginId: 'pluginIosId', pluginId: 'pluginIosId',
pluginData: data.pluginIosId, pluginData: data.pluginIosId,
@ -115,6 +126,9 @@ describe('docsClientUtils', () => {
}, },
], ],
}; };
expect(getActiveVersion(data, '/someUnknownPath')).toEqual(undefined);
expect(getActiveVersion(data, '/docs/next')?.name).toEqual('next'); expect(getActiveVersion(data, '/docs/next')?.name).toEqual('next');
expect(getActiveVersion(data, '/docs/next/')?.name).toEqual('next'); expect(getActiveVersion(data, '/docs/next/')?.name).toEqual('next');
expect(getActiveVersion(data, '/docs/next/someDoc')?.name).toEqual('next'); expect(getActiveVersion(data, '/docs/next/someDoc')?.name).toEqual('next');

View file

@ -20,13 +20,27 @@ export type ActivePlugin = {
pluginData: GlobalPluginData; pluginData: GlobalPluginData;
}; };
export type GetActivePluginOptions = {failfast?: boolean};
// get the data of the plugin that is currently "active" // get the data of the plugin that is currently "active"
// ie the docs of that plugin are currently browsed // ie the docs of that plugin are currently browsed
// it is useful to support multiple docs plugin instances // it is useful to support multiple docs plugin instances
export const getActivePlugin = ( export function getActivePlugin(
allPluginDatas: Record<string, GlobalPluginData>, allPluginDatas: Record<string, GlobalPluginData>,
pathname: string, pathname: string,
): ActivePlugin | undefined => { options: {failfast: true}, // use fail-fast option if you know for sure one plugin instance is active
): ActivePlugin;
export function getActivePlugin(
allPluginDatas: Record<string, GlobalPluginData>,
pathname: string,
options?: GetActivePluginOptions,
): ActivePlugin | undefined;
export function getActivePlugin(
allPluginDatas: Record<string, GlobalPluginData>,
pathname: string,
options: GetActivePluginOptions = {},
): ActivePlugin | undefined {
const activeEntry = Object.entries(allPluginDatas).find( const activeEntry = Object.entries(allPluginDatas).find(
([_id, pluginData]) => { ([_id, pluginData]) => {
return !!matchPath(pathname, { return !!matchPath(pathname, {
@ -37,10 +51,22 @@ export const getActivePlugin = (
}, },
); );
return activeEntry const activePlugin: ActivePlugin | undefined = activeEntry
? {pluginId: activeEntry[0], pluginData: activeEntry[1]} ? {pluginId: activeEntry[0], pluginData: activeEntry[1]}
: undefined; : undefined;
};
if (!activePlugin && options.failfast) {
throw new Error(
`Can't find active docs plugin for pathname=${pathname}, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(
allPluginDatas,
)
.map((plugin) => plugin.path)
.join(', ')}`,
);
}
return activePlugin;
}
export type ActiveDocContext = { export type ActiveDocContext = {
activeVersion?: Version; activeVersion?: Version;

View file

@ -200,9 +200,14 @@ export function loadSidebars(sidebarFilePath: string): Sidebars {
if (!sidebarFilePath) { if (!sidebarFilePath) {
throw new Error(`sidebarFilePath not provided: ${sidebarFilePath}`); throw new Error(`sidebarFilePath not provided: ${sidebarFilePath}`);
} }
// sidebars file is optional, some users use docs without sidebars!
// See https://github.com/facebook/docusaurus/issues/3366
if (!fs.existsSync(sidebarFilePath)) { if (!fs.existsSync(sidebarFilePath)) {
throw new Error(`No sidebar file exist at path: ${sidebarFilePath}`); // throw new Error(`No sidebar file exist at path: ${sidebarFilePath}`);
return {};
} }
// We don't want sidebars to be cached because of hot reloading. // We don't want sidebars to be cached because of hot reloading.
const sidebarJson = importFresh(sidebarFilePath) as SidebarsJSON; const sidebarJson = importFresh(sidebarFilePath) as SidebarsJSON;
return normalizeSidebars(sidebarJson); return normalizeSidebars(sidebarJson);

View file

@ -18,6 +18,7 @@ import {
getActiveVersion, getActiveVersion,
getActiveDocContext, getActiveDocContext,
getDocVersionSuggestions, getDocVersionSuggestions,
GetActivePluginOptions,
} from '../../client/docsClientUtils'; } from '../../client/docsClientUtils';
const useAllDocsData = (): Record<string, GlobalPluginData> => const useAllDocsData = (): Record<string, GlobalPluginData> =>
@ -26,10 +27,10 @@ const useAllDocsData = (): Record<string, GlobalPluginData> =>
const useDocsData = (pluginId: string | undefined) => const useDocsData = (pluginId: string | undefined) =>
usePluginData('docusaurus-plugin-content-docs', pluginId) as GlobalPluginData; usePluginData('docusaurus-plugin-content-docs', pluginId) as GlobalPluginData;
export const useActivePlugin = () => { export const useActivePlugin = (options: GetActivePluginOptions = {}) => {
const data = useAllDocsData(); const data = useAllDocsData();
const {pathname} = useLocation(); const {pathname} = useLocation();
return getActivePlugin(data, pathname); return getActivePlugin(data, pathname, options);
}; };
// versions are returned ordered (most recent first) // versions are returned ordered (most recent first)

View file

@ -24,6 +24,7 @@ import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
import {LoadContext} from '@docusaurus/types'; import {LoadContext} from '@docusaurus/types';
import {normalizeUrl} from '@docusaurus/utils'; import {normalizeUrl} from '@docusaurus/utils';
import {difference} from 'lodash'; import {difference} from 'lodash';
import chalk from 'chalk';
// retro-compatibility: no prefix for the default plugin id // retro-compatibility: no prefix for the default plugin id
function addPluginIdPrefix(fileOrDir: string, pluginId: string): string { function addPluginIdPrefix(fileOrDir: string, pluginId: string): string {
@ -222,9 +223,13 @@ function checkVersionMetadataPaths({
`The docs folder does not exist for version [${versionName}]. A docs folder is expected to be found at ${docsDirPath}`, `The docs folder does not exist for version [${versionName}]. A docs folder is expected to be found at ${docsDirPath}`,
); );
} }
// See https://github.com/facebook/docusaurus/issues/3366
if (!fs.existsSync(sidebarFilePath)) { if (!fs.existsSync(sidebarFilePath)) {
throw new Error( console.log(
`The sidebar file does not exist for version [${versionName}]. A sidebar file is expected to be found at ${sidebarFilePath}`, chalk.yellow(
`The sidebar file of docs version [${versionName}] does not exist. It is optional, but should rather be provided at ${sidebarFilePath}`,
),
); );
} }
} }

View file

@ -55,7 +55,6 @@ describe('themeConfig', () => {
{ {
type: 'docsVersionDropdown', type: 'docsVersionDropdown',
position: 'left', position: 'left',
nextVersionLabel: '2.0.0-next',
}, },
{ {
to: 'docs/next/support', to: 'docs/next/support',

View file

@ -17,16 +17,11 @@ import TOC from '@theme/TOC';
import clsx from 'clsx'; import clsx from 'clsx';
import styles from './styles.module.css'; import styles from './styles.module.css';
import {useActivePlugin, useActiveVersion} from '@theme/hooks/useDocs'; import {
useActivePlugin,
// TODO can't we receive the version as props instead? useVersions,
const useDocVersion = () => { useActiveVersion,
const version = useActiveVersion(useActivePlugin().pluginId); } from '@theme/hooks/useDocs';
if (!version) {
throw new Error("unexpected, can't get version data of doc"); // should not happen
}
return version;
};
function DocItem(props: Props): JSX.Element { function DocItem(props: Props): JSX.Element {
const {siteConfig = {}} = useDocusaurusContext(); const {siteConfig = {}} = useDocusaurusContext();
@ -49,7 +44,15 @@ function DocItem(props: Props): JSX.Element {
hide_table_of_contents: hideTableOfContents, hide_table_of_contents: hideTableOfContents,
}, },
} = DocContent; } = DocContent;
const version = useDocVersion();
const {pluginId} = useActivePlugin({failfast: true});
const versions = useVersions(pluginId);
const version = useActiveVersion(pluginId);
// If site is not versioned or only one version is included
// we don't show the version badge
// See https://github.com/facebook/docusaurus/issues/3362
const showVersionBadge = versions.length > 1;
const metaTitle = title ? `${title} | ${siteTitle}` : siteTitle; const metaTitle = title ? `${title} | ${siteTitle}` : siteTitle;
const metaImageUrl = useBaseUrl(metaImage, {absolute: true}); const metaImageUrl = useBaseUrl(metaImage, {absolute: true});
@ -83,7 +86,7 @@ function DocItem(props: Props): JSX.Element {
<DocVersionSuggestions /> <DocVersionSuggestions />
<div className={styles.docItemContainer}> <div className={styles.docItemContainer}>
<article> <article>
{version && ( {showVersionBadge && (
<div> <div>
<span className="badge badge--secondary"> <span className="badge badge--secondary">
Version: {version.label} Version: {version.label}

View file

@ -14,16 +14,6 @@ import {
useDocVersionSuggestions, useDocVersionSuggestions,
} from '@theme/hooks/useDocs'; } from '@theme/hooks/useDocs';
const useMandatoryActiveDocsPluginId = () => {
const activePlugin = useActivePlugin();
if (!activePlugin) {
throw new Error(
'DocVersionCallout is only supposed to be used on docs-related routes',
);
}
return activePlugin.pluginId;
};
const getVersionMainDoc = (version) => const getVersionMainDoc = (version) =>
version.docs.find((doc) => doc.id === version.mainDocId); version.docs.find((doc) => doc.id === version.mainDocId);
@ -31,7 +21,7 @@ function DocVersionSuggestions(): JSX.Element {
const { const {
siteConfig: {title: siteTitle}, siteConfig: {title: siteTitle},
} = useDocusaurusContext(); } = useDocusaurusContext();
const pluginId = useMandatoryActiveDocsPluginId(); const {pluginId} = useActivePlugin({failfast: true});
const activeVersion = useActiveVersion(pluginId); const activeVersion = useActiveVersion(pluginId);
const { const {
latestDocSuggestion, latestDocSuggestion,

View file

@ -56,7 +56,6 @@ const DocsVersionDropdownNavbarItemSchema = Joi.object({
type: Joi.string().equal('docsVersionDropdown').required(), type: Joi.string().equal('docsVersionDropdown').required(),
position: NavbarItemPosition, position: NavbarItemPosition,
docsPluginId: Joi.string(), docsPluginId: Joi.string(),
nextVersionLabel: Joi.string().default('Next'), // TODO remove soon
}); });
// Can this be made easier? :/ // Can this be made easier? :/

View file

@ -250,7 +250,6 @@ module.exports = {
{ {
type: 'docsVersionDropdown', type: 'docsVersionDropdown',
position: 'left', position: 'left',
nextVersionLabel: '2.0.0-next',
}, },
{to: 'blog', label: 'Blog', position: 'left'}, {to: 'blog', label: 'Blog', position: 'left'},
{to: 'showcase', label: 'Showcase', position: 'left'}, {to: 'showcase', label: 'Showcase', position: 'left'},