refactor: remove unnecessary default values normalized during validation (#6864)

* refactor: remove unnecessary default values normalized during validation

* more
This commit is contained in:
Joshua Chen 2022-03-07 19:23:30 +08:00 committed by GitHub
parent 7fc134ba0e
commit 8e934450d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 146 additions and 138 deletions

View file

@ -114,7 +114,7 @@ export default async function mdxLoader(
): Promise<void> { ): Promise<void> {
const callback = this.async(); const callback = this.async();
const filePath = this.resourcePath; const filePath = this.resourcePath;
const reqOptions = this.getOptions() || {}; const reqOptions = this.getOptions() ?? {};
const {frontMatter, content: contentWithTitle} = parseFrontMatter(fileString); const {frontMatter, content: contentWithTitle} = parseFrontMatter(fileString);
@ -127,7 +127,7 @@ export default async function mdxLoader(
const options: Options = { const options: Options = {
...reqOptions, ...reqOptions,
remarkPlugins: [ remarkPlugins: [
...(reqOptions.beforeDefaultRemarkPlugins || []), ...(reqOptions.beforeDefaultRemarkPlugins ?? []),
...DEFAULT_OPTIONS.remarkPlugins, ...DEFAULT_OPTIONS.remarkPlugins,
[ [
transformImage, transformImage,
@ -143,12 +143,12 @@ export default async function mdxLoader(
siteDir: reqOptions.siteDir, siteDir: reqOptions.siteDir,
}, },
], ],
...(reqOptions.remarkPlugins || []), ...(reqOptions.remarkPlugins ?? []),
], ],
rehypePlugins: [ rehypePlugins: [
...(reqOptions.beforeDefaultRehypePlugins || []), ...(reqOptions.beforeDefaultRehypePlugins ?? []),
...DEFAULT_OPTIONS.rehypePlugins, ...DEFAULT_OPTIONS.rehypePlugins,
...(reqOptions.rehypePlugins || []), ...(reqOptions.rehypePlugins ?? []),
], ],
filepath: filePath, filepath: filePath,
}; };

View file

@ -166,9 +166,7 @@ function createCreateRedirectsOptionRedirects(
createRedirects: PluginOptions['createRedirects'], createRedirects: PluginOptions['createRedirects'],
): RedirectMetadata[] { ): RedirectMetadata[] {
function createPathRedirects(path: string): RedirectMetadata[] { function createPathRedirects(path: string): RedirectMetadata[] {
const fromsMixed: string | string[] = createRedirects const fromsMixed: string | string[] = createRedirects?.(path) ?? [];
? createRedirects(path) || []
: [];
const froms: string[] = const froms: string[] =
typeof fromsMixed === 'string' ? [fromsMixed] : fromsMixed; typeof fromsMixed === 'string' ? [fromsMixed] : fromsMixed;

View file

@ -546,13 +546,11 @@ export default async function pluginContentBlog(
const headTags: HtmlTags = []; const headTags: HtmlTags = [];
feedTypes.forEach((feedType) => { feedTypes.forEach((feedType) => {
const feedConfig = feedsConfig[feedType] || {}; const {
type,
if (!feedsConfig) { path: feedConfigPath,
return; title: feedConfigTitle,
} } = feedsConfig[feedType];
const {type, path: feedConfigPath, title: feedConfigTitle} = feedConfig;
headTags.push({ headTags.push({
tagName: 'link', tagName: 'link',

View file

@ -537,7 +537,7 @@ export function filterVersions(
): string[] { ): string[] {
if (options.onlyIncludeVersions) { if (options.onlyIncludeVersions) {
return versionNamesUnfiltered.filter((name) => return versionNamesUnfiltered.filter((name) =>
(options.onlyIncludeVersions || []).includes(name), options.onlyIncludeVersions!.includes(name),
); );
} }
return versionNamesUnfiltered; return versionNamesUnfiltered;

View file

@ -47,7 +47,7 @@ export default async function pluginContentPages(
): Promise<Plugin<LoadedContent | null>> { ): Promise<Plugin<LoadedContent | null>> {
if (options.admonitions) { if (options.admonitions) {
options.remarkPlugins = options.remarkPlugins.concat([ options.remarkPlugins = options.remarkPlugins.concat([
[admonitions, options.admonitions || {}], [admonitions, options.admonitions],
]); ]);
} }
const { const {
@ -77,7 +77,7 @@ export default async function pluginContentPages(
name: 'docusaurus-plugin-content-pages', name: 'docusaurus-plugin-content-pages',
getPathsToWatch() { getPathsToWatch() {
const {include = []} = options; const {include} = options;
return getContentPathList(contentPaths).flatMap((contentPath) => return getContentPathList(contentPaths).flatMap((contentPath) =>
include.map((pattern) => `${contentPath}/${pattern}`), include.map((pattern) => `${contentPath}/${pattern}`),
); );

View file

@ -191,7 +191,7 @@ export default function pluginPWA(
'**/*.{woff,woff2,eot,ttf,otf}', '**/*.{woff,woff2,eot,ttf,otf}',
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
...(injectManifest.globPatterns || []), ...(injectManifest.globPatterns ?? []),
], ],
// those attributes are not overrideable // those attributes are not overrideable
swDest, swDest,

View file

@ -97,16 +97,15 @@ export default function docusaurusThemeClassic(
options: Options, options: Options,
): Plugin<void> { ): Plugin<void> {
const { const {
siteConfig: {themeConfig: roughlyTypedThemeConfig},
i18n: {currentLocale, localeConfigs}, i18n: {currentLocale, localeConfigs},
} = context; } = context;
const themeConfig = (roughlyTypedThemeConfig || {}) as ThemeConfig; const themeConfig = context.siteConfig.themeConfig as ThemeConfig;
const { const {
announcementBar, announcementBar,
colorMode, colorMode,
prism: {additionalLanguages = []} = {}, prism: {additionalLanguages},
} = themeConfig; } = themeConfig;
const {customCss} = options || {}; const {customCss} = options ?? {};
const {direction} = localeConfigs[currentLocale]!; const {direction} = localeConfigs[currentLocale]!;
return { return {

View file

@ -50,14 +50,11 @@ function YearsSection({years}: {years: YearProp[]}) {
} }
function listPostsByYears(blogPosts: readonly ArchiveBlogPost[]): YearProp[] { function listPostsByYears(blogPosts: readonly ArchiveBlogPost[]): YearProp[] {
const postsByYear: Map<string, ArchiveBlogPost[]> = blogPosts.reduceRight( const postsByYear = blogPosts.reduceRight((posts, post) => {
(posts, post) => { const year = post.metadata.date.split('-')[0]!;
const year = post.metadata.date.split('-')[0]; const yearPosts = posts.get(year) ?? [];
const yearPosts = posts.get(year) || []; return posts.set(year, [post, ...yearPosts]);
return posts.set(year, [post, ...yearPosts]); }, new Map<string, ArchiveBlogPost[]>());
},
new Map(),
);
return Array.from(postsByYear, ([year, posts]) => ({ return Array.from(postsByYear, ([year, posts]) => ({
year, year,

View file

@ -15,10 +15,10 @@ import {
type MultiColumnFooter, type MultiColumnFooter,
type SimpleFooter, type SimpleFooter,
} from '@docusaurus/theme-common'; } from '@docusaurus/theme-common';
import useBaseUrl from '@docusaurus/useBaseUrl'; import useBaseUrl, {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
import isInternalUrl from '@docusaurus/isInternalUrl'; import isInternalUrl from '@docusaurus/isInternalUrl';
import styles from './styles.module.css'; import styles from './styles.module.css';
import ThemedImage, {type Props as ThemedImageProps} from '@theme/ThemedImage'; import ThemedImage from '@theme/ThemedImage';
import IconExternalLink from '@theme/IconExternalLink'; import IconExternalLink from '@theme/IconExternalLink';
function FooterLink({ function FooterLink({
@ -54,21 +54,35 @@ function FooterLink({
); );
} }
function FooterLogo({ function FooterLogo({logo}: {logo: SimpleFooter['logo']}) {
sources, const {withBaseUrl} = useBaseUrlUtils();
alt, if (!logo?.src) {
width, return null;
height, }
}: Pick<ThemedImageProps, 'sources' | 'alt' | 'width' | 'height'>) { const sources = {
return ( light: withBaseUrl(logo.src),
dark: withBaseUrl(logo.srcDark ?? logo.src),
};
const image = (
<ThemedImage <ThemedImage
className="footer__logo" className="footer__logo"
alt={alt} alt={logo.alt}
sources={sources} sources={sources}
width={width} width={logo.width}
height={height} height={logo.height}
/> />
); );
return (
<div className="margin-bottom--sm">
{logo.href ? (
<Link href={logo.href} className={styles.footerLogoLink}>
{image}
</Link>
) : (
image
)}
</div>
);
} }
function MultiColumnLinks({links}: {links: MultiColumnFooter['links']}) { function MultiColumnLinks({links}: {links: MultiColumnFooter['links']}) {
@ -136,16 +150,10 @@ function isMultiColumnFooterLinks(
function Footer(): JSX.Element | null { function Footer(): JSX.Element | null {
const {footer} = useThemeConfig(); const {footer} = useThemeConfig();
const {copyright, links = [], logo = {}} = footer || {};
const sources = {
light: useBaseUrl(logo.src),
dark: useBaseUrl(logo.srcDark || logo.src),
};
if (!footer) { if (!footer) {
return null; return null;
} }
const {copyright, links, logo} = footer;
return ( return (
<footer <footer
@ -166,28 +174,8 @@ function Footer(): JSX.Element | null {
))} ))}
{(logo || copyright) && ( {(logo || copyright) && (
<div className="footer__bottom text--center"> <div className="footer__bottom text--center">
{logo && (logo.src || logo.srcDark) && ( <FooterLogo logo={logo} />
<div className="margin-bottom--sm"> {copyright && (
{logo.href ? (
<Link href={logo.href} className={styles.footerLogoLink}>
<FooterLogo
alt={logo.alt}
sources={sources}
width={logo.width}
height={logo.height}
/>
</Link>
) : (
<FooterLogo
alt={logo.alt}
sources={sources}
width={logo.width}
height={logo.height}
/>
)}
</div>
)}
{copyright ? (
<div <div
className="footer__copyright" className="footer__copyright"
// Developer provided the HTML, so assume it's safe. // Developer provided the HTML, so assume it's safe.
@ -196,7 +184,7 @@ function Footer(): JSX.Element | null {
__html: copyright, __html: copyright,
}} }}
/> />
) : null} )}
</div> </div>
)} )}
</div> </div>

View file

@ -17,7 +17,7 @@ import styles from './styles.module.css';
export default function ThemedImage(props: Props): JSX.Element { export default function ThemedImage(props: Props): JSX.Element {
const isBrowser = useIsBrowser(); const isBrowser = useIsBrowser();
const {isDarkTheme} = useColorMode(); const {isDarkTheme} = useColorMode();
const {sources, className, alt = '', ...propsRest} = props; const {sources, className, alt, ...propsRest} = props;
type SourceName = keyof Props['sources']; type SourceName = keyof Props['sources'];

View file

@ -304,7 +304,7 @@ export const ThemeConfigSchema = Joi.object({
style: Joi.string().equal('dark', 'light').default('light'), style: Joi.string().equal('dark', 'light').default('light'),
logo: Joi.object({ logo: Joi.object({
alt: Joi.string().allow(''), alt: Joi.string().allow(''),
src: Joi.string(), src: Joi.string().required(),
srcDark: Joi.string(), srcDark: Joi.string(),
// TODO infer this from reading the image // TODO infer this from reading the image
width: Joi.alternatives().try(Joi.string(), Joi.number()), width: Joi.alternatives().try(Joi.string(), Joi.number()),

View file

@ -56,7 +56,7 @@ export type PrismConfig = {
theme?: PrismTheme; theme?: PrismTheme;
darkTheme?: PrismTheme; darkTheme?: PrismTheme;
defaultLanguage?: string; defaultLanguage?: string;
additionalLanguages?: string[]; additionalLanguages: string[];
}; };
export type FooterLinkItem = { export type FooterLinkItem = {
@ -71,7 +71,7 @@ export type FooterBase = {
style: 'light' | 'dark'; style: 'light' | 'dark';
logo?: { logo?: {
alt?: string; alt?: string;
src?: string; src: string;
srcDark?: string; srcDark?: string;
width?: string | number; width?: string | number;
height?: string | number; height?: string | number;

View file

@ -40,24 +40,24 @@ export interface DocusaurusConfig {
deploymentBranch?: string; deploymentBranch?: string;
githubHost?: string; githubHost?: string;
githubPort?: string; githubPort?: string;
plugins?: PluginConfig[]; plugins: PluginConfig[];
themes?: PluginConfig[]; themes: PluginConfig[];
presets?: PresetConfig[]; presets: PresetConfig[];
themeConfig: ThemeConfig; themeConfig: ThemeConfig;
customFields?: { customFields?: {
[key: string]: unknown; [key: string]: unknown;
}; };
scripts?: ( scripts: (
| string | string
| { | {
src: string; src: string;
[key: string]: unknown; [key: string]: unknown;
} }
)[]; )[];
clientModules?: string[]; clientModules: string[];
ssrTemplate?: string; ssrTemplate?: string;
staticDirectories: string[]; staticDirectories: string[];
stylesheets?: ( stylesheets: (
| string | string
| { | {
href: string; href: string;

View file

@ -30,5 +30,5 @@ Current type: ${isValidElement(children) ? 'React element' : typeof children}`);
return <>{children()}</>; return <>{children()}</>;
} }
return fallback || null; return fallback ?? null;
} }

View file

@ -179,7 +179,7 @@ function Link(
{...props} {...props}
onMouseEnter={onMouseEnter} onMouseEnter={onMouseEnter}
innerRef={handleRef} innerRef={handleRef}
to={targetLink || ''} to={targetLink}
// avoid "React does not recognize the `activeClassName` prop on a DOM // avoid "React does not recognize the `activeClassName` prop on a DOM
// element" // element"
{...(isNavLink && {isActive, activeClassName})} {...(isNavLink && {isActive, activeClassName})}

View file

@ -116,14 +116,14 @@ async function doRender(locals: Locals & {path: string}) {
// manifest information. // manifest information.
const modulesToBeLoaded = [...manifest.entrypoints, ...Array.from(modules)]; const modulesToBeLoaded = [...manifest.entrypoints, ...Array.from(modules)];
const bundles = getBundles(manifest, modulesToBeLoaded); const bundles = getBundles(manifest, modulesToBeLoaded);
const stylesheets = (bundles.css || []).map((b) => b.file); const stylesheets = (bundles.css ?? []).map((b) => b.file);
const scripts = (bundles.js || []).map((b) => b.file); const scripts = (bundles.js ?? []).map((b) => b.file);
const renderedHtml = renderSSRTemplate(ssrTemplate, { const renderedHtml = renderSSRTemplate(ssrTemplate, {
appHtml, appHtml,
baseUrl, baseUrl,
htmlAttributes: htmlAttributes || '', htmlAttributes,
bodyAttributes: bodyAttributes || '', bodyAttributes,
headTags, headTags,
preBodyTags, preBodyTags,
postBodyTags, postBodyTags,

View file

@ -12,7 +12,7 @@ import {DEFAULT_PORT} from '@docusaurus/utils';
export function getCLIOptionHost( export function getCLIOptionHost(
hostOption: HostPortCLIOptions['host'], hostOption: HostPortCLIOptions['host'],
): string { ): string {
return hostOption || 'localhost'; return hostOption ?? 'localhost';
} }
export async function getCLIOptionPort( export async function getCLIOptionPort(

View file

@ -75,7 +75,7 @@ export default async function start(
logger.error(err.stack); logger.error(err.stack);
}); });
}, 500); }, 500);
const {siteConfig, plugins = []} = props; const {siteConfig, plugins} = props;
const normalizeToSiteDir = (filepath: string) => { const normalizeToSiteDir = (filepath: string) => {
if (filepath && path.isAbsolute(filepath)) { if (filepath && path.isAbsolute(filepath)) {
@ -84,12 +84,9 @@ export default async function start(
return posixPath(filepath); return posixPath(filepath);
}; };
const pluginPaths = ([] as string[]) const pluginPaths = plugins
.concat( .flatMap((plugin) => plugin.getPathsToWatch?.() ?? [])
...plugins .filter(Boolean)
.map((plugin) => plugin.getPathsToWatch?.() ?? [])
.filter(Boolean),
)
.map(normalizeToSiteDir); .map(normalizeToSiteDir);
const pathsToWatch = [ const pathsToWatch = [

View file

@ -15,6 +15,7 @@ exports[`loadConfig website with valid async config 1`] = `
Object { Object {
"baseUrl": "/", "baseUrl": "/",
"baseUrlIssueBanner": true, "baseUrlIssueBanner": true,
"clientModules": Array [],
"customFields": Object {}, "customFields": Object {},
"i18n": Object { "i18n": Object {
"defaultLocale": "en", "defaultLocale": "en",
@ -31,9 +32,11 @@ Object {
"plugins": Array [], "plugins": Array [],
"presets": Array [], "presets": Array [],
"projectName": "hello", "projectName": "hello",
"scripts": Array [],
"staticDirectories": Array [ "staticDirectories": Array [
"static", "static",
], ],
"stylesheets": Array [],
"tagline": "Hello World", "tagline": "Hello World",
"themeConfig": Object {}, "themeConfig": Object {},
"themes": Array [], "themes": Array [],
@ -47,6 +50,7 @@ exports[`loadConfig website with valid async config creator function 1`] = `
Object { Object {
"baseUrl": "/", "baseUrl": "/",
"baseUrlIssueBanner": true, "baseUrlIssueBanner": true,
"clientModules": Array [],
"customFields": Object {}, "customFields": Object {},
"i18n": Object { "i18n": Object {
"defaultLocale": "en", "defaultLocale": "en",
@ -63,9 +67,11 @@ Object {
"plugins": Array [], "plugins": Array [],
"presets": Array [], "presets": Array [],
"projectName": "hello", "projectName": "hello",
"scripts": Array [],
"staticDirectories": Array [ "staticDirectories": Array [
"static", "static",
], ],
"stylesheets": Array [],
"tagline": "Hello World", "tagline": "Hello World",
"themeConfig": Object {}, "themeConfig": Object {},
"themes": Array [], "themes": Array [],
@ -79,6 +85,7 @@ exports[`loadConfig website with valid config creator function 1`] = `
Object { Object {
"baseUrl": "/", "baseUrl": "/",
"baseUrlIssueBanner": true, "baseUrlIssueBanner": true,
"clientModules": Array [],
"customFields": Object {}, "customFields": Object {},
"i18n": Object { "i18n": Object {
"defaultLocale": "en", "defaultLocale": "en",
@ -95,9 +102,11 @@ Object {
"plugins": Array [], "plugins": Array [],
"presets": Array [], "presets": Array [],
"projectName": "hello", "projectName": "hello",
"scripts": Array [],
"staticDirectories": Array [ "staticDirectories": Array [
"static", "static",
], ],
"stylesheets": Array [],
"tagline": "Hello World", "tagline": "Hello World",
"themeConfig": Object {}, "themeConfig": Object {},
"themes": Array [], "themes": Array [],
@ -111,6 +120,7 @@ exports[`loadConfig website with valid siteConfig 1`] = `
Object { Object {
"baseUrl": "/", "baseUrl": "/",
"baseUrlIssueBanner": true, "baseUrlIssueBanner": true,
"clientModules": Array [],
"customFields": Object {}, "customFields": Object {},
"favicon": "img/docusaurus.ico", "favicon": "img/docusaurus.ico",
"i18n": Object { "i18n": Object {
@ -136,9 +146,11 @@ Object {
], ],
"presets": Array [], "presets": Array [],
"projectName": "hello", "projectName": "hello",
"scripts": Array [],
"staticDirectories": Array [ "staticDirectories": Array [
"static", "static",
], ],
"stylesheets": Array [],
"tagline": "Hello World", "tagline": "Hello World",
"themeConfig": Object {}, "themeConfig": Object {},
"themes": Array [], "themes": Array [],

View file

@ -26,6 +26,9 @@ export const DEFAULT_CONFIG: Pick<
| 'plugins' | 'plugins'
| 'themes' | 'themes'
| 'presets' | 'presets'
| 'stylesheets'
| 'scripts'
| 'clientModules'
| 'customFields' | 'customFields'
| 'themeConfig' | 'themeConfig'
| 'titleDelimiter' | 'titleDelimiter'
@ -41,6 +44,9 @@ export const DEFAULT_CONFIG: Pick<
plugins: [], plugins: [],
themes: [], themes: [],
presets: [], presets: [],
stylesheets: [],
scripts: [],
clientModules: [],
customFields: {}, customFields: {},
themeConfig: {}, themeConfig: {},
titleDelimiter: '|', titleDelimiter: '|',
@ -170,25 +176,31 @@ export const ConfigSchema = Joi.object({
themes: Joi.array().items(ThemeSchema).default(DEFAULT_CONFIG.themes), themes: Joi.array().items(ThemeSchema).default(DEFAULT_CONFIG.themes),
presets: Joi.array().items(PresetSchema).default(DEFAULT_CONFIG.presets), presets: Joi.array().items(PresetSchema).default(DEFAULT_CONFIG.presets),
themeConfig: Joi.object().unknown().default(DEFAULT_CONFIG.themeConfig), themeConfig: Joi.object().unknown().default(DEFAULT_CONFIG.themeConfig),
scripts: Joi.array().items( scripts: Joi.array()
Joi.string(), .items(
Joi.object({ Joi.string(),
src: Joi.string().required(), Joi.object({
async: Joi.bool(), src: Joi.string().required(),
defer: Joi.bool(), async: Joi.bool(),
}) defer: Joi.bool(),
// See https://github.com/facebook/docusaurus/issues/3378 })
.unknown(), // See https://github.com/facebook/docusaurus/issues/3378
), .unknown(),
)
.default(DEFAULT_CONFIG.scripts),
ssrTemplate: Joi.string(), ssrTemplate: Joi.string(),
stylesheets: Joi.array().items( stylesheets: Joi.array()
Joi.string(), .items(
Joi.object({ Joi.string(),
href: Joi.string().required(), Joi.object({
type: Joi.string(), href: Joi.string().required(),
}).unknown(), type: Joi.string(),
), }).unknown(),
clientModules: Joi.array().items(Joi.string()), )
.default(DEFAULT_CONFIG.stylesheets),
clientModules: Joi.array()
.items(Joi.string())
.default(DEFAULT_CONFIG.clientModules),
tagline: Joi.string().allow('').default(DEFAULT_CONFIG.tagline), tagline: Joi.string().allow('').default(DEFAULT_CONFIG.tagline),
titleDelimiter: Joi.string().default('|'), titleDelimiter: Joi.string().default('|'),
noIndex: Joi.bool().default(false), noIndex: Joi.bool().default(false),

View file

@ -33,7 +33,7 @@ export default function htmlTagObjectToString(tagDefinition: unknown): string {
); );
} }
const isVoidTag = voidHtmlTags.indexOf(tagDefinition.tagName) !== -1; const isVoidTag = voidHtmlTags.indexOf(tagDefinition.tagName) !== -1;
const tagAttributes = tagDefinition.attributes || {}; const tagAttributes = tagDefinition.attributes ?? {};
const attributes = Object.keys(tagAttributes) const attributes = Object.keys(tagAttributes)
.filter((attributeName) => tagAttributes[attributeName] !== false) .filter((attributeName) => tagAttributes[attributeName] !== false)
.map((attributeName) => { .map((attributeName) => {

View file

@ -28,7 +28,7 @@ export function loadHtmlTags(plugins: LoadedPlugin[]): InjectedHtmlTags {
return acc; return acc;
} }
const {headTags, preBodyTags, postBodyTags} = const {headTags, preBodyTags, postBodyTags} =
plugin.injectHtmlTags({content: plugin.content}) || {}; plugin.injectHtmlTags({content: plugin.content}) ?? {};
return { return {
headTags: headTags headTags: headTags
? `${acc.headTags}\n${createHtmlTagsString(headTags)}` ? `${acc.headTags}\n${createHtmlTagsString(headTags)}`

View file

@ -160,10 +160,10 @@ export async function loadPluginConfigs(
presetThemes = presetThemes.map((theme) => presetThemes = presetThemes.map((theme) =>
normalizeShorthand(theme, 'theme'), normalizeShorthand(theme, 'theme'),
); );
const standalonePlugins = (siteConfig.plugins || []).map((plugin) => const standalonePlugins = siteConfig.plugins.map((plugin) =>
normalizeShorthand(plugin, 'plugin'), normalizeShorthand(plugin, 'plugin'),
); );
const standaloneThemes = (siteConfig.themes || []).map((theme) => const standaloneThemes = siteConfig.themes.map((theme) =>
normalizeShorthand(theme, 'theme'), normalizeShorthand(theme, 'theme'),
); );
return [ return [
@ -184,9 +184,9 @@ function createBootstrapPlugin({
siteConfig: DocusaurusConfig; siteConfig: DocusaurusConfig;
}): LoadedPlugin { }): LoadedPlugin {
const { const {
stylesheets = [], stylesheets,
scripts = [], scripts,
clientModules: siteConfigClientModules = [], clientModules: siteConfigClientModules,
} = siteConfig; } = siteConfig;
return { return {
name: 'docusaurus-bootstrap-plugin', name: 'docusaurus-bootstrap-plugin',
@ -314,6 +314,7 @@ export async function load(
generatedFilesDir, generatedFilesDir,
'DONT-EDIT-THIS-FOLDER', 'DONT-EDIT-THIS-FOLDER',
`This folder stores temp files that Docusaurus' client bundler accesses. `This folder stores temp files that Docusaurus' client bundler accesses.
DO NOT hand-modify files in this folder because they will be overwritten in the DO NOT hand-modify files in this folder because they will be overwritten in the
next build. You can clear all build artifacts (including this folder) with the next build. You can clear all build artifacts (including this folder) with the
\`docusaurus clear\` command. \`docusaurus clear\` command.
@ -326,11 +327,12 @@ next build. You can clear all build artifacts (including this folder) with the
generatedFilesDir, generatedFilesDir,
DEFAULT_CONFIG_FILE_NAME, DEFAULT_CONFIG_FILE_NAME,
`/* `/*
AUTOGENERATED - DON'T EDIT * AUTOGENERATED - DON'T EDIT
Your edits in this file will be overwritten in the next build! * Your edits in this file will be overwritten in the next build!
Modify the docusaurus.config.js file at your site's root instead. * Modify the docusaurus.config.js file at your site's root instead.
*/ */
export default ${JSON.stringify(siteConfig, null, 2)};`, export default ${JSON.stringify(siteConfig, null, 2)};
`,
); );
plugins.push(createBootstrapPlugin({siteConfig})); plugins.push(createBootstrapPlugin({siteConfig}));
@ -341,11 +343,14 @@ export default ${JSON.stringify(siteConfig, null, 2)};`,
const genClientModules = generate( const genClientModules = generate(
generatedFilesDir, generatedFilesDir,
'client-modules.js', 'client-modules.js',
`export default [\n${clientModules `export default [
// import() is async so we use require() because client modules can have ${clientModules
// CSS and the order matters for loading CSS. // import() is async so we use require() because client modules can have
.map((module) => ` require('${escapePath(module)}'),`) // CSS and the order matters for loading CSS.
.join('\n')}\n];\n`, .map((module) => ` require('${escapePath(module)}'),`)
.join('\n')}
];
`,
); );
// Load extra head & body html tags. // Load extra head & body html tags.
@ -367,7 +372,8 @@ ${Object.entries(registry)
chunk.modulePath, chunk.modulePath,
)}', require.resolveWeak('${escapePath(chunk.modulePath)}')],`, )}', require.resolveWeak('${escapePath(chunk.modulePath)}')],`,
) )
.join('\n')}};\n`, .join('\n')}};
`,
); );
const genRoutesChunkNames = generate( const genRoutesChunkNames = generate(

View file

@ -14,7 +14,9 @@ describe('loadPresets', () => {
test('no presets', async () => { test('no presets', async () => {
const context = { const context = {
siteConfigPath: __dirname, siteConfigPath: __dirname,
siteConfig: {}, siteConfig: {
presets: [],
},
} as LoadContext; } as LoadContext;
const presets = await loadPresets(context); const presets = await loadPresets(context);
expect(presets).toMatchInlineSnapshot(` expect(presets).toMatchInlineSnapshot(`

View file

@ -10,7 +10,6 @@ import importFresh from 'import-fresh';
import type { import type {
LoadContext, LoadContext,
PluginConfig, PluginConfig,
PresetConfig,
ImportedPresetModule, ImportedPresetModule,
} from '@docusaurus/types'; } from '@docusaurus/types';
import {resolveModuleName} from '../moduleShorthand'; import {resolveModuleName} from '../moduleShorthand';
@ -23,7 +22,7 @@ export default async function loadPresets(context: LoadContext): Promise<{
// siteDir's package.json declares the dependency on these presets. // siteDir's package.json declares the dependency on these presets.
const presetRequire = createRequire(context.siteConfigPath); const presetRequire = createRequire(context.siteConfigPath);
const presets: PresetConfig[] = context.siteConfig.presets || []; const {presets} = context.siteConfig;
const unflatPlugins: PluginConfig[][] = []; const unflatPlugins: PluginConfig[][] = [];
const unflatThemes: PluginConfig[][] = []; const unflatThemes: PluginConfig[][] = [];

View file

@ -176,7 +176,7 @@ export default class CleanWebpackPlugin {
stats.toJson({ stats.toJson({
all: false, all: false,
assets: true, assets: true,
}).assets || []; }).assets ?? [];
const assets = statsAssets.map((asset: {name: string}) => asset.name); const assets = statsAssets.map((asset: {name: string}) => asset.name);
/** /**

View file

@ -23,7 +23,7 @@ export default async function lqipLoader(
const callback = this.async(); const callback = this.async();
const imgPath = this.resourcePath; const imgPath = this.resourcePath;
const config = this.getOptions() || {}; const config = this.getOptions() ?? {};
config.base64 = 'base64' in config ? config.base64 : true; config.base64 = 'base64' in config ? config.base64 : true;
// color palette generation is set to false by default // color palette generation is set to false by default
// since it is little bit slower than base64 generation // since it is little bit slower than base64 generation