@docusaurus/core 2.0.0-beta.16 → 2.0.0-beta.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/beforeCli.mjs +14 -12
- package/bin/docusaurus.mjs +41 -93
- package/lib/babel/preset.js +2 -2
- package/lib/client/.eslintrc.js +2 -3
- package/lib/client/App.d.ts +1 -1
- package/lib/client/App.js +15 -7
- package/lib/client/{baseUrlIssueBanner/BaseUrlIssueBanner.d.ts → BaseUrlIssueBanner/index.d.ts} +10 -5
- package/lib/client/{baseUrlIssueBanner/BaseUrlIssueBanner.js → BaseUrlIssueBanner/index.js} +14 -9
- package/lib/client/{baseUrlIssueBanner → BaseUrlIssueBanner}/styles.module.css +0 -0
- package/lib/client/ClientLifecyclesDispatcher.d.ts +16 -0
- package/lib/client/ClientLifecyclesDispatcher.js +34 -0
- package/lib/client/LinksCollector.d.ts +1 -1
- package/lib/client/LinksCollector.js +4 -5
- package/lib/client/PendingNavigation.d.ts +8 -17
- package/lib/client/PendingNavigation.js +39 -70
- package/lib/{server/loadSetup.d.ts → client/SiteMetadataDefaults.d.ts} +2 -2
- package/lib/client/SiteMetadataDefaults.js +19 -0
- package/lib/client/{exports/browserContext.d.ts → browserContext.d.ts} +0 -0
- package/lib/client/{exports/browserContext.js → browserContext.js} +0 -0
- package/lib/client/clientEntry.js +3 -4
- package/lib/client/docusaurus.d.ts +5 -5
- package/lib/client/docusaurus.js +26 -33
- package/lib/client/{exports/docusaurusContext.d.ts → docusaurusContext.d.ts} +0 -0
- package/lib/client/{exports/docusaurusContext.js → docusaurusContext.js} +0 -0
- package/lib/client/exports/BrowserOnly.d.ts +3 -4
- package/lib/client/exports/BrowserOnly.js +2 -2
- package/lib/client/exports/ComponentCreator.js +65 -40
- package/lib/client/exports/ErrorBoundary.d.ts +2 -2
- package/lib/client/exports/ErrorBoundary.js +4 -5
- package/lib/client/exports/Interpolate.d.ts +1 -1
- package/lib/client/exports/Interpolate.js +18 -41
- package/lib/client/exports/Link.d.ts +3 -15
- package/lib/client/exports/Link.js +24 -30
- package/lib/client/exports/Translate.d.ts +2 -2
- package/lib/client/exports/Translate.js +3 -3
- package/lib/client/exports/useBaseUrl.js +8 -9
- package/lib/client/exports/useDocusaurusContext.js +1 -1
- package/lib/client/exports/useGlobalData.d.ts +4 -3
- package/lib/client/exports/useGlobalData.js +5 -5
- package/lib/client/exports/useIsBrowser.js +1 -1
- package/lib/{server/client-modules/index.d.ts → client/exports/useRouteContext.d.ts} +2 -2
- package/lib/client/exports/useRouteContext.js +15 -0
- package/lib/client/flat.d.ts +12 -2
- package/lib/client/flat.js +12 -5
- package/lib/client/normalizeLocation.js +13 -8
- package/lib/client/prefetch.js +10 -28
- package/lib/client/preload.d.ts +1 -3
- package/lib/client/preload.js +5 -11
- package/lib/client/routeContext.d.ts +13 -0
- package/lib/client/routeContext.js +31 -0
- package/lib/client/serverEntry.js +19 -18
- package/lib/client/theme-fallback/Error/index.js +7 -1
- package/lib/client/theme-fallback/Layout/index.d.ts +1 -1
- package/lib/client/theme-fallback/Layout/index.js +2 -17
- package/lib/client/theme-fallback/Loading/index.js +2 -0
- package/lib/client/theme-fallback/NotFound/index.js +13 -5
- package/lib/client/theme-fallback/Root/index.d.ts +4 -4
- package/lib/client/theme-fallback/Root/index.js +2 -1
- package/lib/{server/html-tags/htmlTags.d.ts → client/theme-fallback/SiteMetadata/index.d.ts} +2 -1
- package/lib/client/theme-fallback/SiteMetadata/index.js +10 -0
- package/lib/commands/build.d.ts +6 -2
- package/lib/commands/build.js +48 -30
- package/lib/commands/clear.d.ts +1 -1
- package/lib/commands/clear.js +6 -5
- package/lib/commands/deploy.d.ts +5 -5
- package/lib/commands/deploy.js +21 -45
- package/lib/commands/external.d.ts +1 -1
- package/lib/commands/external.js +6 -11
- package/lib/commands/serve.d.ts +7 -2
- package/lib/commands/serve.js +18 -19
- package/lib/commands/start.d.ts +8 -2
- package/lib/commands/start.js +33 -30
- package/lib/commands/swizzle/actions.d.ts +2 -2
- package/lib/commands/swizzle/actions.js +10 -10
- package/lib/commands/swizzle/common.d.ts +3 -3
- package/lib/commands/swizzle/common.js +8 -9
- package/lib/commands/swizzle/components.js +48 -13
- package/lib/commands/swizzle/config.js +21 -15
- package/lib/commands/swizzle/context.js +6 -12
- package/lib/commands/swizzle/index.d.ts +2 -2
- package/lib/commands/swizzle/index.js +5 -4
- package/lib/commands/swizzle/prompts.js +2 -2
- package/lib/commands/swizzle/tables.js +10 -13
- package/lib/commands/swizzle/themes.js +9 -8
- package/lib/commands/writeHeadingIds.d.ts +2 -9
- package/lib/commands/writeHeadingIds.js +11 -69
- package/lib/commands/writeTranslations.d.ts +3 -4
- package/lib/commands/writeTranslations.js +10 -14
- package/lib/index.d.ts +9 -10
- package/lib/index.js +18 -19
- package/lib/server/brokenLinks.d.ts +3 -16
- package/lib/server/brokenLinks.js +37 -31
- package/lib/server/clientModules.d.ts +12 -0
- package/lib/server/clientModules.js +20 -0
- package/lib/server/config.d.ts +5 -2
- package/lib/server/config.js +14 -9
- package/lib/server/configValidation.d.ts +1 -1
- package/lib/server/configValidation.js +39 -13
- package/lib/server/getHostPort.d.ts +14 -0
- package/lib/{choosePort.js → server/getHostPort.js} +24 -41
- package/lib/server/htmlTags.d.ts +12 -0
- package/lib/server/htmlTags.js +62 -0
- package/lib/server/i18n.d.ts +2 -11
- package/lib/server/i18n.js +7 -28
- package/lib/server/index.d.ts +28 -13
- package/lib/server/index.js +62 -229
- package/lib/server/plugins/configs.d.ts +51 -0
- package/lib/server/plugins/configs.js +101 -0
- package/lib/server/plugins/index.d.ts +9 -8
- package/lib/server/plugins/index.js +65 -132
- package/lib/server/plugins/init.d.ts +6 -15
- package/lib/server/plugins/init.js +25 -83
- package/lib/server/{moduleShorthand.d.ts → plugins/moduleShorthand.d.ts} +0 -0
- package/lib/server/{moduleShorthand.js → plugins/moduleShorthand.js} +0 -0
- package/lib/server/plugins/pluginIds.d.ts +4 -0
- package/lib/server/plugins/pluginIds.js +6 -4
- package/lib/server/plugins/presets.d.ts +12 -0
- package/lib/server/{presets/index.js → plugins/presets.js} +21 -20
- package/lib/server/plugins/{applyRouteTrailingSlash.d.ts → routeConfig.d.ts} +3 -1
- package/lib/server/plugins/routeConfig.js +54 -0
- package/lib/server/plugins/synthetic.d.ts +20 -0
- package/lib/server/plugins/synthetic.js +112 -0
- package/lib/server/routes.d.ts +39 -7
- package/lib/server/routes.js +169 -102
- package/lib/server/siteMetadata.d.ts +12 -0
- package/lib/server/siteMetadata.js +81 -0
- package/lib/server/translations/translations.d.ts +5 -14
- package/lib/server/translations/translations.js +23 -39
- package/lib/server/translations/translationsExtractor.d.ts +2 -2
- package/lib/server/translations/translationsExtractor.js +16 -19
- package/lib/server/utils.js +1 -1
- package/lib/webpack/aliases/index.d.ts +34 -0
- package/lib/webpack/aliases/index.js +106 -0
- package/lib/webpack/base.d.ts +0 -1
- package/lib/webpack/base.js +12 -30
- package/lib/webpack/client.js +7 -8
- package/lib/webpack/plugins/ChunkAssetPlugin.js +7 -7
- package/lib/webpack/plugins/CleanWebpackPlugin.d.ts +2 -2
- package/lib/webpack/plugins/CleanWebpackPlugin.js +2 -2
- package/lib/webpack/plugins/LogPlugin.js +2 -2
- package/lib/webpack/plugins/WaitPlugin.d.ts +2 -2
- package/lib/webpack/plugins/WaitPlugin.js +3 -3
- package/lib/webpack/server.d.ts +2 -2
- package/lib/webpack/server.js +10 -8
- package/lib/webpack/utils.d.ts +9 -3
- package/lib/webpack/utils.js +20 -25
- package/package.json +38 -41
- package/lib/choosePort.d.ts +0 -11
- package/lib/client/client-lifecycles-dispatcher.d.ts +0 -9
- package/lib/client/client-lifecycles-dispatcher.js +0 -23
- package/lib/client/nprogress.css +0 -36
- package/lib/commands/commandUtils.d.ts +0 -9
- package/lib/commands/commandUtils.js +0 -21
- package/lib/server/client-modules/index.js +0 -12
- package/lib/server/duplicateRoutes.d.ts +0 -10
- package/lib/server/duplicateRoutes.js +0 -42
- package/lib/server/html-tags/htmlTags.js +0 -38
- package/lib/server/html-tags/index.d.ts +0 -9
- package/lib/server/html-tags/index.js +0 -43
- package/lib/server/loadSetup.js +0 -25
- package/lib/server/plugins/applyRouteTrailingSlash.js +0 -19
- package/lib/server/presets/index.d.ts +0 -11
- package/lib/server/themes/alias.d.ts +0 -9
- package/lib/server/themes/alias.js +0 -48
- package/lib/server/themes/index.d.ts +0 -12
- package/lib/server/themes/index.js +0 -47
- package/lib/server/versions/__fixtures__/dummy-plugin.d.ts +0 -0
- package/lib/server/versions/__fixtures__/dummy-plugin.js +0 -0
- package/lib/server/versions/__fixtures__/package.json +0 -3
- package/lib/server/versions/index.d.ts +0 -9
- package/lib/server/versions/index.js +0 -51
|
@@ -5,19 +5,21 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
|
-
import { Route
|
|
9
|
-
import
|
|
10
|
-
import
|
|
8
|
+
import { Route } from 'react-router-dom';
|
|
9
|
+
import ClientLifecyclesDispatcher, { dispatchLifecycleAction, } from './ClientLifecyclesDispatcher';
|
|
10
|
+
import ExecutionEnvironment from './exports/ExecutionEnvironment';
|
|
11
11
|
import preload from './preload';
|
|
12
|
-
import normalizeLocation from './normalizeLocation';
|
|
13
|
-
import './nprogress.css';
|
|
14
|
-
nprogress.configure({ showSpinner: false });
|
|
15
12
|
class PendingNavigation extends React.Component {
|
|
16
13
|
constructor(props) {
|
|
17
14
|
super(props);
|
|
18
15
|
// previousLocation doesn't affect rendering, hence not stored in state.
|
|
19
16
|
this.previousLocation = null;
|
|
20
|
-
this.
|
|
17
|
+
this.routeUpdateCleanupCb = ExecutionEnvironment.canUseDOM
|
|
18
|
+
? dispatchLifecycleAction('onRouteUpdate', {
|
|
19
|
+
previousLocation: null,
|
|
20
|
+
location: this.props.location,
|
|
21
|
+
})
|
|
22
|
+
: () => { };
|
|
21
23
|
this.state = {
|
|
22
24
|
nextRouteHasLoaded: true,
|
|
23
25
|
};
|
|
@@ -25,72 +27,39 @@ class PendingNavigation extends React.Component {
|
|
|
25
27
|
// Intercept location update and still show current route until next route
|
|
26
28
|
// is done loading.
|
|
27
29
|
shouldComponentUpdate(nextProps, nextState) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (routeDidChange) {
|
|
33
|
-
const nextLocation = normalizeLocation(nextProps.location);
|
|
34
|
-
this.startProgressBar(delay);
|
|
35
|
-
// Save the location first.
|
|
36
|
-
this.previousLocation = normalizeLocation(this.props.location);
|
|
37
|
-
this.setState({
|
|
38
|
-
nextRouteHasLoaded: false,
|
|
39
|
-
});
|
|
40
|
-
// Load data while the old screen remains.
|
|
41
|
-
preload(routes, nextLocation.pathname)
|
|
42
|
-
.then(() => {
|
|
43
|
-
clientLifecyclesDispatcher.onRouteUpdate({
|
|
44
|
-
previousLocation: this.previousLocation,
|
|
45
|
-
location: nextLocation,
|
|
46
|
-
});
|
|
47
|
-
// Route has loaded, we can reset previousLocation.
|
|
48
|
-
this.previousLocation = null;
|
|
49
|
-
this.setState({ nextRouteHasLoaded: true }, this.stopProgressBar);
|
|
50
|
-
const { hash } = nextLocation;
|
|
51
|
-
if (!hash) {
|
|
52
|
-
window.scrollTo(0, 0);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
const id = decodeURIComponent(hash.substring(1));
|
|
56
|
-
const element = document.getElementById(id);
|
|
57
|
-
if (element) {
|
|
58
|
-
element.scrollIntoView();
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
})
|
|
62
|
-
.catch((e) => console.warn(e));
|
|
63
|
-
return false;
|
|
30
|
+
if (nextProps.location === this.props.location) {
|
|
31
|
+
// `nextRouteHasLoaded` is false means there's a pending route transition.
|
|
32
|
+
// Don't update until it's done.
|
|
33
|
+
return nextState.nextRouteHasLoaded;
|
|
64
34
|
}
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}, delay);
|
|
86
|
-
}
|
|
87
|
-
stopProgressBar() {
|
|
88
|
-
this.clearProgressBarTimeout();
|
|
89
|
-
nprogress.done();
|
|
35
|
+
// props.location being different means the router is trying to navigate to
|
|
36
|
+
// a new route. We will preload the new route.
|
|
37
|
+
const nextLocation = nextProps.location;
|
|
38
|
+
// Save the location first.
|
|
39
|
+
this.previousLocation = this.props.location;
|
|
40
|
+
this.setState({ nextRouteHasLoaded: false });
|
|
41
|
+
this.routeUpdateCleanupCb = dispatchLifecycleAction('onRouteUpdate', {
|
|
42
|
+
previousLocation: this.previousLocation,
|
|
43
|
+
location: nextLocation,
|
|
44
|
+
});
|
|
45
|
+
// Load data while the old screen remains. Force preload instead of using
|
|
46
|
+
// `window.docusaurus`, because we want to avoid loading screen even when
|
|
47
|
+
// user is on saveData
|
|
48
|
+
preload(nextLocation.pathname)
|
|
49
|
+
.then(() => {
|
|
50
|
+
this.routeUpdateCleanupCb?.();
|
|
51
|
+
this.setState({ nextRouteHasLoaded: true });
|
|
52
|
+
})
|
|
53
|
+
.catch((e) => console.warn(e));
|
|
54
|
+
return false;
|
|
90
55
|
}
|
|
91
56
|
render() {
|
|
92
57
|
const { children, location } = this.props;
|
|
93
|
-
|
|
58
|
+
// Use a controlled <Route> to trick all descendants into rendering the old
|
|
59
|
+
// location.
|
|
60
|
+
return (<ClientLifecyclesDispatcher previousLocation={this.previousLocation} location={location}>
|
|
61
|
+
<Route location={location} render={() => children}/>
|
|
62
|
+
</ClientLifecyclesDispatcher>);
|
|
94
63
|
}
|
|
95
64
|
}
|
|
96
|
-
export default
|
|
65
|
+
export default PendingNavigation;
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
export default function
|
|
7
|
+
/// <reference types="react" />
|
|
8
|
+
export default function SiteMetadataDefaults(): JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import Head from '@docusaurus/Head';
|
|
9
|
+
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
|
10
|
+
import useBaseUrl from '@docusaurus/useBaseUrl';
|
|
11
|
+
export default function SiteMetadataDefaults() {
|
|
12
|
+
const { siteConfig: { favicon, tagline, title }, i18n: { currentLocale, localeConfigs }, } = useDocusaurusContext();
|
|
13
|
+
const faviconUrl = useBaseUrl(favicon);
|
|
14
|
+
const { htmlLang, direction: htmlDir } = localeConfigs[currentLocale];
|
|
15
|
+
return (<Head defaultTitle={`${title}${tagline ? ` · ${tagline}` : ''}`}>
|
|
16
|
+
<html lang={htmlLang} dir={htmlDir}/>
|
|
17
|
+
{favicon && <link rel="icon" href={faviconUrl}/>}
|
|
18
|
+
</Head>);
|
|
19
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -5,10 +5,9 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
|
-
import
|
|
8
|
+
import ReactDOM from 'react-dom';
|
|
9
9
|
import { BrowserRouter } from 'react-router-dom';
|
|
10
10
|
import { HelmetProvider } from 'react-helmet-async';
|
|
11
|
-
import routes from '@generated/routes';
|
|
12
11
|
import ExecutionEnvironment from './exports/ExecutionEnvironment';
|
|
13
12
|
import App from './App';
|
|
14
13
|
import preload from './preload';
|
|
@@ -21,8 +20,8 @@ if (ExecutionEnvironment.canUseDOM) {
|
|
|
21
20
|
// first-load experience.
|
|
22
21
|
// For development, there is no existing markup so we had to render it.
|
|
23
22
|
// We also preload async component to avoid first-load loading screen.
|
|
24
|
-
const renderMethod = process.env.NODE_ENV === 'production' ? hydrate : render;
|
|
25
|
-
preload(
|
|
23
|
+
const renderMethod = process.env.NODE_ENV === 'production' ? ReactDOM.hydrate : ReactDOM.render;
|
|
24
|
+
preload(window.location.pathname).then(() => {
|
|
26
25
|
renderMethod(<HelmetProvider>
|
|
27
26
|
<BrowserRouter>
|
|
28
27
|
<App />
|
|
@@ -15,8 +15,8 @@ declare global {
|
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
declare const
|
|
19
|
-
prefetch
|
|
20
|
-
preload
|
|
21
|
-
}
|
|
22
|
-
export default
|
|
18
|
+
declare const _default: Readonly<{
|
|
19
|
+
prefetch(routePath: string): false | Promise<void[]>;
|
|
20
|
+
preload(routePath: string): false | Promise<void[]>;
|
|
21
|
+
}>;
|
|
22
|
+
export default _default;
|
package/lib/client/docusaurus.js
CHANGED
|
@@ -10,58 +10,51 @@ import routes from '@generated/routes';
|
|
|
10
10
|
import prefetchHelper from './prefetch';
|
|
11
11
|
import preloadHelper from './preload';
|
|
12
12
|
import flat from './flat';
|
|
13
|
-
const fetched =
|
|
14
|
-
const loaded =
|
|
13
|
+
const fetched = new Set();
|
|
14
|
+
const loaded = new Set();
|
|
15
15
|
// If user is on slow or constrained connection.
|
|
16
|
-
const isSlowConnection = () =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const canPreload = (routePath) => !isSlowConnection() && !loaded[routePath];
|
|
16
|
+
const isSlowConnection = () => navigator.connection?.effectiveType.includes('2g') ||
|
|
17
|
+
navigator.connection?.saveData;
|
|
18
|
+
const canPrefetch = (routePath) => !isSlowConnection() && !loaded.has(routePath) && !fetched.has(routePath);
|
|
19
|
+
const canPreload = (routePath) => !isSlowConnection() && !loaded.has(routePath);
|
|
20
|
+
const getChunkNamesToLoad = (path) => Object.entries(routesChunkNames)
|
|
21
|
+
.filter(
|
|
23
22
|
// Remove the last part containing the route hash
|
|
24
23
|
// input: /blog/2018/12/14/Happy-First-Birthday-Slash-fe9
|
|
25
24
|
// output: /blog/2018/12/14/Happy-First-Birthday-Slash
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.filter(([routeNameWithHash]) => removeRouteNameHash(routeNameWithHash) === path)
|
|
29
|
-
.flatMap(([, routeChunks]) =>
|
|
30
|
-
// flat() is useful for nested chunk names, it's not like array.flat()
|
|
31
|
-
Object.values(flat(routeChunks)));
|
|
25
|
+
([routeNameWithHash]) => routeNameWithHash.replace(/-[^-]+$/, '') === path)
|
|
26
|
+
.flatMap(([, routeChunks]) => Object.values(flat(routeChunks)));
|
|
32
27
|
const docusaurus = {
|
|
33
|
-
prefetch
|
|
28
|
+
prefetch(routePath) {
|
|
34
29
|
if (!canPrefetch(routePath)) {
|
|
35
30
|
return false;
|
|
36
31
|
}
|
|
37
|
-
|
|
38
|
-
fetched[routePath] = true;
|
|
32
|
+
fetched.add(routePath);
|
|
39
33
|
// Find all webpack chunk names needed.
|
|
40
34
|
const matches = matchRoutes(routes, routePath);
|
|
41
35
|
const chunkNamesNeeded = matches.flatMap((match) => getChunkNamesToLoad(match.route.path));
|
|
42
36
|
// Prefetch all webpack chunk assets file needed.
|
|
43
|
-
chunkNamesNeeded.
|
|
44
|
-
// "__webpack_require__.gca" is
|
|
45
|
-
//
|
|
46
|
-
// it will return the URL for that chunk.
|
|
37
|
+
return Promise.all(chunkNamesNeeded.map((chunkName) => {
|
|
38
|
+
// "__webpack_require__.gca" is injected by ChunkAssetPlugin. Pass it
|
|
39
|
+
// the name of the chunk you want to load and it will return its URL.
|
|
47
40
|
// eslint-disable-next-line camelcase
|
|
48
41
|
const chunkAsset = __webpack_require__.gca(chunkName);
|
|
49
|
-
// In some cases, webpack might decide to optimize further
|
|
50
|
-
// chunk assets
|
|
51
|
-
//
|
|
42
|
+
// In some cases, webpack might decide to optimize further, leading to
|
|
43
|
+
// the chunk assets being merged to another chunk. In this case, we can
|
|
44
|
+
// safely filter it out and don't need to load it.
|
|
52
45
|
if (chunkAsset && !/undefined/.test(chunkAsset)) {
|
|
53
|
-
prefetchHelper(chunkAsset);
|
|
46
|
+
return prefetchHelper(chunkAsset);
|
|
54
47
|
}
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
return Promise.resolve();
|
|
49
|
+
}));
|
|
57
50
|
},
|
|
58
|
-
preload
|
|
51
|
+
preload(routePath) {
|
|
59
52
|
if (!canPreload(routePath)) {
|
|
60
53
|
return false;
|
|
61
54
|
}
|
|
62
|
-
loaded
|
|
63
|
-
preloadHelper(
|
|
64
|
-
return true;
|
|
55
|
+
loaded.add(routePath);
|
|
56
|
+
return preloadHelper(routePath);
|
|
65
57
|
},
|
|
66
58
|
};
|
|
67
|
-
|
|
59
|
+
// This object is directly mounted onto window, better freeze it
|
|
60
|
+
export default Object.freeze(docusaurus);
|
|
File without changes
|
|
File without changes
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
+
/// <reference types="@docusaurus/module-type-aliases" />
|
|
7
8
|
/// <reference types="react" />
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
fallback?: JSX.Element;
|
|
11
|
-
}): JSX.Element | null;
|
|
9
|
+
import type { Props } from '@docusaurus/BrowserOnly';
|
|
10
|
+
export default function BrowserOnly({ children, fallback, }: Props): JSX.Element | null;
|
|
@@ -16,7 +16,7 @@ export default function BrowserOnly({ children, fallback, }) {
|
|
|
16
16
|
throw new Error(`Docusaurus error: The children of <BrowserOnly> must be a "render function", e.g. <BrowserOnly>{() => <span>{window.location.href}</span>}</BrowserOnly>.
|
|
17
17
|
Current type: ${isValidElement(children) ? 'React element' : typeof children}`);
|
|
18
18
|
}
|
|
19
|
-
return <>{children()}</>;
|
|
19
|
+
return <>{children?.()}</>;
|
|
20
20
|
}
|
|
21
|
-
return fallback
|
|
21
|
+
return fallback ?? null;
|
|
22
22
|
}
|
|
@@ -10,69 +10,94 @@ import Loading from '@theme/Loading';
|
|
|
10
10
|
import routesChunkNames from '@generated/routesChunkNames';
|
|
11
11
|
import registry from '@generated/registry';
|
|
12
12
|
import flat from '../flat';
|
|
13
|
+
import { RouteContextProvider } from '../routeContext';
|
|
13
14
|
export default function ComponentCreator(path, hash) {
|
|
14
15
|
// 404 page
|
|
15
16
|
if (path === '*') {
|
|
16
17
|
return Loadable({
|
|
17
18
|
loading: Loading,
|
|
18
|
-
loader: () => import('@theme/NotFound')
|
|
19
|
+
loader: () => import('@theme/NotFound').then(({ default: NotFound }) => (props) => (<RouteContextProvider
|
|
20
|
+
// Do we want a better name than native-default?
|
|
21
|
+
value={{ plugin: { name: 'native', id: 'default' } }}>
|
|
22
|
+
<NotFound {...props}/>
|
|
23
|
+
</RouteContextProvider>)),
|
|
19
24
|
});
|
|
20
25
|
}
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const
|
|
26
|
+
const chunkNames = routesChunkNames[`${path}-${hash}`];
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
const loader = {};
|
|
29
|
+
const modules = [];
|
|
24
30
|
const optsWebpack = [];
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
component: () => import('./Pages.js'),
|
|
32
|
-
content.foo: () => import('./doc1.md'),
|
|
33
|
-
}
|
|
34
|
-
- optsModules: ['./Pages.js', './doc1.md']
|
|
35
|
-
- optsWebpack: [
|
|
36
|
-
require.resolveWeak('./Pages.js'),
|
|
37
|
-
require.resolveWeak('./doc1.md'),
|
|
38
|
-
]
|
|
39
|
-
*/
|
|
31
|
+
// A map from prop names to chunk names.
|
|
32
|
+
// e.g. Suppose the plugin added this as route:
|
|
33
|
+
// { __comp: "...", prop: { foo: "..." }, items: ["...", "..."] }
|
|
34
|
+
// It will become:
|
|
35
|
+
// { __comp: "...", "prop.foo": "...", "items.0": "...", "items.1": ... }
|
|
36
|
+
// Loadable.Map will _map_ over `loader` and load each key.
|
|
40
37
|
const flatChunkNames = flat(chunkNames);
|
|
41
|
-
Object.
|
|
42
|
-
const chunkRegistry = registry[
|
|
38
|
+
Object.entries(flatChunkNames).forEach(([keyPath, chunkName]) => {
|
|
39
|
+
const chunkRegistry = registry[chunkName];
|
|
43
40
|
if (chunkRegistry) {
|
|
44
41
|
// eslint-disable-next-line prefer-destructuring
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
loader[keyPath] = chunkRegistry[0];
|
|
43
|
+
modules.push(chunkRegistry[1]);
|
|
47
44
|
optsWebpack.push(chunkRegistry[2]);
|
|
48
45
|
}
|
|
49
46
|
});
|
|
50
47
|
return Loadable.Map({
|
|
51
48
|
loading: Loading,
|
|
52
|
-
loader
|
|
53
|
-
modules
|
|
49
|
+
loader,
|
|
50
|
+
modules,
|
|
54
51
|
webpack: () => optsWebpack,
|
|
55
52
|
render: (loaded, props) => {
|
|
56
|
-
//
|
|
53
|
+
// `loaded` will be a map from key path (as returned from the flattened
|
|
54
|
+
// chunk names) to the modules loaded from the loaders. We now have to
|
|
55
|
+
// restore the chunk names' previous shape from this flat record.
|
|
56
|
+
// We do so by taking advantage of the existing `chunkNames` and replacing
|
|
57
|
+
// each chunk name with its loaded module, so we don't create another
|
|
58
|
+
// object from scratch.
|
|
57
59
|
const loadedModules = JSON.parse(JSON.stringify(chunkNames));
|
|
58
|
-
Object.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
Object.entries(loaded).forEach(([keyPath, loadedModule]) => {
|
|
61
|
+
// JSON modules are also loaded as `{ default: ... }` (`import()`
|
|
62
|
+
// semantics) but we just want to pass the actual value to props.
|
|
63
|
+
const chunk = loadedModule.default;
|
|
64
|
+
// One loaded chunk can only be one of two things: a module (props) or a
|
|
65
|
+
// component. Modules are always JSON, so `default` always exists. This
|
|
66
|
+
// could only happen with a user-defined component.
|
|
67
|
+
if (!chunk) {
|
|
68
|
+
throw new Error(`The page component at ${path} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);
|
|
63
69
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
// A module can be a primitive, for example, if the user stored a string
|
|
71
|
+
// as a prop. However, there seems to be a bug with swc-loader's CJS
|
|
72
|
+
// logic, in that it would load a JSON module with content "foo" as
|
|
73
|
+
// `{ default: "foo", 0: "f", 1: "o", 2: "o" }`. Just to be safe, we
|
|
74
|
+
// first make sure that the chunk is non-primitive.
|
|
75
|
+
if (typeof chunk === 'object' || typeof chunk === 'function') {
|
|
76
|
+
Object.keys(loadedModule)
|
|
77
|
+
.filter((k) => k !== 'default')
|
|
78
|
+
.forEach((nonDefaultKey) => {
|
|
79
|
+
chunk[nonDefaultKey] = loadedModule[nonDefaultKey];
|
|
70
80
|
});
|
|
71
81
|
}
|
|
82
|
+
// We now have this chunk prepared. Go down the key path and replace the
|
|
83
|
+
// chunk name with the actual chunk.
|
|
84
|
+
let val = loadedModules;
|
|
85
|
+
const keyPaths = keyPath.split('.');
|
|
86
|
+
keyPaths.slice(0, -1).forEach((k) => {
|
|
87
|
+
val = val[k];
|
|
88
|
+
});
|
|
89
|
+
val[keyPaths[keyPaths.length - 1]] = chunk;
|
|
72
90
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
91
|
+
/* eslint-disable no-underscore-dangle */
|
|
92
|
+
const Component = loadedModules.__comp;
|
|
93
|
+
delete loadedModules.__comp;
|
|
94
|
+
const routeContext = loadedModules.__context;
|
|
95
|
+
delete loadedModules.__context;
|
|
96
|
+
/* eslint-enable no-underscore-dangle */
|
|
97
|
+
// Is there any way to put this RouteContextProvider upper in the tree?
|
|
98
|
+
return (<RouteContextProvider value={routeContext}>
|
|
99
|
+
<Component {...loadedModules} {...props}/>
|
|
100
|
+
</RouteContextProvider>);
|
|
76
101
|
},
|
|
77
102
|
});
|
|
78
103
|
}
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
/// <reference types="@docusaurus/module-type-aliases" />
|
|
8
8
|
import React, { type ReactNode } from 'react';
|
|
9
9
|
import type { Props } from '@docusaurus/ErrorBoundary';
|
|
10
|
-
|
|
10
|
+
declare type State = {
|
|
11
11
|
error: Error | null;
|
|
12
|
-
}
|
|
12
|
+
};
|
|
13
13
|
export default class ErrorBoundary extends React.Component<Props, State> {
|
|
14
14
|
constructor(props: Props);
|
|
15
15
|
componentDidCatch(error: Error): void;
|
|
@@ -19,18 +19,17 @@ export default class ErrorBoundary extends React.Component {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
render() {
|
|
22
|
-
var _a;
|
|
23
22
|
const { children } = this.props;
|
|
24
23
|
const { error } = this.state;
|
|
25
24
|
if (error) {
|
|
26
|
-
const fallback =
|
|
25
|
+
const fallback = this.props.fallback ?? DefaultFallback;
|
|
27
26
|
return fallback({
|
|
28
27
|
error,
|
|
29
28
|
tryAgain: () => this.setState({ error: null }),
|
|
30
29
|
});
|
|
31
30
|
}
|
|
32
|
-
return (children
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
return (children ??
|
|
32
|
+
// See https://github.com/facebook/docusaurus/issues/6337#issuecomment-1012913647
|
|
33
|
+
null);
|
|
35
34
|
}
|
|
36
35
|
}
|
|
@@ -9,4 +9,4 @@ import { type ReactNode } from 'react';
|
|
|
9
9
|
import type { InterpolateProps, InterpolateValues } from '@docusaurus/Interpolate';
|
|
10
10
|
export declare function interpolate<Str extends string>(text: Str, values?: InterpolateValues<Str, string | number>): string;
|
|
11
11
|
export declare function interpolate<Str extends string, Value extends ReactNode>(text: Str, values?: InterpolateValues<Str, Value>): ReactNode;
|
|
12
|
-
export default function Interpolate<Str extends string>({ children, values, }: InterpolateProps<Str>):
|
|
12
|
+
export default function Interpolate<Str extends string>({ children, values, }: InterpolateProps<Str>): JSX.Element;
|
|
@@ -4,53 +4,30 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import React from 'react';
|
|
8
|
-
/*
|
|
9
|
-
Minimal implementation of a React interpolate component.
|
|
10
|
-
We don't ship a markdown parser nor a feature-complete i18n library on purpose.
|
|
11
|
-
More details here: https://github.com/facebook/docusaurus/pull/4295
|
|
12
|
-
*/
|
|
13
|
-
const ValueRegexp = /{\w+}/g;
|
|
14
|
-
const ValueFoundMarker = '{}'; // does not care much
|
|
7
|
+
import React, { isValidElement } from 'react';
|
|
15
8
|
export function interpolate(text, values) {
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
String(value);
|
|
26
|
-
elements.push(element);
|
|
27
|
-
return ValueFoundMarker;
|
|
9
|
+
// eslint-disable-next-line prefer-named-capture-group
|
|
10
|
+
const segments = text.split(/(\{\w+\})/).map((seg, index) => {
|
|
11
|
+
// Odd indices (1, 3, 5...) of the segments are (potentially) interpolatable
|
|
12
|
+
if (index % 2 === 1) {
|
|
13
|
+
const value = values?.[seg.slice(1, -1)];
|
|
14
|
+
if (value !== undefined) {
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
// No match: add warning? There's no way to "escape" interpolation though
|
|
28
18
|
}
|
|
29
|
-
return
|
|
19
|
+
return seg;
|
|
30
20
|
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
if (segments.some((seg) => isValidElement(seg))) {
|
|
22
|
+
return segments
|
|
23
|
+
.map((seg, index) => isValidElement(seg) ? React.cloneElement(seg, { key: index }) : seg)
|
|
24
|
+
.filter((seg) => seg !== '');
|
|
34
25
|
}
|
|
35
|
-
|
|
36
|
-
if (elements.every((el) => typeof el === 'string')) {
|
|
37
|
-
return processedText
|
|
38
|
-
.split(ValueFoundMarker)
|
|
39
|
-
.reduce((str, value, index) => { var _a; return str.concat(value).concat((_a = elements[index]) !== null && _a !== void 0 ? _a : ''); }, '');
|
|
40
|
-
}
|
|
41
|
-
// JSX interpolation: returns ReactNode
|
|
42
|
-
return processedText.split(ValueFoundMarker).reduce((array, value, index) => [
|
|
43
|
-
...array,
|
|
44
|
-
<React.Fragment key={index}>
|
|
45
|
-
{value}
|
|
46
|
-
{elements[index]}
|
|
47
|
-
</React.Fragment>,
|
|
48
|
-
], []);
|
|
26
|
+
return segments.join('');
|
|
49
27
|
}
|
|
50
28
|
export default function Interpolate({ children, values, }) {
|
|
51
29
|
if (typeof children !== 'string') {
|
|
52
|
-
|
|
53
|
-
throw new Error('The Docusaurus <Interpolate> component only accept simple string values');
|
|
30
|
+
throw new Error(`The Docusaurus <Interpolate> component only accept simple string values. Received: ${isValidElement(children) ? 'React element' : typeof children}`);
|
|
54
31
|
}
|
|
55
|
-
return interpolate(children, values)
|
|
32
|
+
return <>{interpolate(children, values)}</>;
|
|
56
33
|
}
|