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 * @default false
*/ */
noIndex: boolean; noIndex: boolean;
orphanPages?: {
onOrphanPage: ReportingSeverity;
entryPoints: string[];
};
/** /**
* The behavior of Docusaurus when it detects any broken link. * The behavior of Docusaurus when it detects any broken link.
* *

View file

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

View file

@ -18,7 +18,7 @@ import {
resolvePathname, resolvePathname,
} from '@docusaurus/utils'; } from '@docusaurus/utils';
import {getAllFinalRoutes} from './utils'; import {getAllFinalRoutes} from './utils';
import type {RouteConfig, ReportingSeverity} from '@docusaurus/types'; import type {RouteConfig, Props, DocusaurusConfig} from '@docusaurus/types';
type BrokenLink = { type BrokenLink = {
link: string; link: string;
@ -214,19 +214,47 @@ async function filterExistingFileLinks({
); );
} }
function findOrphanLinks({
allCollectedLinks,
orphanPages,
}: {
allCollectedLinks: {[location: string]: 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({ export async function handleBrokenLinks({
allCollectedLinks, allCollectedLinks,
onBrokenLinks, props: {
routes, routes,
baseUrl, baseUrl,
outDir, outDir,
siteConfig: {onBrokenLinks, orphanPages},
},
}: { }: {
allCollectedLinks: {[location: string]: string[]}; allCollectedLinks: {[location: string]: string[]};
onBrokenLinks: ReportingSeverity; props: Props;
routes: RouteConfig[];
baseUrl: string;
outDir: string;
}): Promise<void> { }): Promise<void> {
findOrphanLinks({allCollectedLinks, orphanPages});
if (onBrokenLinks === 'ignore') { if (onBrokenLinks === 'ignore') {
return; return;
} }

View file

@ -227,6 +227,12 @@ export const ConfigSchema = Joi.object<DocusaurusConfig>({
clientModules: Joi.array() clientModules: Joi.array()
.items(Joi.string()) .items(Joi.string())
.default(DEFAULT_CONFIG.clientModules), .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), tagline: Joi.string().allow('').default(DEFAULT_CONFIG.tagline),
titleDelimiter: Joi.string().default(DEFAULT_CONFIG.titleDelimiter), titleDelimiter: Joi.string().default(DEFAULT_CONFIG.titleDelimiter),
noIndex: Joi.bool().default(DEFAULT_CONFIG.noIndex), noIndex: Joi.bool().default(DEFAULT_CONFIG.noIndex),

View file

@ -117,6 +117,10 @@ const config = {
description: description:
'An optimized site generator in React. Docusaurus helps you to move fast and write content. Build documentation websites, blogs, marketing pages, and more.', '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: [ staticDirectories: [
'static', 'static',
path.join(__dirname, '_dogfooding/_asset-tests'), path.join(__dirname, '_dogfooding/_asset-tests'),