@docusaurus/core 2.0.0-beta.12faed89d → 2.0.0-beta.14
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.js +46 -22
- package/bin/docusaurus.js +42 -44
- package/lib/babel/preset.d.ts +6 -0
- package/lib/babel/preset.js +3 -3
- package/lib/choosePort.js +19 -20
- package/lib/client/.eslintrc.js +0 -1
- package/lib/client/App.js +12 -22
- package/lib/client/LinksCollector.d.ts +2 -2
- package/lib/client/LinksCollector.js +4 -8
- package/lib/client/PendingNavigation.d.ts +24 -1
- package/lib/client/PendingNavigation.js +1 -1
- package/lib/client/baseUrlIssueBanner/BaseUrlIssueBanner.d.ts +5 -0
- package/lib/client/client-lifecycles-dispatcher.d.ts +2 -2
- package/lib/client/client-lifecycles-dispatcher.js +0 -2
- package/lib/client/docusaurus.d.ts +6 -0
- package/lib/client/docusaurus.js +11 -19
- package/lib/client/exports/BrowserOnly.js +5 -3
- package/lib/client/exports/ErrorBoundary.d.ts +18 -0
- package/lib/client/exports/ErrorBoundary.js +35 -0
- package/lib/client/exports/Interpolate.js +12 -15
- package/lib/client/exports/Link.js +9 -9
- package/lib/client/exports/Translate.d.ts +2 -2
- package/lib/client/exports/Translate.js +13 -9
- package/lib/client/exports/browserContext.d.ts +11 -0
- package/lib/client/exports/browserContext.js +21 -0
- package/lib/client/exports/constants.js +1 -11
- package/lib/client/exports/{context.d.ts → docusaurusContext.d.ts} +5 -3
- package/lib/client/exports/docusaurusContext.js +25 -0
- package/lib/client/exports/useBaseUrl.js +2 -4
- package/lib/client/exports/useDocusaurusContext.js +2 -7
- package/lib/client/exports/useGlobalData.js +1 -5
- package/lib/client/exports/{context.js → useIsBrowser.d.ts} +1 -2
- package/lib/{webpack/sharedModuleAliases.d.ts → client/exports/useIsBrowser.js} +5 -4
- package/lib/client/flat.d.ts +2 -1
- package/lib/client/flat.js +7 -9
- package/lib/client/normalizeLocation.d.ts +1 -3
- package/lib/client/prefetch.js +0 -1
- package/lib/client/serverEntry.js +20 -42
- package/lib/client/theme-fallback/Error/index.js +47 -0
- package/lib/client/theme-fallback/Layout/index.js +1 -1
- package/lib/client/theme-fallback/Loading/index.js +2 -2
- package/lib/client/theme-fallback/Root/index.js +1 -3
- package/lib/commands/build.js +39 -44
- package/lib/commands/clear.d.ts +6 -0
- package/lib/commands/clear.js +17 -18
- package/lib/commands/commandUtils.d.ts +6 -0
- package/lib/commands/commandUtils.js +7 -7
- package/lib/commands/deploy.d.ts +3 -0
- package/lib/commands/deploy.js +99 -64
- package/lib/commands/external.js +4 -4
- package/lib/commands/serve.js +12 -18
- package/lib/commands/start.js +98 -86
- package/lib/commands/swizzle.js +42 -51
- package/lib/commands/writeHeadingIds.d.ts +9 -6
- package/lib/commands/writeHeadingIds.js +33 -34
- package/lib/commands/writeTranslations.js +31 -11
- package/lib/server/brokenLinks.js +13 -17
- package/lib/server/client-modules/index.js +1 -3
- package/lib/server/config.js +4 -4
- package/lib/server/configValidation.d.ts +1 -1
- package/lib/server/configValidation.js +14 -7
- package/lib/server/duplicateRoutes.js +8 -2
- package/lib/server/html-tags/htmlTags.js +5 -6
- package/lib/server/html-tags/index.js +2 -2
- package/lib/server/i18n.js +16 -16
- package/lib/server/index.js +132 -59
- package/lib/server/loadSetup.js +3 -3
- package/lib/server/moduleShorthand.d.ts +9 -0
- package/lib/server/moduleShorthand.js +42 -0
- package/lib/server/plugins/applyRouteTrailingSlash.js +1 -1
- package/lib/server/plugins/index.d.ts +1 -1
- package/lib/server/plugins/index.js +25 -21
- package/lib/server/plugins/init.js +9 -12
- package/lib/server/plugins/pluginIds.js +6 -4
- package/lib/server/presets/index.js +12 -12
- package/lib/server/routes.js +9 -11
- package/lib/server/themes/alias.d.ts +1 -0
- package/lib/server/themes/alias.js +21 -12
- package/lib/server/themes/index.d.ts +1 -1
- package/lib/server/themes/index.js +22 -23
- package/lib/server/translations/translations.d.ts +6 -0
- package/lib/server/translations/translations.js +19 -26
- package/lib/server/translations/translationsExtractor.d.ts +7 -1
- package/lib/server/translations/translationsExtractor.js +66 -59
- package/lib/server/utils.d.ts +8 -2
- package/lib/server/utils.js +8 -10
- package/lib/server/versions/__fixtures__/dummy-plugin.d.ts +0 -0
- package/lib/server/versions/__tests/index.test.js +5 -5
- package/lib/server/versions/index.js +6 -6
- package/lib/webpack/base.js +14 -16
- package/lib/webpack/client.js +9 -18
- package/lib/webpack/plugins/CleanWebpackPlugin.js +4 -11
- package/lib/webpack/plugins/LogPlugin.js +5 -6
- package/lib/webpack/plugins/WaitPlugin.js +4 -4
- package/lib/webpack/server.js +9 -9
- package/lib/webpack/utils.d.ts +0 -22
- package/lib/webpack/utils.js +37 -134
- package/package.json +55 -50
- package/lib/.tsbuildinfo +0 -1
- package/lib/client/.tsbuildinfo +0 -1
- package/lib/commands/buildRemoteBranchUrl.d.ts +0 -7
- package/lib/commands/buildRemoteBranchUrl.js +0 -27
- package/lib/constants.d.ts +0 -18
- package/lib/constants.js +0 -23
- package/lib/webpack/react-dev-utils-webpack5/README.md +0 -11
- package/lib/webpack/react-dev-utils-webpack5/evalSourceMapMiddleware.js +0 -57
- package/lib/webpack/react-dev-utils-webpack5/formatWebpackMessages.js +0 -138
- package/lib/webpack/react-dev-utils-webpack5/webpackHotDevClient.js +0 -285
- package/lib/webpack/sharedModuleAliases.js +0 -18
- package/tsconfig.client.json +0 -13
- package/tsconfig.json +0 -13
|
@@ -5,10 +5,12 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
|
-
import
|
|
8
|
+
import useIsBrowser from '@docusaurus/useIsBrowser';
|
|
9
|
+
// Similar comp to the one described here:
|
|
10
|
+
// https://www.joshwcomeau.com/react/the-perils-of-rehydration/#abstractions
|
|
9
11
|
function BrowserOnly({ children, fallback, }) {
|
|
10
|
-
const
|
|
11
|
-
if (
|
|
12
|
+
const isBrowser = useIsBrowser();
|
|
13
|
+
if (isBrowser && children != null) {
|
|
12
14
|
return React.createElement(React.Fragment, null, children());
|
|
13
15
|
}
|
|
14
16
|
return fallback || null;
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
import React, { ReactNode } from 'react';
|
|
9
|
+
import type { Props } from '@docusaurus/ErrorBoundary';
|
|
10
|
+
interface State {
|
|
11
|
+
error: Error | null;
|
|
12
|
+
}
|
|
13
|
+
declare class ErrorBoundary extends React.Component<Props, State> {
|
|
14
|
+
constructor(props: Props);
|
|
15
|
+
componentDidCatch(error: Error): void;
|
|
16
|
+
render(): ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export default ErrorBoundary;
|
|
@@ -0,0 +1,35 @@
|
|
|
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 ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
|
9
|
+
import DefaultFallback from '@theme/Error';
|
|
10
|
+
class ErrorBoundary extends React.Component {
|
|
11
|
+
constructor(props) {
|
|
12
|
+
super(props);
|
|
13
|
+
this.state = { error: null };
|
|
14
|
+
}
|
|
15
|
+
componentDidCatch(error) {
|
|
16
|
+
// Catch errors in any components below and re-render with error message
|
|
17
|
+
if (ExecutionEnvironment.canUseDOM) {
|
|
18
|
+
this.setState({ error });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
render() {
|
|
22
|
+
var _a;
|
|
23
|
+
const { children } = this.props;
|
|
24
|
+
const { error } = this.state;
|
|
25
|
+
if (error) {
|
|
26
|
+
const fallback = (_a = this.props.fallback) !== null && _a !== void 0 ? _a : DefaultFallback;
|
|
27
|
+
return fallback({
|
|
28
|
+
error,
|
|
29
|
+
tryAgain: () => this.setState({ error: null }),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return children;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export default ErrorBoundary;
|
|
@@ -16,7 +16,7 @@ export function interpolate(text, values) {
|
|
|
16
16
|
const elements = [];
|
|
17
17
|
const processedText = text.replace(ValueRegexp, (match) => {
|
|
18
18
|
// remove {{ and }} around the placeholder
|
|
19
|
-
const key = match.
|
|
19
|
+
const key = match.substring(1, match.length - 1);
|
|
20
20
|
const value = values === null || values === void 0 ? void 0 : values[key];
|
|
21
21
|
if (typeof value !== 'undefined') {
|
|
22
22
|
const element = React.isValidElement(value)
|
|
@@ -38,25 +38,22 @@ export function interpolate(text, values) {
|
|
|
38
38
|
else if (elements.every((el) => typeof el === 'string')) {
|
|
39
39
|
return processedText
|
|
40
40
|
.split(ValueFoundMarker)
|
|
41
|
-
.reduce((str, value, index) => {
|
|
42
|
-
var _a;
|
|
43
|
-
return str.concat(value).concat((_a = elements[index]) !== null && _a !== void 0 ? _a : '');
|
|
44
|
-
}, '');
|
|
41
|
+
.reduce((str, value, index) => { var _a; return str.concat(value).concat((_a = elements[index]) !== null && _a !== void 0 ? _a : ''); }, '');
|
|
45
42
|
}
|
|
46
43
|
// JSX interpolation: returns ReactNode
|
|
47
44
|
else {
|
|
48
|
-
return processedText
|
|
49
|
-
|
|
50
|
-
.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
value,
|
|
55
|
-
elements[index]),
|
|
56
|
-
];
|
|
57
|
-
}, []);
|
|
45
|
+
return processedText.split(ValueFoundMarker).reduce((array, value, index) => [
|
|
46
|
+
...array,
|
|
47
|
+
React.createElement(React.Fragment, { key: index },
|
|
48
|
+
value,
|
|
49
|
+
elements[index]),
|
|
50
|
+
], []);
|
|
58
51
|
}
|
|
59
52
|
}
|
|
60
53
|
export default function Interpolate({ children, values, }) {
|
|
54
|
+
if (typeof children !== 'string') {
|
|
55
|
+
console.warn('Illegal <Interpolate> children', children);
|
|
56
|
+
throw new Error('The Docusaurus <Interpolate> component only accept simple string values');
|
|
57
|
+
}
|
|
61
58
|
return interpolate(children, values);
|
|
62
59
|
}
|
|
@@ -50,25 +50,25 @@ function Link({ isNavLink, to, href, activeClassName, isActive, 'data-noBrokenLi
|
|
|
50
50
|
targetLink = applyTrailingSlash(targetLink, { trailingSlash, baseUrl });
|
|
51
51
|
}
|
|
52
52
|
const preloaded = useRef(false);
|
|
53
|
-
const LinkComponent = isNavLink ? NavLink : RRLink;
|
|
53
|
+
const LinkComponent = (isNavLink ? NavLink : RRLink);
|
|
54
54
|
const IOSupported = ExecutionEnvironment.canUseIntersectionObserver;
|
|
55
|
-
|
|
55
|
+
const ioRef = useRef();
|
|
56
56
|
const handleIntersection = (el, cb) => {
|
|
57
|
-
|
|
57
|
+
ioRef.current = new window.IntersectionObserver((entries) => {
|
|
58
58
|
entries.forEach((entry) => {
|
|
59
59
|
if (el === entry.target) {
|
|
60
60
|
// If element is in viewport, stop listening/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
|
-
|
|
64
|
-
|
|
63
|
+
ioRef.current.unobserve(el);
|
|
64
|
+
ioRef.current.disconnect();
|
|
65
65
|
cb();
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
69
|
});
|
|
70
70
|
// Add element to the observer.
|
|
71
|
-
|
|
71
|
+
ioRef.current.observe(el);
|
|
72
72
|
};
|
|
73
73
|
const handleRef = (ref) => {
|
|
74
74
|
if (IOSupported && ref && isInternal) {
|
|
@@ -95,11 +95,11 @@ function Link({ isNavLink, to, href, activeClassName, isActive, 'data-noBrokenLi
|
|
|
95
95
|
}
|
|
96
96
|
// When unmounting, stop intersection observer from watching.
|
|
97
97
|
return () => {
|
|
98
|
-
if (IOSupported &&
|
|
99
|
-
|
|
98
|
+
if (IOSupported && ioRef.current) {
|
|
99
|
+
ioRef.current.disconnect();
|
|
100
100
|
}
|
|
101
101
|
};
|
|
102
|
-
}, [targetLink, IOSupported, isInternal]);
|
|
102
|
+
}, [ioRef, targetLink, IOSupported, isInternal]);
|
|
103
103
|
const isAnchorLink = (_a = targetLink === null || targetLink === void 0 ? void 0 : targetLink.startsWith('#')) !== null && _a !== void 0 ? _a : false;
|
|
104
104
|
const isRegularHtmlLink = !targetLink || !isInternal || isAnchorLink;
|
|
105
105
|
if (targetLink && isInternal && !isAnchorLink && !noBrokenLinkCheck) {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
/// <reference types="@docusaurus/module-type-aliases" />
|
|
8
|
-
|
|
8
|
+
import { ReactNode } from 'react';
|
|
9
9
|
import { InterpolateValues } from '@docusaurus/Interpolate';
|
|
10
10
|
import type { TranslateParam, TranslateProps } from '@docusaurus/Translate';
|
|
11
11
|
export declare function translate<Str extends string>({ message, id }: TranslateParam<Str>, values?: InterpolateValues<Str, string | number>): string;
|
|
12
|
-
export default function Translate<Str extends string>({ children, id, values, }: TranslateProps<Str>):
|
|
12
|
+
export default function Translate<Str extends string>({ children, id, values, }: TranslateProps<Str>): ReactNode;
|
|
@@ -4,26 +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
|
|
8
|
-
import Interpolate, { interpolate, } from '@docusaurus/Interpolate';
|
|
7
|
+
import { interpolate } from '@docusaurus/Interpolate';
|
|
9
8
|
// Can't read it from context, due to exposing imperative API
|
|
10
9
|
import codeTranslations from '@generated/codeTranslations';
|
|
11
10
|
function getLocalizedMessage({ id, message, }) {
|
|
12
|
-
var _a;
|
|
13
|
-
|
|
11
|
+
var _a, _b;
|
|
12
|
+
if (typeof id === 'undefined' && typeof message === 'undefined') {
|
|
13
|
+
throw new Error('Docusaurus translation declarations must have at least a translation id or a default translation message');
|
|
14
|
+
}
|
|
15
|
+
return (_b = (_a = codeTranslations[(id !== null && id !== void 0 ? id : message)]) !== null && _a !== void 0 ? _a : message) !== null && _b !== void 0 ? _b : id;
|
|
14
16
|
}
|
|
15
17
|
// Imperative translation API is useful for some edge-cases:
|
|
16
18
|
// - translating page titles (meta)
|
|
17
19
|
// - translating string props (input placeholders, image alt, aria labels...)
|
|
18
20
|
export function translate({ message, id }, values) {
|
|
19
|
-
|
|
20
|
-
const localizedMessage = (_a = getLocalizedMessage({ message, id })) !== null && _a !== void 0 ? _a : message;
|
|
21
|
+
const localizedMessage = getLocalizedMessage({ message, id });
|
|
21
22
|
return interpolate(localizedMessage, values);
|
|
22
23
|
}
|
|
23
24
|
// Maybe we'll want to improve this component with additional features
|
|
24
25
|
// Like toggling a translation mode that adds a little translation button near the text?
|
|
25
26
|
export default function Translate({ children, id, values, }) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
if (children && typeof children !== 'string') {
|
|
28
|
+
console.warn('Illegal <Translate> children', children);
|
|
29
|
+
throw new Error('The Docusaurus <Translate> component only accept simple string values');
|
|
30
|
+
}
|
|
31
|
+
const localizedMessage = getLocalizedMessage({ message: children, id });
|
|
32
|
+
return interpolate(localizedMessage, values);
|
|
29
33
|
}
|
|
@@ -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
|
+
import React, { ReactNode } from 'react';
|
|
8
|
+
export declare const Context: React.Context<boolean>;
|
|
9
|
+
export declare function BrowserContextProvider({ children, }: {
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
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, { useEffect, useState } from 'react';
|
|
8
|
+
// Encapsulate the logic to avoid React hydration problems
|
|
9
|
+
// See https://www.joshwcomeau.com/react/the-perils-of-rehydration/
|
|
10
|
+
// On first client-side render, we need to render exactly as the server rendered
|
|
11
|
+
// isBrowser is set to true only after a successful hydration
|
|
12
|
+
// Note, isBrowser is not part of useDocusaurusContext() for perf reasons
|
|
13
|
+
// Using useDocusaurusContext() (much more common need) should not trigger re-rendering after a successful hydration
|
|
14
|
+
export const Context = React.createContext(false);
|
|
15
|
+
export function BrowserContextProvider({ children, }) {
|
|
16
|
+
const [isBrowser, setIsBrowser] = useState(false);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setIsBrowser(true);
|
|
19
|
+
}, []);
|
|
20
|
+
return React.createElement(Context.Provider, { value: isBrowser }, children);
|
|
21
|
+
}
|
|
@@ -4,15 +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
|
-
// eslint-disable-next-line no-restricted-imports
|
|
9
|
-
export {
|
|
10
|
-
// constants were only available on node
|
|
11
|
-
// this makes some useful constants available to frontend/themes too
|
|
12
|
-
// import {DEFAULT_PLUGIN_ID} '@docusaurus/constants'
|
|
13
|
-
DEFAULT_PLUGIN_ID,
|
|
14
|
-
} from '../../constants';
|
|
15
|
-
*/
|
|
16
|
-
// Not duplicating the constants seems to produce
|
|
17
|
-
// weird TS compilation side-effects
|
|
7
|
+
// Constants used on the client-side: duplicated from server-side code
|
|
18
8
|
export const DEFAULT_PLUGIN_ID = 'default';
|
|
@@ -4,7 +4,9 @@
|
|
|
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';
|
|
7
|
+
import React, { ReactNode } from 'react';
|
|
8
8
|
import { DocusaurusContext } from '@docusaurus/types';
|
|
9
|
-
declare const
|
|
10
|
-
export
|
|
9
|
+
export declare const Context: React.Context<DocusaurusContext>;
|
|
10
|
+
export declare function DocusaurusContextProvider({ children, }: {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
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 siteConfig from '@generated/docusaurus.config';
|
|
9
|
+
import globalData from '@generated/globalData';
|
|
10
|
+
import i18n from '@generated/i18n';
|
|
11
|
+
import codeTranslations from '@generated/codeTranslations';
|
|
12
|
+
import siteMetadata from '@generated/site-metadata';
|
|
13
|
+
// Static value on purpose: don't make it dynamic!
|
|
14
|
+
// Using context is still useful for testability reasons.
|
|
15
|
+
const contextValue = {
|
|
16
|
+
siteConfig,
|
|
17
|
+
siteMetadata,
|
|
18
|
+
globalData,
|
|
19
|
+
i18n,
|
|
20
|
+
codeTranslations,
|
|
21
|
+
};
|
|
22
|
+
export const Context = React.createContext(contextValue);
|
|
23
|
+
export function DocusaurusContextProvider({ children, }) {
|
|
24
|
+
return React.createElement(Context.Provider, { value: contextValue }, children);
|
|
25
|
+
}
|
|
@@ -27,11 +27,9 @@ function addBaseUrl(siteUrl, baseUrl, url, { forcePrependBaseUrl = false, absolu
|
|
|
27
27
|
return absolute ? siteUrl + basePath : basePath;
|
|
28
28
|
}
|
|
29
29
|
export function useBaseUrlUtils() {
|
|
30
|
-
const { siteConfig: { baseUrl = '/', url: siteUrl } = {}
|
|
30
|
+
const { siteConfig: { baseUrl = '/', url: siteUrl } = {} } = useDocusaurusContext();
|
|
31
31
|
return {
|
|
32
|
-
withBaseUrl: (url, options) =>
|
|
33
|
-
return addBaseUrl(siteUrl, baseUrl, url, options);
|
|
34
|
-
},
|
|
32
|
+
withBaseUrl: (url, options) => addBaseUrl(siteUrl, baseUrl, url, options),
|
|
35
33
|
};
|
|
36
34
|
}
|
|
37
35
|
export default function useBaseUrl(url, options = {}) {
|
|
@@ -5,13 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import { useContext } from 'react';
|
|
8
|
-
import
|
|
8
|
+
import { Context } from './docusaurusContext';
|
|
9
9
|
function useDocusaurusContext() {
|
|
10
|
-
|
|
11
|
-
if (docusaurusContext === null) {
|
|
12
|
-
// should not happen normally
|
|
13
|
-
throw new Error('Docusaurus context not provided.');
|
|
14
|
-
}
|
|
15
|
-
return docusaurusContext;
|
|
10
|
+
return useContext(Context);
|
|
16
11
|
}
|
|
17
12
|
export default useDocusaurusContext;
|
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import useDocusaurusContext from './useDocusaurusContext';
|
|
8
|
-
|
|
9
|
-
// if we import something from outside the /client folder,
|
|
10
|
-
// the tsc directory structure is affected
|
|
11
|
-
// import {DEFAULT_PLUGIN_ID} from '../../constants';
|
|
12
|
-
const DEFAULT_PLUGIN_ID = 'default';
|
|
8
|
+
import { DEFAULT_PLUGIN_ID } from './constants';
|
|
13
9
|
export default function useGlobalData() {
|
|
14
10
|
const { globalData } = useDocusaurusContext();
|
|
15
11
|
if (!globalData) {
|
|
@@ -4,7 +4,8 @@
|
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
import { useContext } from 'react';
|
|
8
|
+
import { Context } from './browserContext';
|
|
9
|
+
export default function useIsBrowser() {
|
|
10
|
+
return useContext(Context);
|
|
11
|
+
}
|
package/lib/client/flat.d.ts
CHANGED
|
@@ -4,5 +4,6 @@
|
|
|
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
|
-
|
|
7
|
+
import type { RouteChunksTree } from '@docusaurus/types';
|
|
8
|
+
declare function flat(target: RouteChunksTree): Record<string, string>;
|
|
8
9
|
export default flat;
|
package/lib/client/flat.js
CHANGED
|
@@ -4,22 +4,20 @@
|
|
|
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
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
|
+
const isTree = (x) => typeof x === 'object' && !!x && Object.keys(x).length > 0;
|
|
9
8
|
function flat(target) {
|
|
10
9
|
const delimiter = '.';
|
|
11
10
|
const output = {};
|
|
12
|
-
function step(object,
|
|
11
|
+
function step(object, prefix) {
|
|
13
12
|
Object.keys(object).forEach((key) => {
|
|
14
13
|
const value = object[key];
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
const newKey = prev ? prev + delimiter + key : key;
|
|
18
|
-
if (isObject && Object.keys(value).length) {
|
|
14
|
+
const newKey = prefix ? `${prefix}${delimiter}${key}` : key;
|
|
15
|
+
if (isTree(value)) {
|
|
19
16
|
step(value, newKey);
|
|
20
|
-
return;
|
|
21
17
|
}
|
|
22
|
-
|
|
18
|
+
else {
|
|
19
|
+
output[newKey] = value;
|
|
20
|
+
}
|
|
23
21
|
});
|
|
24
22
|
}
|
|
25
23
|
step(target);
|
|
@@ -4,8 +4,6 @@
|
|
|
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
|
-
pathname: string;
|
|
9
|
-
};
|
|
7
|
+
import type { Location } from '@docusaurus/history';
|
|
10
8
|
declare function normalizeLocation<T extends Location>(location: T): T;
|
|
11
9
|
export default normalizeLocation;
|
package/lib/client/prefetch.js
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
// @ts-check
|
|
9
|
+
|
|
8
10
|
import * as eta from 'eta';
|
|
9
11
|
import React from 'react';
|
|
10
12
|
import {StaticRouter} from 'react-router-dom';
|
|
@@ -18,23 +20,21 @@ import path from 'path';
|
|
|
18
20
|
import fs from 'fs-extra';
|
|
19
21
|
import routes from '@generated/routes';
|
|
20
22
|
import packageJson from '../../package.json';
|
|
21
|
-
// eslint-disable-next-line import/no-unresolved
|
|
22
23
|
import preload from './preload';
|
|
23
|
-
// eslint-disable-next-line import/no-unresolved
|
|
24
24
|
import App from './App';
|
|
25
25
|
import {
|
|
26
26
|
createStatefulLinksCollector,
|
|
27
27
|
ProvideLinksCollector,
|
|
28
28
|
} from './LinksCollector';
|
|
29
|
-
import
|
|
29
|
+
import logger from '@docusaurus/logger';
|
|
30
30
|
// eslint-disable-next-line no-restricted-imports
|
|
31
31
|
import {memoize} from 'lodash';
|
|
32
32
|
|
|
33
|
-
const getCompiledSSRTemplate = memoize((template) =>
|
|
34
|
-
|
|
33
|
+
const getCompiledSSRTemplate = memoize((template) =>
|
|
34
|
+
eta.compile(template.trim(), {
|
|
35
35
|
rmWhitespace: true,
|
|
36
|
-
})
|
|
37
|
-
|
|
36
|
+
}),
|
|
37
|
+
);
|
|
38
38
|
|
|
39
39
|
function renderSSRTemplate(ssrTemplate, data) {
|
|
40
40
|
const compiled = getCompiledSSRTemplate(ssrTemplate);
|
|
@@ -45,20 +45,16 @@ export default async function render(locals) {
|
|
|
45
45
|
try {
|
|
46
46
|
return await doRender(locals);
|
|
47
47
|
} catch (e) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
`Docusaurus Node/SSR could not render static page with path "${locals.path}" because of following error:\n\n${e.stack}\n`,
|
|
51
|
-
),
|
|
52
|
-
);
|
|
48
|
+
logger.error`Docusaurus Node/SSR could not render static page with path path=${locals.path} because of following error:
|
|
49
|
+
${e.stack}`;
|
|
53
50
|
|
|
54
|
-
const isNotDefinedErrorRegex =
|
|
51
|
+
const isNotDefinedErrorRegex =
|
|
52
|
+
/(window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i;
|
|
55
53
|
|
|
56
54
|
if (isNotDefinedErrorRegex.test(e.message)) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
),
|
|
61
|
-
);
|
|
55
|
+
logger.info`It looks like you are using code that should run on the client-side only.
|
|
56
|
+
To get around it, try using code=${'<BrowserOnly>'} (path=${'https://docusaurus.io/docs/docusaurus-core/#browseronly'}) or code=${'ExecutionEnvironment'} (path=${'https://docusaurus.io/docs/docusaurus-core/#executionenvironment'}).
|
|
57
|
+
It might also require to wrap your client code in code=${'useEffect'} hook and/or import a third-party library dynamically (if any).`;
|
|
62
58
|
}
|
|
63
59
|
|
|
64
60
|
throw new Error('Server-side rendering fails due to the error above.');
|
|
@@ -131,10 +127,10 @@ async function doRender(locals) {
|
|
|
131
127
|
version: packageJson.version,
|
|
132
128
|
});
|
|
133
129
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return minify(renderedHtml, {
|
|
137
|
-
removeComments:
|
|
130
|
+
try {
|
|
131
|
+
// Minify html with https://github.com/DanielRuf/html-minifier-terser
|
|
132
|
+
return await minify(renderedHtml, {
|
|
133
|
+
removeComments: false,
|
|
138
134
|
removeRedundantAttributes: true,
|
|
139
135
|
removeEmptyAttributes: true,
|
|
140
136
|
removeScriptTypeAttributes: true,
|
|
@@ -142,27 +138,9 @@ async function doRender(locals) {
|
|
|
142
138
|
useShortDoctype: true,
|
|
143
139
|
minifyJS: true,
|
|
144
140
|
});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// TODO this is a temporary error affecting only monorepos due to Terser 5 (async) being used by html-minifier-terser,
|
|
148
|
-
// instead of the expected Terser 4 (sync)
|
|
149
|
-
// TODO, remove this once we upgrade everything to Terser 5 (https://github.com/terser/html-minifier-terser/issues/46)
|
|
150
|
-
// See also
|
|
151
|
-
// - https://github.com/facebook/docusaurus/issues/3515
|
|
152
|
-
// - https://github.com/terser/html-minifier-terser/issues/49
|
|
153
|
-
try {
|
|
154
|
-
return doMinify();
|
|
155
141
|
} catch (e) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
e.message.includes("Cannot read property 'replace' of undefined")
|
|
159
|
-
) {
|
|
160
|
-
console.error(
|
|
161
|
-
chalk.red(
|
|
162
|
-
'\nDocusaurus user: you probably have this known error due to using a monorepo/workspace.\nWe have a workaround for you, please see https://github.com/facebook/docusaurus/issues/3515\n',
|
|
163
|
-
),
|
|
164
|
-
);
|
|
165
|
-
}
|
|
142
|
+
logger.error`Minification of page path=${locals.path} failed because of following error:
|
|
143
|
+
${e.stack}`;
|
|
166
144
|
throw e;
|
|
167
145
|
}
|
|
168
146
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
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
|
+
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import Layout from '@theme/Layout';
|
|
10
|
+
import ErrorBoundary from '@docusaurus/ErrorBoundary';
|
|
11
|
+
|
|
12
|
+
function ErrorDisplay({error, tryAgain}) {
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
style={{
|
|
16
|
+
display: 'flex',
|
|
17
|
+
flexDirection: 'column',
|
|
18
|
+
justifyContent: 'center',
|
|
19
|
+
alignItems: 'center',
|
|
20
|
+
height: '50vh',
|
|
21
|
+
width: '100%',
|
|
22
|
+
fontSize: '20px',
|
|
23
|
+
}}>
|
|
24
|
+
<h1>This page crashed.</h1>
|
|
25
|
+
<p>{error.message}</p>
|
|
26
|
+
<button type="button" onClick={tryAgain}>
|
|
27
|
+
Try again
|
|
28
|
+
</button>
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function Error({error, tryAgain}) {
|
|
34
|
+
// We wrap the error in its own error boundary because the layout can actually throw too...
|
|
35
|
+
// Only the ErrorDisplay component is simple enough to be considered safe to never throw
|
|
36
|
+
return (
|
|
37
|
+
<ErrorBoundary
|
|
38
|
+
// Note: we display the original error here, not the error that we captured in this extra error boundary
|
|
39
|
+
fallback={() => <ErrorDisplay error={error} tryAgain={tryAgain} />}>
|
|
40
|
+
<Layout title="Page Error">
|
|
41
|
+
<ErrorDisplay error={error} tryAgain={tryAgain} />
|
|
42
|
+
</Layout>
|
|
43
|
+
</ErrorBoundary>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default Error;
|
|
@@ -20,7 +20,7 @@ function Layout(props) {
|
|
|
20
20
|
<>
|
|
21
21
|
<Head defaultTitle={`${defaultTitle}${tagline ? ` · ${tagline}` : ''}`}>
|
|
22
22
|
{title && <title>{`${title} · ${tagline}`}</title>}
|
|
23
|
-
{favicon && <link rel="
|
|
23
|
+
{favicon && <link rel="icon" href={faviconUrl} />}
|
|
24
24
|
{description && <meta name="description" content={description} />}
|
|
25
25
|
{description && (
|
|
26
26
|
<meta property="og:description" content={description} />
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import React from 'react';
|
|
9
9
|
|
|
10
|
-
export default ({error, retry, pastDelay})
|
|
10
|
+
export default function Loading({error, retry, pastDelay}) {
|
|
11
11
|
if (error) {
|
|
12
12
|
return (
|
|
13
13
|
<div
|
|
@@ -133,4 +133,4 @@ export default ({error, retry, pastDelay}) => {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
return null;
|
|
136
|
-
}
|
|
136
|
+
}
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import React from 'react';
|
|
9
|
-
|
|
10
8
|
// Wrapper at the very top of the app, that is applied constantly
|
|
11
9
|
// and does not depend on current route (unlike the layout)
|
|
12
10
|
//
|
|
@@ -15,7 +13,7 @@ import React from 'react';
|
|
|
15
13
|
//
|
|
16
14
|
// See https://github.com/facebook/docusaurus/issues/3919
|
|
17
15
|
function Root({children}) {
|
|
18
|
-
return
|
|
16
|
+
return children;
|
|
19
17
|
}
|
|
20
18
|
|
|
21
19
|
export default Root;
|