@docusaurus/core 2.0.0-beta.15d451942 → 2.0.0-beta.18

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.
Files changed (200) hide show
  1. package/bin/beforeCli.mjs +133 -0
  2. package/bin/docusaurus.mjs +279 -0
  3. package/lib/babel/preset.d.ts +8 -3
  4. package/lib/babel/preset.js +8 -7
  5. package/lib/choosePort.js +31 -43
  6. package/lib/client/.eslintrc.js +0 -1
  7. package/lib/client/App.d.ts +1 -2
  8. package/lib/client/App.js +23 -24
  9. package/lib/client/LinksCollector.d.ts +3 -3
  10. package/lib/client/LinksCollector.js +7 -11
  11. package/lib/client/PendingNavigation.d.ts +24 -1
  12. package/lib/client/PendingNavigation.js +5 -7
  13. package/lib/{webpack/sharedModuleAliases.d.ts → client/SiteMetadataDefaults.d.ts} +2 -4
  14. package/lib/client/SiteMetadataDefaults.js +19 -0
  15. package/lib/client/baseUrlIssueBanner/BaseUrlIssueBanner.d.ts +13 -0
  16. package/lib/client/baseUrlIssueBanner/BaseUrlIssueBanner.js +15 -10
  17. package/lib/client/browserContext.d.ts +11 -0
  18. package/lib/client/browserContext.js +22 -0
  19. package/lib/client/client-lifecycles-dispatcher.d.ts +2 -5
  20. package/lib/client/client-lifecycles-dispatcher.js +6 -10
  21. package/lib/client/clientEntry.js +13 -7
  22. package/lib/client/docusaurus.d.ts +6 -0
  23. package/lib/client/docusaurus.js +16 -25
  24. package/lib/client/docusaurusContext.d.ts +12 -0
  25. package/lib/client/docusaurusContext.js +25 -0
  26. package/lib/client/exports/BrowserOnly.d.ts +2 -3
  27. package/lib/client/exports/BrowserOnly.js +14 -7
  28. package/lib/client/exports/ComponentCreator.d.ts +1 -2
  29. package/lib/client/exports/ComponentCreator.js +40 -19
  30. package/lib/client/exports/ErrorBoundary.d.ts +18 -0
  31. package/lib/client/exports/ErrorBoundary.js +35 -0
  32. package/lib/client/exports/Head.d.ts +2 -3
  33. package/lib/client/exports/Head.js +3 -4
  34. package/lib/client/exports/Interpolate.d.ts +2 -2
  35. package/lib/client/exports/Interpolate.js +20 -26
  36. package/lib/client/exports/Link.d.ts +11 -5
  37. package/lib/client/exports/Link.js +31 -20
  38. package/lib/client/exports/Translate.d.ts +1 -1
  39. package/lib/client/exports/Translate.js +14 -9
  40. package/lib/client/exports/constants.js +1 -11
  41. package/lib/client/exports/isInternalUrl.js +1 -1
  42. package/lib/client/exports/renderRoutes.d.ts +1 -2
  43. package/lib/client/exports/renderRoutes.js +1 -2
  44. package/lib/client/exports/router.d.ts +1 -1
  45. package/lib/client/exports/router.js +1 -1
  46. package/lib/client/exports/useBaseUrl.js +8 -5
  47. package/lib/client/exports/useDocusaurusContext.d.ts +2 -3
  48. package/lib/client/exports/useDocusaurusContext.js +3 -9
  49. package/lib/client/exports/useGlobalData.d.ts +4 -3
  50. package/lib/client/exports/useGlobalData.js +4 -8
  51. package/lib/{server/versions/__tests/index.test.d.ts → client/exports/useIsBrowser.d.ts} +1 -1
  52. package/lib/client/exports/useIsBrowser.js +11 -0
  53. package/lib/{server/loadSetup.d.ts → client/exports/useRouteContext.d.ts} +2 -3
  54. package/lib/client/exports/useRouteContext.js +15 -0
  55. package/lib/client/flat.d.ts +4 -2
  56. package/lib/client/flat.js +9 -13
  57. package/lib/client/normalizeLocation.d.ts +2 -5
  58. package/lib/client/normalizeLocation.js +2 -7
  59. package/lib/client/nprogress.css +2 -2
  60. package/lib/client/prefetch.d.ts +1 -2
  61. package/lib/client/prefetch.js +4 -6
  62. package/lib/client/preload.d.ts +3 -2
  63. package/lib/client/preload.js +5 -10
  64. package/lib/client/routeContext.d.ts +13 -0
  65. package/lib/client/routeContext.js +31 -0
  66. package/lib/client/serverEntry.d.ts +10 -0
  67. package/lib/client/serverEntry.js +90 -142
  68. package/lib/client/theme-fallback/Error/index.d.ts +10 -0
  69. package/lib/client/theme-fallback/Error/index.js +43 -0
  70. package/lib/client/theme-fallback/Layout/index.d.ts +10 -0
  71. package/lib/client/theme-fallback/Layout/index.js +2 -26
  72. package/lib/client/theme-fallback/Loading/index.d.ts +9 -0
  73. package/lib/client/theme-fallback/Loading/index.js +47 -115
  74. package/lib/client/{exports/context.js → theme-fallback/NotFound/index.d.ts} +2 -2
  75. package/lib/client/theme-fallback/NotFound/index.js +17 -18
  76. package/lib/client/theme-fallback/Root/index.d.ts +10 -0
  77. package/lib/client/theme-fallback/Root/index.js +2 -6
  78. package/lib/client/theme-fallback/SiteMetadata/index.d.ts +8 -0
  79. package/lib/client/theme-fallback/SiteMetadata/index.js +10 -0
  80. package/lib/commands/build.d.ts +1 -1
  81. package/lib/commands/build.js +50 -54
  82. package/lib/commands/clear.d.ts +6 -0
  83. package/lib/commands/clear.js +30 -19
  84. package/lib/commands/commandUtils.d.ts +7 -1
  85. package/lib/commands/commandUtils.js +7 -7
  86. package/lib/commands/deploy.d.ts +1 -1
  87. package/lib/commands/deploy.js +83 -66
  88. package/lib/commands/external.d.ts +2 -2
  89. package/lib/commands/external.js +4 -8
  90. package/lib/commands/serve.d.ts +1 -1
  91. package/lib/commands/serve.js +25 -12
  92. package/lib/commands/start.d.ts +1 -1
  93. package/lib/commands/start.js +96 -87
  94. package/lib/commands/swizzle/actions.d.ts +23 -0
  95. package/lib/commands/swizzle/actions.js +101 -0
  96. package/lib/commands/swizzle/common.d.ts +33 -0
  97. package/lib/commands/swizzle/common.js +56 -0
  98. package/lib/commands/swizzle/components.d.ts +29 -0
  99. package/lib/commands/swizzle/components.js +162 -0
  100. package/lib/commands/swizzle/config.d.ts +10 -0
  101. package/lib/commands/swizzle/config.js +80 -0
  102. package/lib/commands/swizzle/context.d.ts +8 -0
  103. package/lib/commands/swizzle/context.js +28 -0
  104. package/lib/commands/swizzle/index.d.ts +8 -0
  105. package/lib/commands/swizzle/index.js +115 -0
  106. package/lib/commands/swizzle/prompts.d.ts +12 -0
  107. package/lib/commands/swizzle/prompts.js +110 -0
  108. package/lib/{client/exports/context.d.ts → commands/swizzle/tables.d.ts} +3 -4
  109. package/lib/commands/swizzle/tables.js +113 -0
  110. package/lib/commands/swizzle/themes.d.ts +20 -0
  111. package/lib/commands/swizzle/themes.js +106 -0
  112. package/lib/commands/writeHeadingIds.d.ts +2 -6
  113. package/lib/commands/writeHeadingIds.js +19 -76
  114. package/lib/commands/writeTranslations.d.ts +2 -2
  115. package/lib/commands/writeTranslations.js +37 -17
  116. package/lib/index.d.ts +10 -9
  117. package/lib/index.js +20 -19
  118. package/lib/server/brokenLinks.d.ts +4 -17
  119. package/lib/server/brokenLinks.js +64 -52
  120. package/lib/server/client-modules/index.d.ts +2 -2
  121. package/lib/server/client-modules/index.js +4 -3
  122. package/lib/server/config.d.ts +2 -2
  123. package/lib/server/config.js +8 -5
  124. package/lib/server/configValidation.d.ts +4 -2
  125. package/lib/server/configValidation.js +93 -37
  126. package/lib/server/duplicateRoutes.d.ts +1 -3
  127. package/lib/server/duplicateRoutes.js +17 -13
  128. package/lib/server/html-tags/htmlTags.js +7 -8
  129. package/lib/server/html-tags/index.d.ts +2 -3
  130. package/lib/server/html-tags/index.js +3 -4
  131. package/lib/server/i18n.d.ts +2 -3
  132. package/lib/server/i18n.js +27 -48
  133. package/lib/server/index.d.ts +9 -2
  134. package/lib/server/index.js +175 -96
  135. package/lib/server/moduleShorthand.d.ts +9 -0
  136. package/lib/server/moduleShorthand.js +46 -0
  137. package/lib/server/plugins/applyRouteTrailingSlash.d.ts +9 -0
  138. package/lib/server/plugins/applyRouteTrailingSlash.js +19 -0
  139. package/lib/server/plugins/index.d.ts +4 -5
  140. package/lib/server/plugins/index.js +69 -45
  141. package/lib/server/plugins/init.d.ts +15 -5
  142. package/lib/server/plugins/init.js +68 -81
  143. package/lib/server/plugins/pluginIds.d.ts +2 -2
  144. package/lib/server/plugins/pluginIds.js +8 -5
  145. package/lib/server/presets/index.d.ts +3 -3
  146. package/lib/server/presets/index.js +16 -23
  147. package/lib/server/routes.d.ts +3 -5
  148. package/lib/server/routes.js +68 -36
  149. package/lib/server/themes/alias.d.ts +3 -2
  150. package/lib/server/themes/alias.js +24 -13
  151. package/lib/server/themes/index.d.ts +6 -2
  152. package/lib/server/themes/index.js +36 -24
  153. package/lib/server/translations/translations.d.ts +21 -17
  154. package/lib/server/translations/translations.js +33 -54
  155. package/lib/server/translations/translationsExtractor.d.ts +12 -5
  156. package/lib/server/translations/translationsExtractor.js +159 -121
  157. package/lib/server/utils.d.ts +9 -3
  158. package/lib/server/utils.js +7 -9
  159. package/lib/server/versions/index.d.ts +3 -4
  160. package/lib/server/versions/index.js +22 -24
  161. package/lib/webpack/base.d.ts +6 -4
  162. package/lib/webpack/base.js +51 -36
  163. package/lib/webpack/client.d.ts +3 -3
  164. package/lib/webpack/client.js +12 -19
  165. package/lib/webpack/plugins/ChunkAssetPlugin.d.ts +13 -3
  166. package/lib/webpack/plugins/ChunkAssetPlugin.js +24 -17
  167. package/lib/webpack/plugins/CleanWebpackPlugin.d.ts +6 -6
  168. package/lib/webpack/plugins/CleanWebpackPlugin.js +10 -16
  169. package/lib/webpack/plugins/LogPlugin.d.ts +1 -1
  170. package/lib/webpack/plugins/LogPlugin.js +4 -5
  171. package/lib/webpack/plugins/WaitPlugin.d.ts +1 -1
  172. package/lib/webpack/plugins/WaitPlugin.js +1 -1
  173. package/lib/webpack/server.d.ts +3 -3
  174. package/lib/webpack/server.js +14 -7
  175. package/lib/{client → webpack}/templates/index.html.template.ejs +0 -0
  176. package/lib/webpack/templates/ssr.html.template.d.ts +8 -0
  177. package/lib/{client → webpack}/templates/ssr.html.template.js +5 -4
  178. package/lib/webpack/utils.d.ts +15 -30
  179. package/lib/webpack/utils.js +57 -175
  180. package/package.json +77 -70
  181. package/bin/docusaurus.js +0 -326
  182. package/lib/.tsbuildinfo +0 -5732
  183. package/lib/client/.tsbuildinfo +0 -4171
  184. package/lib/commands/buildRemoteBranchUrl.d.ts +0 -7
  185. package/lib/commands/buildRemoteBranchUrl.js +0 -27
  186. package/lib/commands/swizzle.d.ts +0 -9
  187. package/lib/commands/swizzle.js +0 -245
  188. package/lib/constants.d.ts +0 -18
  189. package/lib/constants.js +0 -23
  190. package/lib/server/loadSetup.js +0 -25
  191. package/lib/server/versions/__fixtures__/dummy-plugin.js +0 -0
  192. package/lib/server/versions/__fixtures__/package.json +0 -3
  193. package/lib/server/versions/__tests/index.test.js +0 -25
  194. package/lib/webpack/react-dev-utils-webpack5/README.md +0 -11
  195. package/lib/webpack/react-dev-utils-webpack5/evalSourceMapMiddleware.js +0 -57
  196. package/lib/webpack/react-dev-utils-webpack5/formatWebpackMessages.js +0 -138
  197. package/lib/webpack/react-dev-utils-webpack5/webpackHotDevClient.js +0 -285
  198. package/lib/webpack/sharedModuleAliases.js +0 -18
  199. package/tsconfig.client.json +0 -13
  200. package/tsconfig.json +0 -13
@@ -30,9 +30,9 @@ function linkPrefetchStrategy(url) {
30
30
  link.setAttribute('href', url);
31
31
  link.onload = resolve;
32
32
  link.onerror = reject;
33
- const parentElement = document.getElementsByTagName('head')[0] ||
34
- document.getElementsByName('script')[0].parentNode;
35
- parentElement.appendChild(link);
33
+ const parentElement = document.getElementsByTagName('head')[0] ??
34
+ document.getElementsByName('script')[0]?.parentNode;
35
+ parentElement?.appendChild(link);
36
36
  });
37
37
  }
38
38
  function xhrPrefetchStrategy(url) {
@@ -55,7 +55,7 @@ const supportedPrefetchStrategy = support('prefetch')
55
55
  ? linkPrefetchStrategy
56
56
  : xhrPrefetchStrategy;
57
57
  const preFetched = {};
58
- function prefetch(url) {
58
+ export default function prefetch(url) {
59
59
  return new Promise((resolve) => {
60
60
  if (preFetched[url]) {
61
61
  resolve();
@@ -66,8 +66,6 @@ function prefetch(url) {
66
66
  resolve();
67
67
  preFetched[url] = true;
68
68
  })
69
- // eslint-disable-next-line @typescript-eslint/no-empty-function
70
69
  .catch(() => { }); // 404s are logged to the console anyway.
71
70
  });
72
71
  }
73
- export default prefetch;
@@ -4,10 +4,11 @@
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 { RouteConfig } from 'react-router-config';
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 screens.
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
@@ -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 screens.
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
@@ -15,13 +16,7 @@ import { matchRoutes } from 'react-router-config';
15
16
  */
16
17
  export default function preload(routes, pathname) {
17
18
  const matches = matchRoutes(routes, pathname);
18
- return Promise.all(matches.map((match) => {
19
- const { component } = match.route;
20
- // @ts-expect-error: ComponentCreator injected this method.
21
- if (component && component.preload) {
22
- // @ts-expect-error: checked above.
23
- return component.preload();
24
- }
25
- return undefined;
26
- }));
19
+ return Promise.all(
20
+ // @ts-expect-error: ComponentCreator injected this method.
21
+ matches.map((match) => match.route.component?.preload?.()));
27
22
  }
@@ -0,0 +1,13 @@
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, { type ReactNode } from 'react';
8
+ import type { PluginRouteContext, RouteContext } from '@docusaurus/types';
9
+ export declare const Context: React.Context<PluginRouteContext | null>;
10
+ export declare function RouteContextProvider({ children, value, }: {
11
+ children: ReactNode;
12
+ value: PluginRouteContext | RouteContext | null;
13
+ }): JSX.Element;
@@ -0,0 +1,31 @@
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, { useMemo } from 'react';
8
+ export const Context = React.createContext(null);
9
+ function mergeContexts({ parent, value, }) {
10
+ if (!parent) {
11
+ if (!value) {
12
+ throw new Error('Unexpected: no Docusaurus route context found');
13
+ }
14
+ else if (!('plugin' in value)) {
15
+ throw new Error('Unexpected: Docusaurus topmost route context has no `plugin` attribute');
16
+ }
17
+ return value;
18
+ }
19
+ // TODO deep merge this
20
+ const data = { ...parent.data, ...value?.data };
21
+ return {
22
+ // nested routes are not supposed to override plugin attribute
23
+ plugin: parent.plugin,
24
+ data,
25
+ };
26
+ }
27
+ export function RouteContextProvider({ children, value, }) {
28
+ const parent = React.useContext(Context);
29
+ const mergedValue = useMemo(() => mergeContexts({ parent, value }), [parent, value]);
30
+ return <Context.Provider value={mergedValue}>{children}</Context.Provider>;
31
+ }
@@ -0,0 +1,10 @@
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 type { Locals } from '@slorber/static-site-generator-webpack-plugin';
8
+ export default function render(locals: Locals & {
9
+ path: string;
10
+ }): Promise<string>;
@@ -4,165 +4,113 @@
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 * as eta from 'eta';
9
8
  import React from 'react';
10
- import {StaticRouter} from 'react-router-dom';
9
+ import { StaticRouter } from 'react-router-dom';
11
10
  import ReactDOMServer from 'react-dom/server';
12
- import {Helmet} from 'react-helmet';
13
- import {getBundles} from 'react-loadable-ssr-addon-v5-slorber';
11
+ import { HelmetProvider } from 'react-helmet-async';
12
+ import { getBundles } from 'react-loadable-ssr-addon-v5-slorber';
14
13
  import Loadable from 'react-loadable';
15
-
16
- import {minify} from 'html-minifier-terser';
14
+ import { minify } from 'html-minifier-terser';
17
15
  import path from 'path';
18
16
  import fs from 'fs-extra';
19
17
  import routes from '@generated/routes';
20
- import packageJson from '../../package.json';
21
- // eslint-disable-next-line import/no-unresolved
22
18
  import preload from './preload';
23
- // eslint-disable-next-line import/no-unresolved
24
19
  import App from './App';
25
- import {
26
- createStatefulLinksCollector,
27
- ProvideLinksCollector,
28
- } from './LinksCollector';
29
- import chalk from 'chalk';
20
+ import { createStatefulLinksCollector, LinksCollectorProvider, } from './LinksCollector';
21
+ import logger from '@docusaurus/logger';
30
22
  // eslint-disable-next-line no-restricted-imports
31
- import {memoize} from 'lodash';
32
-
33
- const getCompiledSSRTemplate = memoize((template) => {
34
- return eta.compile(template.trim(), {
23
+ import _ from 'lodash';
24
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
25
+ const packageJson = require('../../package.json');
26
+ const getCompiledSSRTemplate = _.memoize((template) => eta.compile(template.trim(), {
35
27
  rmWhitespace: true,
36
- });
37
- });
38
-
28
+ }));
39
29
  function renderSSRTemplate(ssrTemplate, data) {
40
- const compiled = getCompiledSSRTemplate(ssrTemplate);
41
- return compiled(data, eta.defaultConfig);
30
+ const compiled = getCompiledSSRTemplate(ssrTemplate);
31
+ return compiled(data, eta.defaultConfig);
42
32
  }
43
-
44
33
  export default async function render(locals) {
45
- try {
46
- return await doRender(locals);
47
- } catch (e) {
48
- console.error(
49
- chalk.red(
50
- `Docusaurus Node/SSR could not render static page with path "${locals.path}" because of following error:\n\n${e.stack}\n`,
51
- ),
52
- );
53
-
54
- const isNotDefinedErrorRegex = /(window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i;
55
-
56
- if (isNotDefinedErrorRegex.test(e.message)) {
57
- console.error(
58
- chalk.green(
59
- 'Pro tip: It looks like you are using code that should run on the client-side only.\nTo get around it, try using <BrowserOnly> (https://docusaurus.io/docs/docusaurus-core/#browseronly) or ExecutionEnvironment (https://docusaurus.io/docs/docusaurus-core/#executionenvironment).\nIt might also require to wrap your client code in useEffect hook and/or import a third-party library dynamically (if any).',
60
- ),
61
- );
34
+ try {
35
+ return await doRender(locals);
36
+ }
37
+ catch (err) {
38
+ logger.error `Docusaurus server-side rendering could not render static page with path path=${locals.path}.`;
39
+ const isNotDefinedErrorRegex = /(?:window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i;
40
+ if (isNotDefinedErrorRegex.test(err.message)) {
41
+ logger.info `It looks like you are using code that should run on the client-side only.
42
+ 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'}).
43
+ It might also require to wrap your client code in code=${'useEffect'} hook and/or import a third-party library dynamically (if any).`;
44
+ }
45
+ throw err;
62
46
  }
63
-
64
- throw new Error('Server-side rendering fails due to the error above.');
65
- }
66
47
  }
67
-
68
- // Renderer for static-site-generator-webpack-plugin (async rendering via promises).
48
+ // Renderer for static-site-generator-webpack-plugin (async rendering).
69
49
  async function doRender(locals) {
70
- const {
71
- routesLocation,
72
- headTags,
73
- preBodyTags,
74
- postBodyTags,
75
- onLinksCollected,
76
- baseUrl,
77
- ssrTemplate,
78
- noIndex,
79
- } = locals;
80
- const location = routesLocation[locals.path];
81
- await preload(routes, location);
82
- const modules = new Set();
83
- const context = {};
84
-
85
- const linksCollector = createStatefulLinksCollector();
86
- const appHtml = ReactDOMServer.renderToString(
87
- <Loadable.Capture report={(moduleName) => modules.add(moduleName)}>
88
- <StaticRouter location={location} context={context}>
89
- <ProvideLinksCollector linksCollector={linksCollector}>
90
- <App />
91
- </ProvideLinksCollector>
92
- </StaticRouter>
93
- </Loadable.Capture>,
94
- );
95
- onLinksCollected(location, linksCollector.getCollectedLinks());
96
-
97
- const helmet = Helmet.renderStatic();
98
- const htmlAttributes = helmet.htmlAttributes.toString();
99
- const bodyAttributes = helmet.bodyAttributes.toString();
100
- const metaStrings = [
101
- helmet.title.toString(),
102
- helmet.meta.toString(),
103
- helmet.link.toString(),
104
- helmet.script.toString(),
105
- ];
106
- const metaAttributes = metaStrings.filter(Boolean);
107
-
108
- const {generatedFilesDir} = locals;
109
- const manifestPath = path.join(generatedFilesDir, 'client-manifest.json');
110
- const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));
111
-
112
- // Get all required assets for this particular page based on client
113
- // manifest information.
114
- const modulesToBeLoaded = [...manifest.entrypoints, ...Array.from(modules)];
115
- const bundles = getBundles(manifest, modulesToBeLoaded);
116
- const stylesheets = (bundles.css || []).map((b) => b.file);
117
- const scripts = (bundles.js || []).map((b) => b.file);
118
-
119
- const renderedHtml = renderSSRTemplate(ssrTemplate, {
120
- appHtml,
121
- baseUrl,
122
- htmlAttributes: htmlAttributes || '',
123
- bodyAttributes: bodyAttributes || '',
124
- headTags,
125
- preBodyTags,
126
- postBodyTags,
127
- metaAttributes,
128
- scripts,
129
- stylesheets,
130
- noIndex,
131
- version: packageJson.version,
132
- });
133
-
134
- // Minify html with https://github.com/DanielRuf/html-minifier-terser
135
- function doMinify() {
136
- return minify(renderedHtml, {
137
- removeComments: true,
138
- removeRedundantAttributes: true,
139
- removeEmptyAttributes: true,
140
- removeScriptTypeAttributes: true,
141
- removeStyleLinkTypeAttributes: true,
142
- useShortDoctype: true,
143
- minifyJS: true,
50
+ const { routesLocation, headTags, preBodyTags, postBodyTags, onLinksCollected, baseUrl, ssrTemplate, noIndex, } = locals;
51
+ const location = routesLocation[locals.path];
52
+ await preload(routes, location);
53
+ const modules = new Set();
54
+ const context = {};
55
+ const helmetContext = {};
56
+ const linksCollector = createStatefulLinksCollector();
57
+ const appHtml = ReactDOMServer.renderToString(<Loadable.Capture report={(moduleName) => modules.add(moduleName)}>
58
+ <HelmetProvider context={helmetContext}>
59
+ <StaticRouter location={location} context={context}>
60
+ <LinksCollectorProvider linksCollector={linksCollector}>
61
+ <App />
62
+ </LinksCollectorProvider>
63
+ </StaticRouter>
64
+ </HelmetProvider>
65
+ </Loadable.Capture>);
66
+ onLinksCollected(location, linksCollector.getCollectedLinks());
67
+ const { helmet } = helmetContext;
68
+ const htmlAttributes = helmet.htmlAttributes.toString();
69
+ const bodyAttributes = helmet.bodyAttributes.toString();
70
+ const metaStrings = [
71
+ helmet.title.toString(),
72
+ helmet.meta.toString(),
73
+ helmet.link.toString(),
74
+ helmet.script.toString(),
75
+ ];
76
+ const metaAttributes = metaStrings.filter(Boolean);
77
+ const { generatedFilesDir } = locals;
78
+ const manifestPath = path.join(generatedFilesDir, 'client-manifest.json');
79
+ const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));
80
+ // Get all required assets for this particular page based on client
81
+ // manifest information.
82
+ const modulesToBeLoaded = [...manifest.entrypoints, ...Array.from(modules)];
83
+ const bundles = getBundles(manifest, modulesToBeLoaded);
84
+ const stylesheets = (bundles.css ?? []).map((b) => b.file);
85
+ const scripts = (bundles.js ?? []).map((b) => b.file);
86
+ const renderedHtml = renderSSRTemplate(ssrTemplate, {
87
+ appHtml,
88
+ baseUrl,
89
+ htmlAttributes,
90
+ bodyAttributes,
91
+ headTags,
92
+ preBodyTags,
93
+ postBodyTags,
94
+ metaAttributes,
95
+ scripts,
96
+ stylesheets,
97
+ noIndex,
98
+ version: packageJson.version,
144
99
  });
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
- } catch (e) {
156
- if (
157
- e.message &&
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, check https://github.com/facebook/docusaurus/issues/3515\n',
163
- ),
164
- );
100
+ try {
101
+ // Minify html with https://github.com/DanielRuf/html-minifier-terser
102
+ return await minify(renderedHtml, {
103
+ removeComments: false,
104
+ removeRedundantAttributes: true,
105
+ removeEmptyAttributes: true,
106
+ removeScriptTypeAttributes: true,
107
+ removeStyleLinkTypeAttributes: true,
108
+ useShortDoctype: true,
109
+ minifyJS: true,
110
+ });
111
+ }
112
+ catch (err) {
113
+ logger.error `Minification of page path=${locals.path} failed.`;
114
+ throw err;
165
115
  }
166
- throw e;
167
- }
168
116
  }
@@ -0,0 +1,10 @@
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
+ export default function Error({ error, tryAgain }: Props): JSX.Element;
@@ -0,0 +1,43 @@
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 Layout from '@theme/Layout';
9
+ import ErrorBoundary from '@docusaurus/ErrorBoundary';
10
+ import Head from '@docusaurus/Head';
11
+ function ErrorDisplay({ error, tryAgain }) {
12
+ return (<div style={{
13
+ display: 'flex',
14
+ flexDirection: 'column',
15
+ justifyContent: 'center',
16
+ alignItems: 'center',
17
+ height: '50vh',
18
+ width: '100%',
19
+ fontSize: '20px',
20
+ }}>
21
+ <h1>This page crashed.</h1>
22
+ <p>{error.message}</p>
23
+ <button type="button" onClick={tryAgain}>
24
+ Try again
25
+ </button>
26
+ </div>);
27
+ }
28
+ export default function Error({ error, tryAgain }) {
29
+ // We wrap the error in its own error boundary because the layout can actually
30
+ // throw too... Only the ErrorDisplay component is simple enough to be
31
+ // considered safe to never throw
32
+ return (<ErrorBoundary
33
+ // Note: we display the original error here, not the error that we
34
+ // captured in this extra error boundary
35
+ fallback={() => <ErrorDisplay error={error} tryAgain={tryAgain}/>}>
36
+ <Head>
37
+ <title>Page Error</title>
38
+ </Head>
39
+ <Layout>
40
+ <ErrorDisplay error={error} tryAgain={tryAgain}/>
41
+ </Layout>
42
+ </ErrorBoundary>);
43
+ }
@@ -0,0 +1,10 @@
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
+ export default function Layout({ children }: Props): JSX.Element;
@@ -4,31 +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
-
8
7
  import React from 'react';
9
- import Head from '@docusaurus/Head';
10
- import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
11
- import useBaseUrl from '@docusaurus/useBaseUrl';
12
-
13
- function Layout(props) {
14
- const context = useDocusaurusContext();
15
- const {siteConfig = {}} = context;
16
- const {favicon, tagline = '', title: defaultTitle} = siteConfig;
17
- const {children, title, description} = props;
18
- const faviconUrl = useBaseUrl(favicon);
19
- return (
20
- <>
21
- <Head defaultTitle={`${defaultTitle}${tagline ? ` · ${tagline}` : ''}`}>
22
- {title && <title>{`${title} · ${tagline}`}</title>}
23
- {favicon && <link rel="shortcut icon" href={faviconUrl} />}
24
- {description && <meta name="description" content={description} />}
25
- {description && (
26
- <meta property="og:description" content={description} />
27
- )}
28
- </Head>
29
- {children}
30
- </>
31
- );
8
+ export default function Layout({ children }) {
9
+ return <>{children}</>;
32
10
  }
33
-
34
- 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;