feat: report orphan pages

This commit is contained in:
Joshua Chen 2022-06-11 17:35:57 +08:00
parent ec8230b7ba
commit 2da34337a6
No known key found for this signature in database
GPG key ID: C37145B818BDB68F
5 changed files with 54 additions and 23 deletions

View file

@ -146,6 +146,10 @@ export type DocusaurusConfig = {
* @default false
*/
noIndex: boolean;
orphanPages?: {
onOrphanPage: ReportingSeverity;
entryPoints: string[];
};
/**
* The behavior of Docusaurus when it detects any broken link.
*

View file

@ -132,12 +132,7 @@ async function buildLocale({
outDir,
generatedFilesDir,
plugins,
siteConfig: {
baseUrl,
onBrokenLinks,
staticDirectories: staticDirectoriesOption,
},
routes,
siteConfig: {staticDirectories: staticDirectoriesOption},
} = props;
const clientManifestPath = path.join(
@ -264,13 +259,7 @@ async function buildLocale({
}),
);
await handleBrokenLinks({
allCollectedLinks,
routes,
onBrokenLinks,
outDir,
baseUrl,
});
await handleBrokenLinks({allCollectedLinks, props});
logger.success`Generated static files in path=${path.relative(
process.cwd(),

View file

@ -18,7 +18,7 @@ import {
resolvePathname,
} from '@docusaurus/utils';
import {getAllFinalRoutes} from './utils';
import type {RouteConfig, ReportingSeverity} from '@docusaurus/types';
import type {RouteConfig, Props, DocusaurusConfig} from '@docusaurus/types';
type BrokenLink = {
link: string;
@ -214,19 +214,47 @@ async function filterExistingFileLinks({
);
}
export async function handleBrokenLinks({
function findOrphanLinks({
allCollectedLinks,
onBrokenLinks,
routes,
baseUrl,
outDir,
orphanPages,
}: {
allCollectedLinks: {[location: string]: string[]};
onBrokenLinks: ReportingSeverity;
routes: RouteConfig[];
baseUrl: string;
outDir: string;
orphanPages: DocusaurusConfig['orphanPages'];
}) {
if (!orphanPages || orphanPages.onOrphanPage === 'ignore') {
return;
}
const visited = new Set<string>();
function dfs(link: string) {
if (visited.has(link)) {
return;
}
visited.add(link);
allCollectedLinks[link]?.forEach((l) => dfs(resolvePathname(l, link)));
}
orphanPages.entryPoints.forEach(dfs);
const orphaned = new Set(Object.keys(allCollectedLinks));
visited.forEach((l) => orphaned.delete(l));
reportMessage(
logger.interpolate`Orphan pages found: url=${Array.from(orphaned)}`,
orphanPages.onOrphanPage,
);
}
export async function handleBrokenLinks({
allCollectedLinks,
props: {
routes,
baseUrl,
outDir,
siteConfig: {onBrokenLinks, orphanPages},
},
}: {
allCollectedLinks: {[location: string]: string[]};
props: Props;
}): Promise<void> {
findOrphanLinks({allCollectedLinks, orphanPages});
if (onBrokenLinks === 'ignore') {
return;
}

View file

@ -227,6 +227,12 @@ export const ConfigSchema = Joi.object<DocusaurusConfig>({
clientModules: Joi.array()
.items(Joi.string())
.default(DEFAULT_CONFIG.clientModules),
orphanPages: Joi.object({
onOrphanPage: Joi.string()
.equal('ignore', 'log', 'warn', 'error', 'throw')
.default('warn'),
entryPoints: Joi.array().items(Joi.string()).default([]),
}),
tagline: Joi.string().allow('').default(DEFAULT_CONFIG.tagline),
titleDelimiter: Joi.string().default(DEFAULT_CONFIG.titleDelimiter),
noIndex: Joi.bool().default(DEFAULT_CONFIG.noIndex),

View file

@ -117,6 +117,10 @@ const config = {
description:
'An optimized site generator in React. Docusaurus helps you to move fast and write content. Build documentation websites, blogs, marketing pages, and more.',
},
orphanPages: {
onOrphanPage: 'warn',
entryPoints: ['/', '/tests'],
},
staticDirectories: [
'static',
path.join(__dirname, '_dogfooding/_asset-tests'),