fix(v2): restore prefetch functionality (#3723)

* fix(v2): attempt to restore prefetch functionality

* chore(v2): downgrade babel-plugin-dynamic-import-node to 2.3.0

* Get needed routes chunk names

* refactor prefetching logic to make it easier to understand

* array.flat() => flatten(array)

* fix flatten() typo

Co-authored-by: slorber <lorber.sebastien@gmail.com>
This commit is contained in:
Alexey Pyltsyn 2020-11-16 21:52:26 +03:00 committed by GitHub
parent 153d2d46e6
commit 3ab7336875
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 14 deletions

View file

@ -38,7 +38,7 @@ declare module '@generated/routes' {
}
declare module '@generated/routesChunkNames' {
const routesChunkNames: any;
const routesChunkNames: Record<string, Record<string, string>>;
export default routesChunkNames;
}

View file

@ -11,8 +11,8 @@ import prefetchHelper from './prefetch';
import preloadHelper from './preload';
import flat from './flat';
const fetched = {};
const loaded = {};
const fetched: Record<string, boolean> = {};
const loaded: Record<string, boolean> = {};
declare global {
// eslint-disable-next-line camelcase, @typescript-eslint/no-explicit-any
@ -41,6 +41,28 @@ 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[] => {
return flatten(
Object.entries(routesChunkNames)
.filter(
([routeNameWithHash]) =>
removeRouteNameHash(routeNameWithHash) === path,
)
.map(([, routeChunks]) => {
// flat() is useful for nested chunk names, it's not like array.flat()
return Object.values(flat(routeChunks));
}),
);
};
const docusaurus = {
prefetch: (routePath: string): boolean => {
if (!canPrefetch(routePath)) {
@ -51,15 +73,10 @@ const docusaurus = {
// Find all webpack chunk names needed.
const matches = matchRoutes(routes, routePath);
const chunkNamesNeeded = matches.reduce((arr: string[], match) => {
const chunk = routesChunkNames[match.route.path as string];
if (!chunk) {
return arr;
}
const chunkNames = Object.values(flat(chunk)) as string[];
return arr.concat(chunkNames);
}, []);
const chunkNamesNeeded = flatten(
matches.map((match) => getChunkNamesToLoad(match.route.path as string)),
);
// Prefetch all webpack chunk assets file needed.
chunkNamesNeeded.forEach((chunkName) => {

View file

@ -7,11 +7,11 @@
// Too dynamic
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function flat(target: unknown): any {
function flat(target: unknown): Record<string, any> {
const delimiter = '.';
const output = {};
const output: Record<string, any> = {};
function step(object, prev?: string) {
function step(object: any, prev?: string) {
Object.keys(object).forEach((key) => {
const value = object[key];
const type = typeof value;