mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-06 10:20:09 +02:00
refactor(core): fix types for client code (#6064)
This commit is contained in:
parent
f96a051fbe
commit
b4ec7ec011
10 changed files with 48 additions and 58 deletions
|
@ -12,6 +12,7 @@
|
|||
"directory": "packages/docusaurus-module-type-aliases"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/types": "2.0.0-beta.9",
|
||||
"@types/react": "*",
|
||||
"@types/react-helmet": "*",
|
||||
"@types/react-router-config": "*",
|
||||
|
|
|
@ -47,7 +47,9 @@ declare module '@generated/routes' {
|
|||
}
|
||||
|
||||
declare module '@generated/routesChunkNames' {
|
||||
const routesChunkNames: Record<string, Record<string, string>>;
|
||||
import type {RouteChunksTree} from '@docusaurus/types';
|
||||
|
||||
const routesChunkNames: Record<string, RouteChunksTree>;
|
||||
export = routesChunkNames;
|
||||
}
|
||||
|
||||
|
|
2
packages/docusaurus-types/src/index.d.ts
vendored
2
packages/docusaurus-types/src/index.d.ts
vendored
|
@ -442,3 +442,5 @@ export interface TOCItem {
|
|||
readonly children: TOCItem[];
|
||||
readonly level: number;
|
||||
}
|
||||
|
||||
export type RouteChunksTree = {[x: string | number]: string | RouteChunksTree};
|
||||
|
|
|
@ -72,6 +72,12 @@ function insertBanner() {
|
|||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__DOCUSAURUS_INSERT_BASEURL_BANNER: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
function BaseUrlIssueBannerEnabled() {
|
||||
const {
|
||||
siteConfig: {baseUrl},
|
||||
|
@ -80,8 +86,7 @@ function BaseUrlIssueBannerEnabled() {
|
|||
// useLayoutEffect fires before DOMContentLoaded.
|
||||
// It gives the opportunity to avoid inserting the banner in the first place
|
||||
useLayoutEffect(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(window as any)[InsertBannerWindowAttribute] = false;
|
||||
window[InsertBannerWindowAttribute] = false;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
|
|
@ -5,19 +5,16 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
// too dynamic
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
import clientModules from '@generated/client-modules';
|
||||
|
||||
interface Dispatchers {
|
||||
onRouteUpdate: (...args: any) => void;
|
||||
onRouteUpdateDelayed: (...args: any) => void;
|
||||
onRouteUpdate: (...args: unknown[]) => void;
|
||||
onRouteUpdateDelayed: (...args: unknown[]) => void;
|
||||
}
|
||||
|
||||
function dispatchLifecycleAction(
|
||||
lifecycleAction: keyof Dispatchers,
|
||||
...args: any[]
|
||||
...args: unknown[]
|
||||
) {
|
||||
clientModules.forEach((clientModule) => {
|
||||
const lifecycleFunction =
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {matchRoutes} from 'react-router-config';
|
||||
import routesChunkNames from '@generated/routesChunkNames';
|
||||
import routes from '@generated/routes';
|
||||
|
@ -22,18 +23,10 @@ declare global {
|
|||
}
|
||||
}
|
||||
|
||||
const isSlowConnection = () => {
|
||||
// If user is on slow or constrained connection.
|
||||
if (`connection` in navigator) {
|
||||
if (
|
||||
(navigator.connection.effectiveType || ``).indexOf(`2g`) !== -1 &&
|
||||
navigator.connection.saveData
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const isSlowConnection = () =>
|
||||
navigator.connection?.effectiveType.includes('2g') &&
|
||||
navigator.connection?.saveData;
|
||||
|
||||
const canPrefetch = (routePath: string) =>
|
||||
!isSlowConnection() && !loaded[routePath] && !fetched[routePath];
|
||||
|
@ -41,25 +34,19 @@ const canPrefetch = (routePath: string) =>
|
|||
const canPreload = (routePath: string) =>
|
||||
!isSlowConnection() && !loaded[routePath];
|
||||
|
||||
const flatten = <T>(arrays: T[][]): T[] =>
|
||||
Array.prototype.concat.apply([], arrays);
|
||||
|
||||
// Remove the last part containing the route hash
|
||||
// input: /blog/2018/12/14/Happy-First-Birthday-Slash-fe9
|
||||
// output: /blog/2018/12/14/Happy-First-Birthday-Slash
|
||||
const removeRouteNameHash = (str: string) => str.replace(/(-[^-]+)$/, '');
|
||||
|
||||
const getChunkNamesToLoad = (path: string): string[] =>
|
||||
flatten(
|
||||
Object.entries(routesChunkNames)
|
||||
.filter(
|
||||
([routeNameWithHash]) =>
|
||||
removeRouteNameHash(routeNameWithHash) === path,
|
||||
([routeNameWithHash]) => removeRouteNameHash(routeNameWithHash) === path,
|
||||
)
|
||||
.map(([, routeChunks]) =>
|
||||
.flatMap(([, routeChunks]) =>
|
||||
// flat() is useful for nested chunk names, it's not like array.flat()
|
||||
Object.values(flat(routeChunks)),
|
||||
),
|
||||
);
|
||||
|
||||
const docusaurus = {
|
||||
|
@ -73,8 +60,8 @@ const docusaurus = {
|
|||
// Find all webpack chunk names needed.
|
||||
const matches = matchRoutes(routes, routePath);
|
||||
|
||||
const chunkNamesNeeded = flatten(
|
||||
matches.map((match) => getChunkNamesToLoad(match.route.path as string)),
|
||||
const chunkNamesNeeded = matches.flatMap((match) =>
|
||||
getChunkNamesToLoad(match.route.path),
|
||||
);
|
||||
|
||||
// Prefetch all webpack chunk assets file needed.
|
||||
|
|
|
@ -41,9 +41,9 @@ export function interpolate<Str extends string, Value extends ReactNode>(
|
|||
|
||||
const processedText = text.replace(ValueRegexp, (match: string) => {
|
||||
// remove {{ and }} around the placeholder
|
||||
const key = match.substr(
|
||||
const key = match.substring(
|
||||
1,
|
||||
match.length - 2,
|
||||
match.length - 1,
|
||||
) as ExtractInterpolatePlaceholders<Str>;
|
||||
|
||||
const value = values?.[key];
|
||||
|
|
|
@ -5,24 +5,25 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
// Too dynamic
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
function flat(target: unknown): Record<string, any> {
|
||||
import type {RouteChunksTree} from '@docusaurus/types';
|
||||
|
||||
const isTree = (x: string | RouteChunksTree): x is RouteChunksTree =>
|
||||
typeof x === 'object' && !!x && Object.keys(x).length > 0;
|
||||
|
||||
function flat(target: RouteChunksTree): Record<string, string> {
|
||||
const delimiter = '.';
|
||||
const output: Record<string, any> = {};
|
||||
const output: Record<string, string> = {};
|
||||
|
||||
function step(object: any, prev?: string) {
|
||||
Object.keys(object).forEach((key) => {
|
||||
function step(object: RouteChunksTree, prefix?: string | number) {
|
||||
Object.keys(object).forEach((key: string | number) => {
|
||||
const value = object[key];
|
||||
const type = typeof value;
|
||||
const isObject = type === 'object' && !!value;
|
||||
const newKey = prev ? prev + delimiter + key : key;
|
||||
const newKey = prefix ? `${prefix}${delimiter}${key}` : key;
|
||||
|
||||
if (isObject && Object.keys(value).length) {
|
||||
if (isTree(value)) {
|
||||
step(value, newKey);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
output[newKey] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,5 @@ import {Plugin} from '@docusaurus/types';
|
|||
export default function loadClientModules(
|
||||
plugins: Plugin<unknown>[],
|
||||
): string[] {
|
||||
return ([] as string[]).concat(
|
||||
...plugins
|
||||
.map((plugin) => plugin.getClientModules?.() ?? [])
|
||||
.filter(Boolean),
|
||||
);
|
||||
return plugins.flatMap((plugin) => plugin.getClientModules?.() ?? []);
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@ function assertIsHtmlTagObject(val: unknown): asserts val is HtmlTagObject {
|
|||
if (!isPlainObject(val)) {
|
||||
throw new Error(`"${val}" is not a valid HTML tag object.`);
|
||||
}
|
||||
// @ts-expect-error: If tagName doesn't exist, it will throw.
|
||||
if (typeof val.tagName !== 'string') {
|
||||
if (typeof (val as HtmlTagObject).tagName !== 'string') {
|
||||
throw new Error(
|
||||
`${JSON.stringify(
|
||||
val,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue