mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-01 11:18:24 +02:00
feat: report orphan pages
This commit is contained in:
parent
ec8230b7ba
commit
2da34337a6
5 changed files with 54 additions and 23 deletions
4
packages/docusaurus-types/src/index.d.ts
vendored
4
packages/docusaurus-types/src/index.d.ts
vendored
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
Loading…
Add table
Reference in a new issue