@docusaurus/core 2.0.0-beta.18 → 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.
Files changed (130) hide show
  1. package/bin/beforeCli.mjs +12 -7
  2. package/bin/docusaurus.mjs +21 -72
  3. package/lib/client/.eslintrc.js +2 -3
  4. package/lib/client/App.d.ts +1 -1
  5. package/lib/client/App.js +9 -5
  6. package/lib/client/{baseUrlIssueBanner/BaseUrlIssueBanner.d.ts → BaseUrlIssueBanner/index.d.ts} +10 -5
  7. package/lib/client/{baseUrlIssueBanner/BaseUrlIssueBanner.js → BaseUrlIssueBanner/index.js} +14 -9
  8. package/lib/client/{baseUrlIssueBanner → BaseUrlIssueBanner}/styles.module.css +0 -0
  9. package/lib/client/ClientLifecyclesDispatcher.d.ts +16 -0
  10. package/lib/client/ClientLifecyclesDispatcher.js +34 -0
  11. package/lib/client/LinksCollector.js +1 -2
  12. package/lib/client/PendingNavigation.d.ts +8 -17
  13. package/lib/client/PendingNavigation.js +39 -70
  14. package/lib/client/clientEntry.js +1 -2
  15. package/lib/client/docusaurus.d.ts +5 -5
  16. package/lib/client/docusaurus.js +25 -29
  17. package/lib/client/exports/BrowserOnly.d.ts +3 -4
  18. package/lib/client/exports/BrowserOnly.js +1 -1
  19. package/lib/client/exports/ComponentCreator.js +51 -46
  20. package/lib/client/exports/ErrorBoundary.d.ts +2 -2
  21. package/lib/client/exports/Interpolate.js +16 -39
  22. package/lib/client/exports/Link.d.ts +3 -15
  23. package/lib/client/exports/Link.js +21 -26
  24. package/lib/client/exports/useBaseUrl.js +3 -9
  25. package/lib/client/exports/useGlobalData.d.ts +3 -3
  26. package/lib/client/exports/useGlobalData.js +5 -5
  27. package/lib/client/flat.d.ts +10 -2
  28. package/lib/client/flat.js +11 -3
  29. package/lib/client/normalizeLocation.js +14 -5
  30. package/lib/client/prefetch.js +7 -25
  31. package/lib/client/preload.d.ts +1 -3
  32. package/lib/client/preload.js +2 -2
  33. package/lib/client/routeContext.js +1 -1
  34. package/lib/client/serverEntry.js +12 -11
  35. package/lib/client/theme-fallback/Error/index.js +2 -0
  36. package/lib/client/theme-fallback/Loading/index.js +2 -0
  37. package/lib/client/theme-fallback/NotFound/index.js +2 -0
  38. package/lib/commands/build.d.ts +6 -2
  39. package/lib/commands/build.js +35 -15
  40. package/lib/commands/clear.d.ts +1 -1
  41. package/lib/commands/clear.js +3 -2
  42. package/lib/commands/deploy.d.ts +5 -2
  43. package/lib/commands/deploy.js +12 -9
  44. package/lib/commands/external.d.ts +1 -1
  45. package/lib/commands/external.js +5 -6
  46. package/lib/commands/serve.d.ts +7 -2
  47. package/lib/commands/serve.js +12 -12
  48. package/lib/commands/start.d.ts +8 -2
  49. package/lib/commands/start.js +14 -9
  50. package/lib/commands/swizzle/actions.d.ts +2 -2
  51. package/lib/commands/swizzle/actions.js +5 -4
  52. package/lib/commands/swizzle/common.d.ts +3 -3
  53. package/lib/commands/swizzle/components.js +41 -3
  54. package/lib/commands/swizzle/config.js +14 -11
  55. package/lib/commands/swizzle/context.js +6 -10
  56. package/lib/commands/swizzle/index.d.ts +2 -2
  57. package/lib/commands/swizzle/index.js +4 -3
  58. package/lib/commands/writeHeadingIds.d.ts +1 -1
  59. package/lib/commands/writeHeadingIds.js +5 -8
  60. package/lib/commands/writeTranslations.d.ts +3 -4
  61. package/lib/commands/writeTranslations.js +7 -9
  62. package/lib/index.d.ts +9 -10
  63. package/lib/index.js +18 -19
  64. package/lib/server/brokenLinks.js +1 -2
  65. package/lib/server/{client-modules/index.d.ts → clientModules.d.ts} +5 -1
  66. package/lib/server/{client-modules/index.js → clientModules.js} +6 -1
  67. package/lib/server/config.d.ts +5 -2
  68. package/lib/server/config.js +11 -6
  69. package/lib/server/configValidation.js +6 -5
  70. package/lib/server/getHostPort.d.ts +14 -0
  71. package/lib/{choosePort.js → server/getHostPort.js} +21 -35
  72. package/lib/server/htmlTags.d.ts +12 -0
  73. package/lib/server/htmlTags.js +62 -0
  74. package/lib/server/i18n.d.ts +2 -11
  75. package/lib/server/i18n.js +4 -19
  76. package/lib/server/index.d.ts +28 -13
  77. package/lib/server/index.js +42 -210
  78. package/lib/server/plugins/configs.d.ts +51 -0
  79. package/lib/server/plugins/configs.js +101 -0
  80. package/lib/server/plugins/index.d.ts +8 -7
  81. package/lib/server/plugins/index.js +59 -134
  82. package/lib/server/plugins/init.d.ts +6 -19
  83. package/lib/server/plugins/init.js +16 -68
  84. package/lib/server/{moduleShorthand.d.ts → plugins/moduleShorthand.d.ts} +0 -0
  85. package/lib/server/{moduleShorthand.js → plugins/moduleShorthand.js} +0 -0
  86. package/lib/server/plugins/pluginIds.d.ts +4 -0
  87. package/lib/server/plugins/pluginIds.js +4 -2
  88. package/lib/server/plugins/presets.d.ts +12 -0
  89. package/lib/server/{presets/index.js → plugins/presets.js} +14 -6
  90. package/lib/server/plugins/{applyRouteTrailingSlash.d.ts → routeConfig.d.ts} +3 -1
  91. package/lib/server/plugins/routeConfig.js +54 -0
  92. package/lib/server/plugins/synthetic.d.ts +20 -0
  93. package/lib/server/plugins/synthetic.js +112 -0
  94. package/lib/server/routes.d.ts +42 -8
  95. package/lib/server/routes.js +150 -92
  96. package/lib/server/{versions/index.d.ts → siteMetadata.d.ts} +5 -2
  97. package/lib/server/{versions/index.js → siteMetadata.js} +36 -3
  98. package/lib/server/translations/translations.d.ts +5 -13
  99. package/lib/server/translations/translations.js +5 -8
  100. package/lib/server/translations/translationsExtractor.d.ts +2 -4
  101. package/lib/webpack/aliases/index.d.ts +34 -0
  102. package/lib/webpack/aliases/index.js +106 -0
  103. package/lib/webpack/base.d.ts +0 -3
  104. package/lib/webpack/base.js +8 -25
  105. package/lib/webpack/client.js +1 -1
  106. package/lib/webpack/plugins/CleanWebpackPlugin.d.ts +2 -2
  107. package/lib/webpack/plugins/WaitPlugin.d.ts +2 -2
  108. package/lib/webpack/server.d.ts +2 -2
  109. package/lib/webpack/server.js +5 -3
  110. package/lib/webpack/utils.d.ts +3 -3
  111. package/lib/webpack/utils.js +3 -3
  112. package/package.json +33 -36
  113. package/lib/choosePort.d.ts +0 -11
  114. package/lib/client/client-lifecycles-dispatcher.d.ts +0 -9
  115. package/lib/client/client-lifecycles-dispatcher.js +0 -23
  116. package/lib/client/nprogress.css +0 -36
  117. package/lib/commands/commandUtils.d.ts +0 -9
  118. package/lib/commands/commandUtils.js +0 -21
  119. package/lib/server/duplicateRoutes.d.ts +0 -8
  120. package/lib/server/duplicateRoutes.js +0 -42
  121. package/lib/server/html-tags/htmlTags.d.ts +0 -7
  122. package/lib/server/html-tags/htmlTags.js +0 -38
  123. package/lib/server/html-tags/index.d.ts +0 -8
  124. package/lib/server/html-tags/index.js +0 -42
  125. package/lib/server/plugins/applyRouteTrailingSlash.js +0 -19
  126. package/lib/server/presets/index.d.ts +0 -11
  127. package/lib/server/themes/alias.d.ts +0 -9
  128. package/lib/server/themes/alias.js +0 -50
  129. package/lib/server/themes/index.d.ts +0 -12
  130. package/lib/server/themes/index.js +0 -47
@@ -6,50 +6,27 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getHostPort = void 0;
9
10
  const tslib_1 = require("tslib");
10
- /**
11
- * This feature was heavily inspired by create-react-app and
12
- * uses many of the same utility functions to implement it.
13
- */
14
11
  const child_process_1 = require("child_process");
15
12
  const detect_port_1 = tslib_1.__importDefault(require("detect-port"));
16
- const is_root_1 = tslib_1.__importDefault(require("is-root"));
17
13
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
14
+ const utils_1 = require("@docusaurus/utils");
18
15
  const prompts_1 = tslib_1.__importDefault(require("prompts"));
19
- const isInteractive = process.stdout.isTTY;
20
16
  const execOptions = {
21
17
  encoding: 'utf8',
22
- stdio: [
23
- 'pipe',
24
- 'pipe',
25
- 'ignore',
26
- ],
18
+ stdio: [/* stdin */ 'pipe', /* stdout */ 'pipe', /* stderr */ 'ignore'],
27
19
  };
28
- // Clears console
29
20
  function clearConsole() {
30
21
  process.stdout.write(process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H');
31
22
  }
32
- // Gets process id of what is on port
33
- function getProcessIdOnPort(port) {
34
- return (0, child_process_1.execSync)(`lsof -i:${port} -P -t -sTCP:LISTEN`, execOptions)
35
- .split('\n')[0]
36
- .trim();
37
- }
38
- // Gets process command
39
- function getProcessCommand(processId) {
40
- const command = (0, child_process_1.execSync)(`ps -o command -p ${processId} | sed -n 2p`, execOptions);
41
- return command.replace(/\n$/, '');
42
- }
43
- // Gets directory of a process from its process id
44
- function getDirectoryOfProcessById(processId) {
45
- return (0, child_process_1.execSync)(`lsof -p ${processId} | awk '$4=="cwd" {for (i=9; i<=NF; i++) printf "%s ", $i}'`, execOptions).trim();
46
- }
47
- // Gets process on port
48
23
  function getProcessForPort(port) {
49
24
  try {
50
- const processId = getProcessIdOnPort(port);
51
- const directory = getDirectoryOfProcessById(processId);
52
- const command = getProcessCommand(processId);
25
+ const processId = (0, child_process_1.execSync)(`lsof -i:${port} -P -t -sTCP:LISTEN`, execOptions)
26
+ .split('\n')[0]
27
+ .trim();
28
+ const directory = (0, child_process_1.execSync)(`lsof -p ${processId} | awk '$4=="cwd" {for (i=9; i<=NF; i++) printf "%s ", $i}'`, execOptions).trim();
29
+ const command = (0, child_process_1.execSync)(`ps -o command -p ${processId} | sed -n 2p`, execOptions).replace(/\n$/, '');
53
30
  return logger_1.default.interpolate `code=${command} subdue=${`(pid ${processId})`} in path=${directory}`;
54
31
  }
55
32
  catch {
@@ -57,8 +34,9 @@ function getProcessForPort(port) {
57
34
  }
58
35
  }
59
36
  /**
60
- * Detects if program is running on port and prompts user
61
- * to choose another if port is already being used
37
+ * Detects if program is running on port, and prompts user to choose another if
38
+ * port is already being used. This feature was heavily inspired by
39
+ * create-react-app and uses many of the same utility functions to implement it.
62
40
  */
63
41
  async function choosePort(host, defaultPort) {
64
42
  try {
@@ -66,7 +44,9 @@ async function choosePort(host, defaultPort) {
66
44
  if (port === defaultPort) {
67
45
  return port;
68
46
  }
69
- const message = process.platform !== 'win32' && defaultPort < 1024 && !(0, is_root_1.default)()
47
+ const isRoot = process.getuid?.() === 0;
48
+ const isInteractive = process.stdout.isTTY;
49
+ const message = process.platform !== 'win32' && defaultPort < 1024 && !isRoot
70
50
  ? `Admin permissions are required to run a server on a port below 1024.`
71
51
  : `Something is already running on port ${defaultPort}.`;
72
52
  if (!isInteractive) {
@@ -90,4 +70,10 @@ Would you like to run the app on another port instead?`),
90
70
  throw err;
91
71
  }
92
72
  }
93
- exports.default = choosePort;
73
+ async function getHostPort(options) {
74
+ const host = options.host ?? 'localhost';
75
+ const basePort = options.port ? parseInt(options.port, 10) : utils_1.DEFAULT_PORT;
76
+ const port = await choosePort(host, basePort);
77
+ return { host, port };
78
+ }
79
+ exports.getHostPort = getHostPort;
@@ -0,0 +1,12 @@
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 { Props, LoadedPlugin } from '@docusaurus/types';
8
+ /**
9
+ * Runs the `injectHtmlTags` lifecycle, and aggregates all plugins' tags into
10
+ * directly render-able HTML markup.
11
+ */
12
+ export declare function loadHtmlTags(plugins: LoadedPlugin[]): Pick<Props, 'headTags' | 'preBodyTags' | 'postBodyTags'>;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Facebook, Inc. and its affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.loadHtmlTags = void 0;
10
+ const tslib_1 = require("tslib");
11
+ const html_tags_1 = tslib_1.__importDefault(require("html-tags"));
12
+ const void_1 = tslib_1.__importDefault(require("html-tags/void"));
13
+ const escape_html_1 = tslib_1.__importDefault(require("escape-html"));
14
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
15
+ function assertIsHtmlTagObject(val) {
16
+ if (typeof val !== 'object' || !val) {
17
+ throw new Error(`"${val}" is not a valid HTML tag object.`);
18
+ }
19
+ if (typeof val.tagName !== 'string') {
20
+ throw new Error(`${JSON.stringify(val)} is not a valid HTML tag object. "tagName" must be defined as a string.`);
21
+ }
22
+ if (!html_tags_1.default.includes(val.tagName)) {
23
+ throw new Error(`Error loading ${JSON.stringify(val)}, "${val.tagName}" is not a valid HTML tag.`);
24
+ }
25
+ }
26
+ function htmlTagObjectToString(tag) {
27
+ assertIsHtmlTagObject(tag);
28
+ const isVoidTag = void_1.default.includes(tag.tagName);
29
+ const tagAttributes = tag.attributes ?? {};
30
+ const attributes = Object.keys(tagAttributes)
31
+ .map((attr) => {
32
+ const value = tagAttributes[attr];
33
+ if (typeof value === 'boolean') {
34
+ return value ? attr : undefined;
35
+ }
36
+ return `${attr}="${(0, escape_html_1.default)(value)}"`;
37
+ })
38
+ .filter((str) => Boolean(str));
39
+ const openingTag = `<${[tag.tagName].concat(attributes).join(' ')}>`;
40
+ const innerHTML = (!isVoidTag && tag.innerHTML) || '';
41
+ const closingTag = isVoidTag ? '' : `</${tag.tagName}>`;
42
+ return openingTag + innerHTML + closingTag;
43
+ }
44
+ function createHtmlTagsString(tags) {
45
+ return (Array.isArray(tags) ? tags : [tags])
46
+ .filter(Boolean)
47
+ .map((val) => (typeof val === 'string' ? val : htmlTagObjectToString(val)))
48
+ .join('\n');
49
+ }
50
+ /**
51
+ * Runs the `injectHtmlTags` lifecycle, and aggregates all plugins' tags into
52
+ * directly render-able HTML markup.
53
+ */
54
+ function loadHtmlTags(plugins) {
55
+ const pluginHtmlTags = plugins.map((plugin) => plugin.injectHtmlTags?.({ content: plugin.content }) ?? {});
56
+ const tagTypes = ['headTags', 'preBodyTags', 'postBodyTags'];
57
+ return Object.fromEntries(lodash_1.default.zip(tagTypes, tagTypes.map((type) => pluginHtmlTags
58
+ .map((tags) => createHtmlTagsString(tags[type]))
59
+ .join('\n')
60
+ .trim())));
61
+ }
62
+ exports.loadHtmlTags = loadHtmlTags;
@@ -5,15 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { I18n, DocusaurusConfig, I18nLocaleConfig } from '@docusaurus/types';
8
+ import type { LoadContextOptions } from './index';
8
9
  export declare function getDefaultLocaleConfig(locale: string): I18nLocaleConfig;
9
- export declare function loadI18n(config: DocusaurusConfig, options: {
10
- locale?: string;
11
- }): Promise<I18n>;
12
- export declare function localizePath({ pathType, path: originalPath, i18n, options, }: {
13
- pathType: 'fs' | 'url';
14
- path: string;
15
- i18n: I18n;
16
- options?: {
17
- localizePath?: boolean;
18
- };
19
- }): string;
10
+ export declare function loadI18n(config: DocusaurusConfig, options: Pick<LoadContextOptions, 'locale'>): Promise<I18n>;
@@ -6,10 +6,8 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.localizePath = exports.loadI18n = exports.getDefaultLocaleConfig = void 0;
9
+ exports.loadI18n = exports.getDefaultLocaleConfig = void 0;
10
10
  const tslib_1 = require("tslib");
11
- const path_1 = tslib_1.__importDefault(require("path"));
12
- const utils_1 = require("@docusaurus/utils");
13
11
  const rtl_detect_1 = require("rtl-detect");
14
12
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
15
13
  function getDefaultLocaleLabel(locale) {
@@ -21,6 +19,8 @@ function getDefaultLocaleConfig(locale) {
21
19
  label: getDefaultLocaleLabel(locale),
22
20
  direction: (0, rtl_detect_1.getLangDir)(locale),
23
21
  htmlLang: locale,
22
+ // If the locale name includes -u-ca-xxx the calendar will be defined
23
+ calendar: new Intl.Locale(locale).calendar ?? 'gregory',
24
24
  };
25
25
  }
26
26
  exports.getDefaultLocaleConfig = getDefaultLocaleConfig;
@@ -40,7 +40,7 @@ Note: Docusaurus only support running one locale at a time.`;
40
40
  ...i18nConfig.localeConfigs[locale],
41
41
  };
42
42
  }
43
- const localeConfigs = locales.reduce((acc, locale) => ({ ...acc, [locale]: getLocaleConfig(locale) }), {});
43
+ const localeConfigs = Object.fromEntries(locales.map((locale) => [locale, getLocaleConfig(locale)]));
44
44
  return {
45
45
  defaultLocale: i18nConfig.defaultLocale,
46
46
  locales,
@@ -49,18 +49,3 @@ Note: Docusaurus only support running one locale at a time.`;
49
49
  };
50
50
  }
51
51
  exports.loadI18n = loadI18n;
52
- function localizePath({ pathType, path: originalPath, i18n, options = {}, }) {
53
- const shouldLocalizePath =
54
- // By default, we don't localize the path of defaultLocale
55
- options.localizePath ?? i18n.currentLocale !== i18n.defaultLocale;
56
- if (!shouldLocalizePath) {
57
- return originalPath;
58
- }
59
- // FS paths need special care, for Windows support
60
- if (pathType === 'fs') {
61
- return path_1.default.join(originalPath, i18n.currentLocale);
62
- }
63
- // Url paths; add a trailing slash so it's a valid base URL
64
- return (0, utils_1.normalizeUrl)([originalPath, i18n.currentLocale, '/']);
65
- }
66
- exports.localizePath = localizePath;
@@ -4,20 +4,35 @@
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 type { DocusaurusConfig, LoadContext, PluginConfig, Props } from '@docusaurus/types';
7
+ import type { LoadContext, Props } from '@docusaurus/types';
8
8
  export declare type LoadContextOptions = {
9
- customOutDir?: string;
10
- customConfigFilePath?: string;
9
+ /** Usually the CWD; can be overridden with command argument. */
10
+ siteDir: string;
11
+ /** Custom output directory. Can be customized with `--out-dir` option */
12
+ outDir?: string;
13
+ /** Custom config path. Can be customized with `--config` option */
14
+ config?: string;
15
+ /** Default is `i18n.defaultLocale` */
11
16
  locale?: string;
17
+ /**
18
+ * `true` means the paths will have the locale prepended; `false` means they
19
+ * won't (useful for `yarn build -l zh-Hans` where the output should be
20
+ * emitted into `build/` instead of `build/zh-Hans/`); `undefined` is like the
21
+ * "smart" option where only non-default locale paths are localized
22
+ */
12
23
  localizePath?: boolean;
13
24
  };
14
- export declare function loadSiteConfig({ siteDir, customConfigFilePath, }: {
15
- siteDir: string;
16
- customConfigFilePath?: string;
17
- }): Promise<{
18
- siteConfig: DocusaurusConfig;
19
- siteConfigPath: string;
20
- }>;
21
- export declare function loadContext(siteDir: string, options?: LoadContextOptions): Promise<LoadContext>;
22
- export declare function loadPluginConfigs(context: LoadContext): Promise<PluginConfig[]>;
23
- export declare function load(siteDir: string, options?: LoadContextOptions): Promise<Props>;
25
+ /**
26
+ * Loading context is the very first step in site building. Its options are
27
+ * directly acquired from CLI options. It mainly loads `siteConfig` and the i18n
28
+ * context (which includes code translations). The `LoadContext` will be passed
29
+ * to plugin constructors.
30
+ */
31
+ export declare function loadContext(options: LoadContextOptions): Promise<LoadContext>;
32
+ /**
33
+ * This is the crux of the Docusaurus server-side. It reads everything it needs—
34
+ * code translations, config file, plugin modules... Plugins then use their
35
+ * lifecycles to generate content and other data. It is side-effect-ful because
36
+ * it generates temp files in the `.docusaurus` folder for the bundler.
37
+ */
38
+ export declare function load(options: LoadContextOptions): Promise<Props>;
@@ -6,50 +6,41 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.load = exports.loadPluginConfigs = exports.loadContext = exports.loadSiteConfig = void 0;
9
+ exports.load = exports.loadContext = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const utils_1 = require("@docusaurus/utils");
12
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
12
13
  const path_1 = tslib_1.__importDefault(require("path"));
13
- const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
14
- const ssr_html_template_1 = tslib_1.__importDefault(require("../webpack/templates/ssr.html.template"));
15
- const client_modules_1 = tslib_1.__importDefault(require("./client-modules"));
16
- const config_1 = tslib_1.__importDefault(require("./config"));
14
+ const config_1 = require("./config");
15
+ const clientModules_1 = require("./clientModules");
17
16
  const plugins_1 = require("./plugins");
18
- const presets_1 = tslib_1.__importDefault(require("./presets"));
19
- const routes_1 = tslib_1.__importDefault(require("./routes"));
20
- const html_tags_1 = require("./html-tags");
21
- const versions_1 = require("./versions");
22
- const duplicateRoutes_1 = require("./duplicateRoutes");
17
+ const routes_1 = require("./routes");
18
+ const htmlTags_1 = require("./htmlTags");
19
+ const siteMetadata_1 = require("./siteMetadata");
23
20
  const i18n_1 = require("./i18n");
24
21
  const translations_1 = require("./translations/translations");
25
- const lodash_1 = tslib_1.__importDefault(require("lodash"));
26
- const remark_admonitions_1 = tslib_1.__importDefault(require("remark-admonitions"));
27
- const module_1 = require("module");
28
- const moduleShorthand_1 = require("./moduleShorthand");
29
- async function loadSiteConfig({ siteDir, customConfigFilePath, }) {
30
- const siteConfigPath = path_1.default.resolve(siteDir, customConfigFilePath ?? utils_1.DEFAULT_CONFIG_FILE_NAME);
31
- const siteConfig = await (0, config_1.default)(siteConfigPath);
32
- return { siteConfig, siteConfigPath };
33
- }
34
- exports.loadSiteConfig = loadSiteConfig;
35
- async function loadContext(siteDir, options = {}) {
36
- const { customOutDir, locale, customConfigFilePath } = options;
22
+ /**
23
+ * Loading context is the very first step in site building. Its options are
24
+ * directly acquired from CLI options. It mainly loads `siteConfig` and the i18n
25
+ * context (which includes code translations). The `LoadContext` will be passed
26
+ * to plugin constructors.
27
+ */
28
+ async function loadContext(options) {
29
+ const { siteDir, outDir: baseOutDir = utils_1.DEFAULT_BUILD_DIR_NAME, locale, config: customConfigFilePath, } = options;
37
30
  const generatedFilesDir = path_1.default.resolve(siteDir, utils_1.GENERATED_FILES_DIR_NAME);
38
- const { siteConfig: initialSiteConfig, siteConfigPath } = await loadSiteConfig({
31
+ const { siteConfig: initialSiteConfig, siteConfigPath } = await (0, config_1.loadSiteConfig)({
39
32
  siteDir,
40
33
  customConfigFilePath,
41
34
  });
42
- const { ssrTemplate } = initialSiteConfig;
43
- const baseOutDir = path_1.default.resolve(siteDir, customOutDir ?? utils_1.DEFAULT_BUILD_DIR_NAME);
44
35
  const i18n = await (0, i18n_1.loadI18n)(initialSiteConfig, { locale });
45
- const baseUrl = (0, i18n_1.localizePath)({
36
+ const baseUrl = (0, utils_1.localizePath)({
46
37
  path: initialSiteConfig.baseUrl,
47
38
  i18n,
48
39
  options,
49
40
  pathType: 'url',
50
41
  });
51
- const outDir = (0, i18n_1.localizePath)({
52
- path: baseOutDir,
42
+ const outDir = (0, utils_1.localizePath)({
43
+ path: path_1.default.resolve(siteDir, baseOutDir),
53
44
  i18n,
54
45
  options,
55
46
  pathType: 'fs',
@@ -69,152 +60,36 @@ async function loadContext(siteDir, options = {}) {
69
60
  outDir,
70
61
  baseUrl,
71
62
  i18n,
72
- ssrTemplate: ssrTemplate ?? ssr_html_template_1.default,
73
63
  codeTranslations,
74
64
  };
75
65
  }
76
66
  exports.loadContext = loadContext;
77
- async function loadPluginConfigs(context) {
78
- let { plugins: presetPlugins, themes: presetThemes } = await (0, presets_1.default)(context);
79
- const { siteConfig, siteConfigPath } = context;
80
- const require = (0, module_1.createRequire)(siteConfigPath);
81
- function normalizeShorthand(pluginConfig, pluginType) {
82
- if (typeof pluginConfig === 'string') {
83
- return (0, moduleShorthand_1.resolveModuleName)(pluginConfig, require, pluginType);
84
- }
85
- else if (Array.isArray(pluginConfig) &&
86
- typeof pluginConfig[0] === 'string') {
87
- return [
88
- (0, moduleShorthand_1.resolveModuleName)(pluginConfig[0], require, pluginType),
89
- pluginConfig[1] ?? {},
90
- ];
91
- }
92
- return pluginConfig;
93
- }
94
- presetPlugins = presetPlugins.map((plugin) => normalizeShorthand(plugin, 'plugin'));
95
- presetThemes = presetThemes.map((theme) => normalizeShorthand(theme, 'theme'));
96
- const standalonePlugins = siteConfig.plugins.map((plugin) => normalizeShorthand(plugin, 'plugin'));
97
- const standaloneThemes = siteConfig.themes.map((theme) => normalizeShorthand(theme, 'theme'));
98
- return [
99
- ...presetPlugins,
100
- ...presetThemes,
101
- // Site config should be the highest priority.
102
- ...standalonePlugins,
103
- ...standaloneThemes,
104
- ];
105
- }
106
- exports.loadPluginConfigs = loadPluginConfigs;
107
- // Make a fake plugin to:
108
- // - Resolve aliased theme components
109
- // - Inject scripts/stylesheets
110
- function createBootstrapPlugin({ siteDir, siteConfig, }) {
111
- const { stylesheets, scripts, clientModules: siteConfigClientModules, } = siteConfig;
112
- return {
113
- name: 'docusaurus-bootstrap-plugin',
114
- content: null,
115
- options: {
116
- id: 'default',
117
- },
118
- version: { type: 'synthetic' },
119
- path: siteDir,
120
- getClientModules() {
121
- return siteConfigClientModules;
122
- },
123
- injectHtmlTags: () => {
124
- const stylesheetsTags = stylesheets.map((source) => typeof source === 'string'
125
- ? `<link rel="stylesheet" href="${source}">`
126
- : {
127
- tagName: 'link',
128
- attributes: {
129
- rel: 'stylesheet',
130
- ...source,
131
- },
132
- });
133
- const scriptsTags = scripts.map((source) => typeof source === 'string'
134
- ? `<script src="${source}"></script>`
135
- : {
136
- tagName: 'script',
137
- attributes: {
138
- ...source,
139
- },
140
- });
141
- return {
142
- headTags: [...stylesheetsTags, ...scriptsTags],
143
- };
144
- },
145
- };
146
- }
147
67
  /**
148
- * Configure Webpack fallback mdx loader for md/mdx files out of content-plugin
149
- * folders. Adds a "fallback" mdx loader for mdx files that are not processed by
150
- * content plugins. This allows to do things such as importing repo/README.md as
151
- * a partial from another doc. Not ideal solution, but good enough for now
68
+ * This is the crux of the Docusaurus server-side. It reads everything it needs—
69
+ * code translations, config file, plugin modules... Plugins then use their
70
+ * lifecycles to generate content and other data. It is side-effect-ful because
71
+ * it generates temp files in the `.docusaurus` folder for the bundler.
152
72
  */
153
- function createMDXFallbackPlugin({ siteDir, siteConfig, }) {
154
- return {
155
- name: 'docusaurus-mdx-fallback-plugin',
156
- content: null,
157
- options: {
158
- id: 'default',
159
- },
160
- version: { type: 'synthetic' },
161
- // Synthetic, the path doesn't matter much
162
- path: '.',
163
- configureWebpack(config, isServer, { getJSLoader }) {
164
- // We need the mdx fallback loader to exclude files that were already
165
- // processed by content plugins mdx loaders. This works, but a bit
166
- // hacky... Not sure there's a way to handle that differently in webpack
167
- function getMDXFallbackExcludedPaths() {
168
- const rules = config?.module?.rules;
169
- return rules.flatMap((rule) => {
170
- const isMDXRule = rule.test instanceof RegExp && rule.test.test('x.mdx');
171
- return isMDXRule ? rule.include : [];
172
- });
173
- }
174
- return {
175
- module: {
176
- rules: [
177
- {
178
- test: /\.mdx?$/i,
179
- exclude: getMDXFallbackExcludedPaths(),
180
- use: [
181
- getJSLoader({ isServer }),
182
- {
183
- loader: require.resolve('@docusaurus/mdx-loader'),
184
- options: {
185
- staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
186
- siteDir,
187
- isMDXPartial: () => true,
188
- isMDXPartialFrontMatterWarningDisabled: true,
189
- remarkPlugins: [remark_admonitions_1.default],
190
- },
191
- },
192
- ],
193
- },
194
- ],
195
- },
196
- };
197
- },
73
+ async function load(options) {
74
+ const { siteDir } = options;
75
+ const context = await loadContext(options);
76
+ const { generatedFilesDir, siteConfig, siteConfigPath, outDir, baseUrl, i18n, codeTranslations: siteCodeTranslations, } = context;
77
+ const { plugins, pluginsRouteConfigs, globalData } = await (0, plugins_1.loadPlugins)(context);
78
+ const clientModules = (0, clientModules_1.loadClientModules)(plugins);
79
+ const { headTags, preBodyTags, postBodyTags } = (0, htmlTags_1.loadHtmlTags)(plugins);
80
+ const { registry, routesChunkNames, routesConfig, routesPaths } = (0, routes_1.loadRoutes)(pluginsRouteConfigs, baseUrl, siteConfig.onDuplicateRoutes);
81
+ const codeTranslations = {
82
+ ...(await (0, translations_1.getPluginsDefaultCodeTranslationMessages)(plugins)),
83
+ ...siteCodeTranslations,
198
84
  };
199
- }
200
- async function load(siteDir, options = {}) {
201
- // Context.
202
- const context = await loadContext(siteDir, options);
203
- const { generatedFilesDir, siteConfig, siteConfigPath, outDir, baseUrl, i18n, ssrTemplate, codeTranslations, } = context;
204
- // Plugins.
205
- const pluginConfigs = await loadPluginConfigs(context);
206
- const { plugins, pluginsRouteConfigs, globalData, themeConfigTranslated } = await (0, plugins_1.loadPlugins)({ pluginConfigs, context });
207
- // Side-effect to replace the untranslated themeConfig by the translated one
208
- context.siteConfig.themeConfig = themeConfigTranslated;
209
- (0, duplicateRoutes_1.handleDuplicateRoutes)(pluginsRouteConfigs, siteConfig.onDuplicateRoutes);
85
+ const siteMetadata = await (0, siteMetadata_1.loadSiteMetadata)({ plugins, siteDir });
86
+ // === Side-effects part ===
210
87
  const genWarning = (0, utils_1.generate)(generatedFilesDir, 'DONT-EDIT-THIS-FOLDER', `This folder stores temp files that Docusaurus' client bundler accesses.
211
88
 
212
89
  DO NOT hand-modify files in this folder because they will be overwritten in the
213
90
  next build. You can clear all build artifacts (including this folder) with the
214
91
  \`docusaurus clear\` command.
215
92
  `);
216
- // Site config must be generated after plugins
217
- // We want the generated config to have been normalized by the plugins!
218
93
  const genSiteConfig = (0, utils_1.generate)(generatedFilesDir, utils_1.DEFAULT_CONFIG_FILE_NAME, `/*
219
94
  * AUTOGENERATED - DON'T EDIT
220
95
  * Your edits in this file will be overwritten in the next build!
@@ -222,48 +97,25 @@ next build. You can clear all build artifacts (including this folder) with the
222
97
  */
223
98
  export default ${JSON.stringify(siteConfig, null, 2)};
224
99
  `);
225
- plugins.push(createBootstrapPlugin({ siteDir, siteConfig }), createMDXFallbackPlugin({ siteDir, siteConfig }));
226
- // Load client modules.
227
- const clientModules = (0, client_modules_1.default)(plugins);
228
100
  const genClientModules = (0, utils_1.generate)(generatedFilesDir, 'client-modules.js', `export default [
229
101
  ${clientModules
230
- // import() is async so we use require() because client modules can have
231
- // CSS and the order matters for loading CSS.
232
- .map((module) => ` require('${(0, utils_1.escapePath)(module)}'),`)
102
+ // Use `require()` because `import()` is async but client modules can have CSS
103
+ // and the order matters for loading CSS.
104
+ .map((clientModule) => ` require('${(0, utils_1.escapePath)(clientModule)}'),`)
233
105
  .join('\n')}
234
106
  ];
235
107
  `);
236
- // Load extra head & body html tags.
237
- const { headTags, preBodyTags, postBodyTags } = (0, html_tags_1.loadHtmlTags)(plugins);
238
- // Routing.
239
- const { registry, routesChunkNames, routesConfig, routesPaths } = await (0, routes_1.default)(pluginsRouteConfigs, baseUrl);
240
108
  const genRegistry = (0, utils_1.generate)(generatedFilesDir, 'registry.js', `export default {
241
109
  ${Object.entries(registry)
242
110
  .sort((a, b) => a[0].localeCompare(b[0]))
243
- .map(([key, chunk]) => ` '${key}': [${chunk.loader}, '${(0, utils_1.escapePath)(chunk.modulePath)}', require.resolveWeak('${(0, utils_1.escapePath)(chunk.modulePath)}')],`)
111
+ .map(([chunkName, modulePath]) => ` '${chunkName}': [() => import(/* webpackChunkName: '${chunkName}' */ '${modulePath}'), '${modulePath}', require.resolveWeak('${modulePath}')],`)
244
112
  .join('\n')}};
245
113
  `);
246
114
  const genRoutesChunkNames = (0, utils_1.generate)(generatedFilesDir, 'routesChunkNames.json', JSON.stringify(routesChunkNames, null, 2));
247
115
  const genRoutes = (0, utils_1.generate)(generatedFilesDir, 'routes.js', routesConfig);
248
116
  const genGlobalData = (0, utils_1.generate)(generatedFilesDir, 'globalData.json', JSON.stringify(globalData, null, 2));
249
117
  const genI18n = (0, utils_1.generate)(generatedFilesDir, 'i18n.json', JSON.stringify(i18n, null, 2));
250
- const codeTranslationsWithFallbacks = {
251
- ...(await (0, translations_1.getPluginsDefaultCodeTranslationMessages)(plugins)),
252
- ...codeTranslations,
253
- };
254
- const genCodeTranslations = (0, utils_1.generate)(generatedFilesDir, 'codeTranslations.json', JSON.stringify(codeTranslationsWithFallbacks, null, 2));
255
- // Version metadata.
256
- const siteMetadata = {
257
- docusaurusVersion: (await (0, versions_1.getPackageJsonVersion)(path_1.default.join(__dirname, '../../package.json'))),
258
- siteVersion: await (0, versions_1.getPackageJsonVersion)(path_1.default.join(siteDir, 'package.json')),
259
- pluginVersions: {},
260
- };
261
- plugins
262
- .filter(({ version: { type } }) => type !== 'synthetic')
263
- .forEach(({ name, version }) => {
264
- siteMetadata.pluginVersions[name] = version;
265
- });
266
- checkDocusaurusPackagesVersion(siteMetadata);
118
+ const genCodeTranslations = (0, utils_1.generate)(generatedFilesDir, 'codeTranslations.json', JSON.stringify(codeTranslations, null, 2));
267
119
  const genSiteMetadata = (0, utils_1.generate)(generatedFilesDir, 'site-metadata.json', JSON.stringify(siteMetadata, null, 2));
268
120
  await Promise.all([
269
121
  genWarning,
@@ -277,7 +129,7 @@ ${Object.entries(registry)
277
129
  genI18n,
278
130
  genCodeTranslations,
279
131
  ]);
280
- const props = {
132
+ return {
281
133
  siteConfig,
282
134
  siteConfigPath,
283
135
  siteMetadata,
@@ -292,27 +144,7 @@ ${Object.entries(registry)
292
144
  headTags,
293
145
  preBodyTags,
294
146
  postBodyTags,
295
- ssrTemplate,
296
147
  codeTranslations,
297
148
  };
298
- return props;
299
149
  }
300
150
  exports.load = load;
301
- // We want all @docusaurus/* packages to have the exact same version!
302
- // See https://github.com/facebook/docusaurus/issues/3371
303
- // See https://github.com/facebook/docusaurus/pull/3386
304
- function checkDocusaurusPackagesVersion(siteMetadata) {
305
- const { docusaurusVersion } = siteMetadata;
306
- Object.entries(siteMetadata.pluginVersions).forEach(([plugin, versionInfo]) => {
307
- if (versionInfo.type === 'package' &&
308
- versionInfo.name?.startsWith('@docusaurus/') &&
309
- versionInfo.version &&
310
- versionInfo.version !== docusaurusVersion) {
311
- // should we throw instead?
312
- // It still could work with different versions
313
- logger_1.default.error `Invalid name=${plugin} version number=${versionInfo.version}.
314
- All official @docusaurus/* packages should have the exact same version as @docusaurus/core (number=${docusaurusVersion}).
315
- Maybe you want to check, or regenerate your yarn.lock or package-lock.json file?`;
316
- }
317
- });
318
- }