@docusaurus/core 0.0.0-4518 → 0.0.0-4524
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/lib/babel/preset.js +5 -4
- package/lib/client/App.js +12 -6
- package/lib/client/LinksCollector.js +1 -1
- package/lib/client/PendingNavigation.d.ts +3 -3
- package/lib/client/PendingNavigation.js +3 -3
- package/lib/client/baseUrlIssueBanner/BaseUrlIssueBanner.d.ts +8 -0
- package/lib/client/baseUrlIssueBanner/BaseUrlIssueBanner.js +15 -10
- package/lib/client/clientEntry.js +8 -5
- package/lib/client/docusaurus.js +5 -3
- package/lib/client/exports/BrowserOnly.js +1 -1
- package/lib/client/exports/ComponentCreator.js +5 -2
- package/lib/client/exports/Head.js +1 -1
- package/lib/client/exports/Interpolate.js +9 -12
- package/lib/client/exports/Link.js +7 -4
- package/lib/client/exports/Translate.js +2 -1
- package/lib/client/exports/browserContext.js +3 -2
- package/lib/client/exports/docusaurusContext.js +1 -1
- package/lib/client/preload.d.ts +2 -1
- package/lib/client/preload.js +2 -1
- package/lib/client/serverEntry.js +8 -5
- package/lib/client/theme-fallback/Error/index.d.ts +11 -0
- package/lib/client/theme-fallback/Error/index.js +21 -28
- package/lib/client/theme-fallback/Layout/index.d.ts +11 -0
- package/lib/client/theme-fallback/Layout/index.js +10 -18
- package/lib/client/theme-fallback/Loading/index.d.ts +9 -0
- package/lib/client/theme-fallback/Loading/index.js +46 -114
- package/lib/client/theme-fallback/NotFound/index.d.ts +9 -0
- package/lib/client/theme-fallback/NotFound/index.js +8 -14
- package/lib/client/theme-fallback/Root/index.d.ts +11 -0
- package/lib/client/theme-fallback/Root/index.js +2 -4
- package/lib/commands/build.js +15 -17
- package/lib/commands/deploy.js +3 -3
- package/lib/commands/serve.js +2 -2
- package/lib/commands/swizzle.js +4 -2
- package/lib/commands/writeHeadingIds.js +10 -11
- package/lib/commands/writeTranslations.js +7 -4
- package/lib/server/brokenLinks.js +14 -9
- package/lib/server/configValidation.d.ts +1 -1
- package/lib/server/configValidation.js +2 -1
- package/lib/server/duplicateRoutes.js +2 -4
- package/lib/server/i18n.js +11 -15
- package/lib/server/index.js +9 -7
- package/lib/server/plugins/index.js +6 -6
- package/lib/server/plugins/init.js +12 -22
- package/lib/server/presets/index.js +2 -2
- package/lib/server/routes.js +2 -1
- package/lib/server/themes/index.js +3 -2
- package/lib/server/translations/translations.js +2 -4
- package/lib/server/translations/translationsExtractor.js +17 -14
- package/lib/server/versions/index.js +4 -2
- package/lib/webpack/base.js +19 -11
- package/lib/webpack/client.js +5 -2
- package/lib/webpack/plugins/ChunkAssetPlugin.d.ts +11 -0
- package/lib/webpack/plugins/ChunkAssetPlugin.js +17 -10
- package/lib/webpack/plugins/CleanWebpackPlugin.d.ts +4 -3
- package/lib/webpack/plugins/CleanWebpackPlugin.js +2 -1
- package/lib/webpack/server.js +4 -3
- package/lib/webpack/utils.js +8 -9
- package/package.json +10 -10
package/lib/babel/preset.js
CHANGED
|
@@ -11,7 +11,8 @@ const path_1 = (0, tslib_1.__importDefault)(require("path"));
|
|
|
11
11
|
function getTransformOptions(isServer) {
|
|
12
12
|
const absoluteRuntimePath = path_1.default.dirname(require.resolve(`@babel/runtime/package.json`));
|
|
13
13
|
return {
|
|
14
|
-
// All optional newlines and whitespace will be omitted when generating code
|
|
14
|
+
// All optional newlines and whitespace will be omitted when generating code
|
|
15
|
+
// in compact mode
|
|
15
16
|
compact: true,
|
|
16
17
|
presets: [
|
|
17
18
|
isServer
|
|
@@ -46,9 +47,9 @@ function getTransformOptions(isServer) {
|
|
|
46
47
|
{
|
|
47
48
|
corejs: false,
|
|
48
49
|
helpers: true,
|
|
49
|
-
// By default, it assumes @babel/runtime@7.0.0. Since we use >7.0.0,
|
|
50
|
-
// explicitly specify the version so that it can reuse the
|
|
51
|
-
// See https://github.com/babel/babel/issues/10261
|
|
50
|
+
// By default, it assumes @babel/runtime@7.0.0. Since we use >7.0.0,
|
|
51
|
+
// better to explicitly specify the version so that it can reuse the
|
|
52
|
+
// helper better. See https://github.com/babel/babel/issues/10261
|
|
52
53
|
// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
|
|
53
54
|
version: require('@babel/runtime/package.json').version,
|
|
54
55
|
regenerator: true,
|
package/lib/client/App.js
CHANGED
|
@@ -17,11 +17,17 @@ import './client-lifecycles-dispatcher';
|
|
|
17
17
|
import ErrorBoundary from '@docusaurus/ErrorBoundary';
|
|
18
18
|
import Error from '@theme/Error';
|
|
19
19
|
function App() {
|
|
20
|
-
return (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
return (<ErrorBoundary fallback={Error}>
|
|
21
|
+
<DocusaurusContextProvider>
|
|
22
|
+
<BrowserContextProvider>
|
|
23
|
+
<Root>
|
|
24
|
+
<BaseUrlIssueBanner />
|
|
25
|
+
<PendingNavigation routes={routes} delay={1000}>
|
|
26
|
+
{renderRoutes(routes)}
|
|
27
|
+
</PendingNavigation>
|
|
28
|
+
</Root>
|
|
29
|
+
</BrowserContextProvider>
|
|
30
|
+
</DocusaurusContextProvider>
|
|
31
|
+
</ErrorBoundary>);
|
|
26
32
|
}
|
|
27
33
|
export default App;
|
|
@@ -23,5 +23,5 @@ const Context = createContext({
|
|
|
23
23
|
});
|
|
24
24
|
export const useLinksCollector = () => useContext(Context);
|
|
25
25
|
export function ProvideLinksCollector({ children, linksCollector, }) {
|
|
26
|
-
return
|
|
26
|
+
return <Context.Provider value={linksCollector}>{children}</Context.Provider>;
|
|
27
27
|
}
|
|
@@ -23,9 +23,9 @@ declare class PendingNavigation extends React.Component<Props, State> {
|
|
|
23
23
|
progressBarTimeout: NodeJS.Timeout | null;
|
|
24
24
|
constructor(props: Props);
|
|
25
25
|
shouldComponentUpdate(nextProps: Props, nextState: State): boolean;
|
|
26
|
-
clearProgressBarTimeout
|
|
27
|
-
startProgressBar
|
|
28
|
-
stopProgressBar
|
|
26
|
+
private clearProgressBarTimeout;
|
|
27
|
+
private startProgressBar;
|
|
28
|
+
private stopProgressBar;
|
|
29
29
|
render(): JSX.Element;
|
|
30
30
|
}
|
|
31
31
|
declare const _default: React.ComponentClass<Pick<Props, "routes" | "delay">, any> & import("react-router").WithRouterStatics<typeof PendingNavigation>;
|
|
@@ -27,8 +27,8 @@ class PendingNavigation extends React.Component {
|
|
|
27
27
|
shouldComponentUpdate(nextProps, nextState) {
|
|
28
28
|
const routeDidChange = nextProps.location !== this.props.location;
|
|
29
29
|
const { routes, delay } = this.props;
|
|
30
|
-
// If `routeDidChange` is true, means the router is trying to navigate to a
|
|
31
|
-
// route. We will preload the new route.
|
|
30
|
+
// If `routeDidChange` is true, means the router is trying to navigate to a
|
|
31
|
+
// new route. We will preload the new route.
|
|
32
32
|
if (routeDidChange) {
|
|
33
33
|
const nextLocation = normalizeLocation(nextProps.location);
|
|
34
34
|
this.startProgressBar(delay);
|
|
@@ -92,7 +92,7 @@ class PendingNavigation extends React.Component {
|
|
|
92
92
|
}
|
|
93
93
|
render() {
|
|
94
94
|
const { children, location } = this.props;
|
|
95
|
-
return (
|
|
95
|
+
return (<Route location={normalizeLocation(location)} render={() => children}/>);
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
export default withRouter(PendingNavigation);
|
|
@@ -11,4 +11,12 @@ declare global {
|
|
|
11
11
|
__DOCUSAURUS_INSERT_BASEURL_BANNER: boolean;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* We want to help the users with a bad baseUrl configuration (very common
|
|
16
|
+
* error) Help message is inlined, and hidden if JS or CSS is able to load
|
|
17
|
+
* Note: it might create false positives (ie network failures): not a big deal
|
|
18
|
+
* Note: we only inline this for the homepage to avoid polluting all the site's
|
|
19
|
+
* pages
|
|
20
|
+
* @see https://github.com/facebook/docusaurus/pull/3621
|
|
21
|
+
*/
|
|
14
22
|
export default function BaseUrlIssueBanner(): JSX.Element | null;
|
|
@@ -67,21 +67,26 @@ function BaseUrlIssueBannerEnabled() {
|
|
|
67
67
|
useLayoutEffect(() => {
|
|
68
68
|
window[InsertBannerWindowAttribute] = false;
|
|
69
69
|
}, []);
|
|
70
|
-
return (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
return (<>
|
|
71
|
+
{!ExecutionEnvironment.canUseDOM && (<Head>
|
|
72
|
+
<script>{createInlineScript(baseUrl)}</script>
|
|
73
|
+
</Head>)}
|
|
74
|
+
<div id={BannerContainerId}/>
|
|
75
|
+
</>);
|
|
74
76
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
/**
|
|
78
|
+
* We want to help the users with a bad baseUrl configuration (very common
|
|
79
|
+
* error) Help message is inlined, and hidden if JS or CSS is able to load
|
|
80
|
+
* Note: it might create false positives (ie network failures): not a big deal
|
|
81
|
+
* Note: we only inline this for the homepage to avoid polluting all the site's
|
|
82
|
+
* pages
|
|
83
|
+
* @see https://github.com/facebook/docusaurus/pull/3621
|
|
84
|
+
*/
|
|
80
85
|
export default function BaseUrlIssueBanner() {
|
|
81
86
|
const { siteConfig: { baseUrl, baseUrlIssueBanner }, } = useDocusaurusContext();
|
|
82
87
|
const { pathname } = useLocation();
|
|
83
88
|
// returns true for the homepage during SRR
|
|
84
89
|
const isHomePage = pathname === baseUrl;
|
|
85
90
|
const enabled = baseUrlIssueBanner && isHomePage;
|
|
86
|
-
return enabled ?
|
|
91
|
+
return enabled ? <BaseUrlIssueBannerEnabled /> : null;
|
|
87
92
|
}
|
|
@@ -12,16 +12,19 @@ import ExecutionEnvironment from './exports/ExecutionEnvironment';
|
|
|
12
12
|
import App from './App';
|
|
13
13
|
import preload from './preload';
|
|
14
14
|
import docusaurus from './docusaurus';
|
|
15
|
-
// Client-side render (e.g: running in browser) to become single-page
|
|
15
|
+
// Client-side render (e.g: running in browser) to become single-page
|
|
16
|
+
// application (SPA).
|
|
16
17
|
if (ExecutionEnvironment.canUseDOM) {
|
|
17
18
|
window.docusaurus = docusaurus;
|
|
18
|
-
// For production, attempt to hydrate existing markup for performant
|
|
19
|
+
// For production, attempt to hydrate existing markup for performant
|
|
20
|
+
// first-load experience.
|
|
19
21
|
// For development, there is no existing markup so we had to render it.
|
|
20
|
-
//
|
|
22
|
+
// We also preload async component to avoid first-load loading screen.
|
|
21
23
|
const renderMethod = process.env.NODE_ENV === 'production' ? hydrate : render;
|
|
22
24
|
preload(routes, window.location.pathname).then(() => {
|
|
23
|
-
renderMethod(
|
|
24
|
-
|
|
25
|
+
renderMethod(<BrowserRouter>
|
|
26
|
+
<App />
|
|
27
|
+
</BrowserRouter>, document.getElementById('__docusaurus'));
|
|
25
28
|
});
|
|
26
29
|
// Webpack Hot Module Replacement API
|
|
27
30
|
if (module.hot) {
|
package/lib/client/docusaurus.js
CHANGED
|
@@ -41,11 +41,13 @@ const docusaurus = {
|
|
|
41
41
|
const chunkNamesNeeded = matches.flatMap((match) => getChunkNamesToLoad(match.route.path));
|
|
42
42
|
// Prefetch all webpack chunk assets file needed.
|
|
43
43
|
chunkNamesNeeded.forEach((chunkName) => {
|
|
44
|
-
// "__webpack_require__.gca" is a custom function provided by
|
|
45
|
-
// Pass it the chunkName or chunkId you want to load and
|
|
44
|
+
// "__webpack_require__.gca" is a custom function provided by
|
|
45
|
+
// ChunkAssetPlugin. Pass it the chunkName or chunkId you want to load and
|
|
46
|
+
// it will return the URL for that chunk.
|
|
46
47
|
// eslint-disable-next-line camelcase
|
|
47
48
|
const chunkAsset = __webpack_require__.gca(chunkName);
|
|
48
|
-
// In some cases, webpack might decide to optimize further & hence the
|
|
49
|
+
// In some cases, webpack might decide to optimize further & hence the
|
|
50
|
+
// chunk assets are merged to another chunk/previous chunk.
|
|
49
51
|
// Hence, we can safely filter it out/don't need to load it.
|
|
50
52
|
if (chunkAsset && !/undefined/.test(chunkAsset)) {
|
|
51
53
|
prefetchHelper(chunkAsset);
|
|
@@ -16,7 +16,7 @@ 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
|
|
19
|
+
return <>{children()}</>;
|
|
20
20
|
}
|
|
21
21
|
return fallback || null;
|
|
22
22
|
}
|
|
@@ -32,7 +32,10 @@ function ComponentCreator(path, hash) {
|
|
|
32
32
|
content.foo: () => import('./doc1.md'),
|
|
33
33
|
}
|
|
34
34
|
- optsModules: ['./Pages.js', './doc1.md']
|
|
35
|
-
- optsWebpack: [
|
|
35
|
+
- optsWebpack: [
|
|
36
|
+
require.resolveWeak('./Pages.js'),
|
|
37
|
+
require.resolveWeak('./doc1.md'),
|
|
38
|
+
]
|
|
36
39
|
*/
|
|
37
40
|
const flatChunkNames = flat(chunkNames);
|
|
38
41
|
Object.keys(flatChunkNames).forEach((key) => {
|
|
@@ -69,7 +72,7 @@ function ComponentCreator(path, hash) {
|
|
|
69
72
|
});
|
|
70
73
|
const Component = loadedModules.component;
|
|
71
74
|
delete loadedModules.component;
|
|
72
|
-
return
|
|
75
|
+
return <Component {...loadedModules} {...props}/>;
|
|
73
76
|
},
|
|
74
77
|
});
|
|
75
78
|
}
|
|
@@ -26,29 +26,26 @@ export function interpolate(text, values) {
|
|
|
26
26
|
elements.push(element);
|
|
27
27
|
return ValueFoundMarker;
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
return match; // no match? add warning?
|
|
31
|
-
}
|
|
29
|
+
return match; // no match? add warning?
|
|
32
30
|
});
|
|
33
31
|
// No interpolation to be done: just return the text
|
|
34
32
|
if (elements.length === 0) {
|
|
35
33
|
return text;
|
|
36
34
|
}
|
|
37
35
|
// Basic string interpolation: returns interpolated string
|
|
38
|
-
|
|
36
|
+
if (elements.every((el) => typeof el === 'string')) {
|
|
39
37
|
return processedText
|
|
40
38
|
.split(ValueFoundMarker)
|
|
41
39
|
.reduce((str, value, index) => { var _a; return str.concat(value).concat((_a = elements[index]) !== null && _a !== void 0 ? _a : ''); }, '');
|
|
42
40
|
}
|
|
43
41
|
// JSX interpolation: returns ReactNode
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
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
|
+
], []);
|
|
52
49
|
}
|
|
53
50
|
export default function Interpolate({ children, values, }) {
|
|
54
51
|
if (typeof children !== 'string') {
|
|
@@ -57,7 +57,7 @@ function Link({ isNavLink, to, href, activeClassName, isActive, 'data-noBrokenLi
|
|
|
57
57
|
ioRef.current = new window.IntersectionObserver((entries) => {
|
|
58
58
|
entries.forEach((entry) => {
|
|
59
59
|
if (el === entry.target) {
|
|
60
|
-
// If element is in viewport, stop
|
|
60
|
+
// If element is in viewport, stop observing and run callback.
|
|
61
61
|
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
|
|
62
62
|
if (entry.isIntersecting || entry.intersectionRatio > 0) {
|
|
63
63
|
ioRef.current.unobserve(el);
|
|
@@ -72,7 +72,7 @@ function Link({ isNavLink, to, href, activeClassName, isActive, 'data-noBrokenLi
|
|
|
72
72
|
};
|
|
73
73
|
const handleRef = (ref) => {
|
|
74
74
|
if (IOSupported && ref && isInternal) {
|
|
75
|
-
// If IO supported and element reference found,
|
|
75
|
+
// If IO supported and element reference found, set up Observer.
|
|
76
76
|
handleIntersection(ref, () => {
|
|
77
77
|
if (targetLink != null) {
|
|
78
78
|
window.docusaurus.prefetch(targetLink);
|
|
@@ -107,7 +107,10 @@ function Link({ isNavLink, to, href, activeClassName, isActive, 'data-noBrokenLi
|
|
|
107
107
|
}
|
|
108
108
|
return isRegularHtmlLink ? (
|
|
109
109
|
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
<a href={targetLink} {...(targetLinkUnprefixed &&
|
|
111
|
+
!isInternal && { target: '_blank', rel: 'noopener noreferrer' })} {...props}/>) : (<LinkComponent {...props} onMouseEnter={onMouseEnter} innerRef={handleRef} to={targetLink || ''}
|
|
112
|
+
// avoid "React does not recognize the `activeClassName` prop on a DOM
|
|
113
|
+
// element"
|
|
114
|
+
{...(isNavLink && { isActive, activeClassName })}/>);
|
|
112
115
|
}
|
|
113
116
|
export default Link;
|
|
@@ -22,7 +22,8 @@ export function translate({ message, id }, values) {
|
|
|
22
22
|
return interpolate(localizedMessage, values);
|
|
23
23
|
}
|
|
24
24
|
// Maybe we'll want to improve this component with additional features
|
|
25
|
-
// Like toggling a translation mode that adds a little translation button near
|
|
25
|
+
// Like toggling a translation mode that adds a little translation button near
|
|
26
|
+
// the text?
|
|
26
27
|
export default function Translate({ children, id, values, }) {
|
|
27
28
|
if (children && typeof children !== 'string') {
|
|
28
29
|
console.warn('Illegal <Translate> children', children);
|
|
@@ -10,12 +10,13 @@ import React, { useEffect, useState } from 'react';
|
|
|
10
10
|
// On first client-side render, we need to render exactly as the server rendered
|
|
11
11
|
// isBrowser is set to true only after a successful hydration
|
|
12
12
|
// Note, isBrowser is not part of useDocusaurusContext() for perf reasons
|
|
13
|
-
// Using useDocusaurusContext() (much more common need) should not trigger
|
|
13
|
+
// Using useDocusaurusContext() (much more common need) should not trigger
|
|
14
|
+
// re-rendering after a successful hydration
|
|
14
15
|
export const Context = React.createContext(false);
|
|
15
16
|
export function BrowserContextProvider({ children, }) {
|
|
16
17
|
const [isBrowser, setIsBrowser] = useState(false);
|
|
17
18
|
useEffect(() => {
|
|
18
19
|
setIsBrowser(true);
|
|
19
20
|
}, []);
|
|
20
|
-
return
|
|
21
|
+
return <Context.Provider value={isBrowser}>{children}</Context.Provider>;
|
|
21
22
|
}
|
|
@@ -21,5 +21,5 @@ const contextValue = {
|
|
|
21
21
|
};
|
|
22
22
|
export const Context = React.createContext(contextValue);
|
|
23
23
|
export function DocusaurusContextProvider({ children, }) {
|
|
24
|
-
return
|
|
24
|
+
return <Context.Provider value={contextValue}>{children}</Context.Provider>;
|
|
25
25
|
}
|
package/lib/client/preload.d.ts
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
import { type RouteConfig } from 'react-router-config';
|
|
8
8
|
/**
|
|
9
9
|
* Helper function to make sure all async components for that particular route
|
|
10
|
-
* is preloaded before rendering. This is especially useful to avoid loading
|
|
10
|
+
* is preloaded before rendering. This is especially useful to avoid loading
|
|
11
|
+
* screens.
|
|
11
12
|
*
|
|
12
13
|
* @param routes react-router-config
|
|
13
14
|
* @param pathname the route pathname, example: /docs/installation
|
package/lib/client/preload.js
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
import { matchRoutes } from 'react-router-config';
|
|
8
8
|
/**
|
|
9
9
|
* Helper function to make sure all async components for that particular route
|
|
10
|
-
* is preloaded before rendering. This is especially useful to avoid loading
|
|
10
|
+
* is preloaded before rendering. This is especially useful to avoid loading
|
|
11
|
+
* screens.
|
|
11
12
|
*
|
|
12
13
|
* @param routes react-router-config
|
|
13
14
|
* @param pathname the route pathname, example: /docs/installation
|
|
@@ -46,7 +46,7 @@ It might also require to wrap your client code in code=${'useEffect'} hook and/o
|
|
|
46
46
|
throw new Error('Server-side rendering fails due to the error above.');
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
// Renderer for static-site-generator-webpack-plugin (async rendering
|
|
49
|
+
// Renderer for static-site-generator-webpack-plugin (async rendering).
|
|
50
50
|
async function doRender(locals) {
|
|
51
51
|
const { routesLocation, headTags, preBodyTags, postBodyTags, onLinksCollected, baseUrl, ssrTemplate, noIndex, } = locals;
|
|
52
52
|
const location = routesLocation[locals.path];
|
|
@@ -54,10 +54,13 @@ async function doRender(locals) {
|
|
|
54
54
|
const modules = new Set();
|
|
55
55
|
const context = {};
|
|
56
56
|
const linksCollector = createStatefulLinksCollector();
|
|
57
|
-
const appHtml = ReactDOMServer.renderToString(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
const appHtml = ReactDOMServer.renderToString(<Loadable.Capture report={(moduleName) => modules.add(moduleName)}>
|
|
58
|
+
<StaticRouter location={location} context={context}>
|
|
59
|
+
<ProvideLinksCollector linksCollector={linksCollector}>
|
|
60
|
+
<App />
|
|
61
|
+
</ProvideLinksCollector>
|
|
62
|
+
</StaticRouter>
|
|
63
|
+
</Loadable.Capture>);
|
|
61
64
|
onLinksCollected(location, linksCollector.getCollectedLinks());
|
|
62
65
|
const helmet = Helmet.renderStatic();
|
|
63
66
|
const htmlAttributes = helmet.htmlAttributes.toString();
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
/// <reference types="@docusaurus/module-type-aliases" />
|
|
8
|
+
/// <reference types="react" />
|
|
9
|
+
import type { Props } from '@theme/Error';
|
|
10
|
+
declare function Error({ error, tryAgain }: Props): JSX.Element;
|
|
11
|
+
export default Error;
|
|
@@ -4,44 +4,37 @@
|
|
|
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
7
|
import React from 'react';
|
|
9
8
|
import Layout from '@theme/Layout';
|
|
10
9
|
import ErrorBoundary from '@docusaurus/ErrorBoundary';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
width: '100%',
|
|
22
|
-
fontSize: '20px',
|
|
23
|
-
}}>
|
|
10
|
+
function ErrorDisplay({ error, tryAgain }) {
|
|
11
|
+
return (<div style={{
|
|
12
|
+
display: 'flex',
|
|
13
|
+
flexDirection: 'column',
|
|
14
|
+
justifyContent: 'center',
|
|
15
|
+
alignItems: 'center',
|
|
16
|
+
height: '50vh',
|
|
17
|
+
width: '100%',
|
|
18
|
+
fontSize: '20px',
|
|
19
|
+
}}>
|
|
24
20
|
<h1>This page crashed.</h1>
|
|
25
21
|
<p>{error.message}</p>
|
|
26
22
|
<button type="button" onClick={tryAgain}>
|
|
27
23
|
Try again
|
|
28
24
|
</button>
|
|
29
|
-
</div>
|
|
30
|
-
);
|
|
25
|
+
</div>);
|
|
31
26
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
function Error({ error, tryAgain }) {
|
|
28
|
+
// We wrap the error in its own error boundary because the layout can actually
|
|
29
|
+
// throw too... Only the ErrorDisplay component is simple enough to be
|
|
30
|
+
// considered safe to never throw
|
|
31
|
+
return (<ErrorBoundary
|
|
32
|
+
// Note: we display the original error here, not the error that we
|
|
33
|
+
// captured in this extra error boundary
|
|
34
|
+
fallback={() => <ErrorDisplay error={error} tryAgain={tryAgain}/>}>
|
|
40
35
|
<Layout title="Page Error">
|
|
41
|
-
<ErrorDisplay error={error} tryAgain={tryAgain}
|
|
36
|
+
<ErrorDisplay error={error} tryAgain={tryAgain}/>
|
|
42
37
|
</Layout>
|
|
43
|
-
</ErrorBoundary>
|
|
44
|
-
);
|
|
38
|
+
</ErrorBoundary>);
|
|
45
39
|
}
|
|
46
|
-
|
|
47
40
|
export default Error;
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
/// <reference types="@docusaurus/module-type-aliases" />
|
|
8
|
+
/// <reference types="react" />
|
|
9
|
+
import type { Props } from '@theme/Layout';
|
|
10
|
+
declare function Layout({ children, title, description }: Props): JSX.Element;
|
|
11
|
+
export default Layout;
|
|
@@ -4,31 +4,23 @@
|
|
|
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
7
|
import React from 'react';
|
|
9
8
|
import Head from '@docusaurus/Head';
|
|
10
9
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
|
11
10
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const faviconUrl = useBaseUrl(favicon);
|
|
19
|
-
return (
|
|
20
|
-
<>
|
|
11
|
+
function Layout({ children, title, description }) {
|
|
12
|
+
const context = useDocusaurusContext();
|
|
13
|
+
const { siteConfig } = context;
|
|
14
|
+
const { favicon, tagline, title: defaultTitle } = siteConfig;
|
|
15
|
+
const faviconUrl = useBaseUrl(favicon);
|
|
16
|
+
return (<>
|
|
21
17
|
<Head defaultTitle={`${defaultTitle}${tagline ? ` · ${tagline}` : ''}`}>
|
|
22
18
|
{title && <title>{`${title} · ${tagline}`}</title>}
|
|
23
|
-
{favicon && <link rel="icon" href={faviconUrl}
|
|
24
|
-
{description && <meta name="description" content={description}
|
|
25
|
-
{description && (
|
|
26
|
-
<meta property="og:description" content={description} />
|
|
27
|
-
)}
|
|
19
|
+
{favicon && <link rel="icon" href={faviconUrl}/>}
|
|
20
|
+
{description && <meta name="description" content={description}/>}
|
|
21
|
+
{description && (<meta property="og:description" content={description}/>)}
|
|
28
22
|
</Head>
|
|
29
23
|
{children}
|
|
30
|
-
</>
|
|
31
|
-
);
|
|
24
|
+
</>);
|
|
32
25
|
}
|
|
33
|
-
|
|
34
26
|
export default Layout;
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
+
/// <reference types="react" />
|
|
8
|
+
import type { LoadingComponentProps } from 'react-loadable';
|
|
9
|
+
export default function Loading({ error, retry, pastDelay, }: LoadingComponentProps): JSX.Element | null;
|