@docusaurus/core 0.0.0-4799 → 0.0.0-4802

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 (50) hide show
  1. package/lib/commands/build.js +4 -2
  2. package/lib/commands/commandUtils.js +2 -3
  3. package/lib/commands/deploy.js +2 -1
  4. package/lib/commands/external.js +1 -1
  5. package/lib/commands/serve.js +2 -2
  6. package/lib/commands/start.js +2 -1
  7. package/lib/commands/swizzle/common.d.ts +1 -2
  8. package/lib/commands/swizzle/context.js +2 -3
  9. package/lib/commands/writeHeadingIds.js +1 -1
  10. package/lib/commands/writeTranslations.js +2 -1
  11. package/lib/server/choosePort.d.ts +12 -0
  12. package/lib/{choosePort.js → server/choosePort.js} +8 -10
  13. package/lib/server/clientModules.d.ts +5 -1
  14. package/lib/server/clientModules.js +4 -0
  15. package/lib/server/config.d.ts +5 -2
  16. package/lib/server/config.js +11 -7
  17. package/lib/server/htmlTags.d.ts +6 -2
  18. package/lib/server/htmlTags.js +4 -0
  19. package/lib/server/i18n.d.ts +2 -3
  20. package/lib/server/index.d.ts +26 -10
  21. package/lib/server/index.js +34 -37
  22. package/lib/server/plugins/configs.d.ts +8 -2
  23. package/lib/server/plugins/configs.js +64 -5
  24. package/lib/server/plugins/index.d.ts +4 -0
  25. package/lib/server/plugins/index.js +20 -21
  26. package/lib/server/plugins/init.d.ts +5 -15
  27. package/lib/server/plugins/init.js +8 -61
  28. package/lib/server/{moduleShorthand.d.ts → plugins/moduleShorthand.d.ts} +0 -0
  29. package/lib/server/{moduleShorthand.js → plugins/moduleShorthand.js} +0 -0
  30. package/lib/server/plugins/pluginIds.d.ts +4 -0
  31. package/lib/server/plugins/pluginIds.js +4 -2
  32. package/lib/server/plugins/presets.d.ts +6 -5
  33. package/lib/server/plugins/presets.js +7 -3
  34. package/lib/server/routes.d.ts +3 -2
  35. package/lib/server/routes.js +49 -24
  36. package/lib/server/siteMetadata.d.ts +2 -2
  37. package/lib/server/siteMetadata.js +2 -1
  38. package/lib/server/translations/translations.js +1 -4
  39. package/lib/webpack/aliases/index.d.ts +29 -0
  40. package/lib/webpack/aliases/index.js +106 -0
  41. package/lib/webpack/base.d.ts +0 -3
  42. package/lib/webpack/base.js +4 -21
  43. package/package.json +10 -11
  44. package/lib/choosePort.d.ts +0 -11
  45. package/lib/server/duplicateRoutes.d.ts +0 -8
  46. package/lib/server/duplicateRoutes.js +0 -42
  47. package/lib/server/themes/alias.d.ts +0 -9
  48. package/lib/server/themes/alias.js +0 -50
  49. package/lib/server/themes/index.d.ts +0 -12
  50. package/lib/server/themes/index.js +0 -47
@@ -47,7 +47,8 @@ forceTerminate = true) {
47
47
  throw err;
48
48
  }
49
49
  }
50
- const context = await (0, server_1.loadContext)(siteDir, {
50
+ const context = await (0, server_1.loadContext)({
51
+ siteDir,
51
52
  customOutDir: cliOptions.outDir,
52
53
  customConfigFilePath: cliOptions.config,
53
54
  locale: cliOptions.locale,
@@ -79,7 +80,8 @@ async function buildLocale({ siteDir, locale, cliOptions, forceTerminate, isLast
79
80
  process.env.BABEL_ENV = 'production';
80
81
  process.env.NODE_ENV = 'production';
81
82
  logger_1.default.info `name=${`[${locale}]`} Creating an optimized production build...`;
82
- const props = await (0, server_1.load)(siteDir, {
83
+ const props = await (0, server_1.load)({
84
+ siteDir,
83
85
  customOutDir: cliOptions.outDir,
84
86
  customConfigFilePath: cliOptions.config,
85
87
  locale,
@@ -7,8 +7,7 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.getCLIOptionPort = exports.getCLIOptionHost = void 0;
10
- const tslib_1 = require("tslib");
11
- const choosePort_1 = tslib_1.__importDefault(require("../choosePort"));
10
+ const choosePort_1 = require("../server/choosePort");
12
11
  const utils_1 = require("@docusaurus/utils");
13
12
  function getCLIOptionHost(hostOption) {
14
13
  return hostOption ?? 'localhost';
@@ -16,6 +15,6 @@ function getCLIOptionHost(hostOption) {
16
15
  exports.getCLIOptionHost = getCLIOptionHost;
17
16
  async function getCLIOptionPort(portOption, host) {
18
17
  const basePort = portOption ? parseInt(portOption, 10) : utils_1.DEFAULT_PORT;
19
- return (0, choosePort_1.default)(host, basePort);
18
+ return (0, choosePort_1.choosePort)(host, basePort);
20
19
  }
21
20
  exports.getCLIOptionPort = getCLIOptionPort;
@@ -35,7 +35,8 @@ function shellExecLog(cmd) {
35
35
  }
36
36
  }
37
37
  async function deploy(siteDir, cliOptions = {}) {
38
- const { outDir, siteConfig, siteConfigPath } = await (0, server_1.loadContext)(siteDir, {
38
+ const { outDir, siteConfig, siteConfigPath } = await (0, server_1.loadContext)({
39
+ siteDir,
39
40
  customConfigFilePath: cliOptions.config,
40
41
  customOutDir: cliOptions.outDir,
41
42
  });
@@ -10,7 +10,7 @@ exports.externalCommand = void 0;
10
10
  const server_1 = require("../server");
11
11
  const init_1 = require("../server/plugins/init");
12
12
  async function externalCommand(cli, siteDir) {
13
- const context = await (0, server_1.loadContext)(siteDir);
13
+ const context = await (0, server_1.loadContext)({ siteDir });
14
14
  const plugins = await (0, init_1.initPlugins)(context);
15
15
  // Plugin Lifecycle - extendCli.
16
16
  plugins.forEach((plugin) => {
@@ -12,7 +12,7 @@ const http_1 = tslib_1.__importDefault(require("http"));
12
12
  const serve_handler_1 = tslib_1.__importDefault(require("serve-handler"));
13
13
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
14
14
  const path_1 = tslib_1.__importDefault(require("path"));
15
- const server_1 = require("../server");
15
+ const config_1 = require("../server/config");
16
16
  const build_1 = require("./build");
17
17
  const commandUtils_1 = require("./commandUtils");
18
18
  async function serve(siteDir, cliOptions) {
@@ -28,7 +28,7 @@ async function serve(siteDir, cliOptions) {
28
28
  if (port === null) {
29
29
  process.exit();
30
30
  }
31
- const { siteConfig: { baseUrl, trailingSlash }, } = await (0, server_1.loadSiteConfig)({
31
+ const { siteConfig: { baseUrl, trailingSlash }, } = await (0, config_1.loadSiteConfig)({
32
32
  siteDir,
33
33
  customConfigFilePath: cliOptions.config,
34
34
  });
@@ -30,7 +30,8 @@ async function start(siteDir, cliOptions) {
30
30
  process.env.BABEL_ENV = 'development';
31
31
  logger_1.default.info('Starting the development server...');
32
32
  function loadSite() {
33
- return (0, server_1.load)(siteDir, {
33
+ return (0, server_1.load)({
34
+ siteDir,
34
35
  customConfigFilePath: cliOptions.config,
35
36
  locale: cliOptions.locale,
36
37
  localizePath: undefined, // should this be configurable?
@@ -4,8 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import type { InitializedPlugin, SwizzleAction, SwizzleActionStatus } from '@docusaurus/types';
8
- import type { NormalizedPluginConfig } from '../../server/plugins/init';
7
+ import type { InitializedPlugin, SwizzleAction, SwizzleActionStatus, NormalizedPluginConfig } from '@docusaurus/types';
9
8
  export declare const SwizzleActions: SwizzleAction[];
10
9
  export declare const SwizzleActionsStatuses: SwizzleActionStatus[];
11
10
  export declare const PartiallySafeHint: string;
@@ -11,13 +11,12 @@ const server_1 = require("../../server");
11
11
  const init_1 = require("../../server/plugins/init");
12
12
  const configs_1 = require("../../server/plugins/configs");
13
13
  async function initSwizzleContext(siteDir) {
14
- const context = await (0, server_1.loadContext)(siteDir);
14
+ const context = await (0, server_1.loadContext)({ siteDir });
15
15
  const plugins = await (0, init_1.initPlugins)(context);
16
16
  const pluginConfigs = await (0, configs_1.loadPluginConfigs)(context);
17
- const pluginsNormalized = await (0, init_1.normalizePluginConfigs)(pluginConfigs, context.siteConfigPath);
18
17
  return {
19
18
  plugins: plugins.map((plugin, pluginIndex) => ({
20
- plugin: pluginsNormalized[pluginIndex],
19
+ plugin: pluginConfigs[pluginIndex],
21
20
  instance: plugin,
22
21
  })),
23
22
  };
@@ -30,7 +30,7 @@ async function transformMarkdownFile(filepath, options) {
30
30
  * transformed
31
31
  */
32
32
  async function getPathsToWatch(siteDir) {
33
- const context = await (0, server_1.loadContext)(siteDir);
33
+ const context = await (0, server_1.loadContext)({ siteDir });
34
34
  const plugins = await (0, init_1.initPlugins)(context);
35
35
  return plugins.flatMap((plugin) => plugin?.getPathsToWatch?.() ?? []);
36
36
  }
@@ -48,7 +48,8 @@ async function writePluginTranslationFiles({ siteDir, plugin, locale, options, }
48
48
  }
49
49
  }
50
50
  async function writeTranslations(siteDir, options) {
51
- const context = await (0, server_1.loadContext)(siteDir, {
51
+ const context = await (0, server_1.loadContext)({
52
+ siteDir,
52
53
  customConfigFilePath: options.config,
53
54
  locale: options.locale,
54
55
  });
@@ -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
+ /**
8
+ * Detects if program is running on port, and prompts user to choose another if
9
+ * port is already being used. This feature was heavily inspired by
10
+ * create-react-app and uses many of the same utility functions to implement it.
11
+ */
12
+ export declare function choosePort(host: string, defaultPort: number): Promise<number | null>;
@@ -6,17 +6,12 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.choosePort = 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"));
18
14
  const prompts_1 = tslib_1.__importDefault(require("prompts"));
19
- const isInteractive = process.stdout.isTTY;
20
15
  const execOptions = {
21
16
  encoding: 'utf8',
22
17
  stdio: [
@@ -57,8 +52,9 @@ function getProcessForPort(port) {
57
52
  }
58
53
  }
59
54
  /**
60
- * Detects if program is running on port and prompts user
61
- * to choose another if port is already being used
55
+ * Detects if program is running on port, and prompts user to choose another if
56
+ * port is already being used. This feature was heavily inspired by
57
+ * create-react-app and uses many of the same utility functions to implement it.
62
58
  */
63
59
  async function choosePort(host, defaultPort) {
64
60
  try {
@@ -66,7 +62,9 @@ async function choosePort(host, defaultPort) {
66
62
  if (port === defaultPort) {
67
63
  return port;
68
64
  }
69
- const message = process.platform !== 'win32' && defaultPort < 1024 && !(0, is_root_1.default)()
65
+ const isRoot = process.getuid?.() === 0;
66
+ const isInteractive = process.stdout.isTTY;
67
+ const message = process.platform !== 'win32' && defaultPort < 1024 && !isRoot
70
68
  ? `Admin permissions are required to run a server on a port below 1024.`
71
69
  : `Something is already running on port ${defaultPort}.`;
72
70
  if (!isInteractive) {
@@ -90,4 +88,4 @@ Would you like to run the app on another port instead?`),
90
88
  throw err;
91
89
  }
92
90
  }
93
- exports.default = choosePort;
91
+ exports.choosePort = choosePort;
@@ -5,4 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { LoadedPlugin } from '@docusaurus/types';
8
- export declare function loadClientModules(plugins: LoadedPlugin<unknown>[]): string[];
8
+ /**
9
+ * Runs the `getClientModules` lifecycle. The returned file paths are all
10
+ * absolute.
11
+ */
12
+ export declare function loadClientModules(plugins: LoadedPlugin[]): string[];
@@ -9,6 +9,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.loadClientModules = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const path_1 = tslib_1.__importDefault(require("path"));
12
+ /**
13
+ * Runs the `getClientModules` lifecycle. The returned file paths are all
14
+ * absolute.
15
+ */
12
16
  function loadClientModules(plugins) {
13
17
  return plugins.flatMap((plugin) => plugin.getClientModules?.().map((p) => path_1.default.resolve(plugin.path, p)) ??
14
18
  []);
@@ -4,5 +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
- import type { DocusaurusConfig } from '@docusaurus/types';
8
- export declare function loadConfig(configPath: string): Promise<DocusaurusConfig>;
7
+ import type { LoadContext } from '@docusaurus/types';
8
+ export declare function loadSiteConfig({ siteDir, customConfigFilePath, }: {
9
+ siteDir: string;
10
+ customConfigFilePath?: string;
11
+ }): Promise<Pick<LoadContext, 'siteConfig' | 'siteConfigPath'>>;
@@ -6,19 +6,23 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.loadConfig = void 0;
9
+ exports.loadSiteConfig = void 0;
10
10
  const tslib_1 = require("tslib");
11
+ const path_1 = tslib_1.__importDefault(require("path"));
11
12
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
13
  const import_fresh_1 = tslib_1.__importDefault(require("import-fresh"));
14
+ const utils_1 = require("@docusaurus/utils");
13
15
  const configValidation_1 = require("./configValidation");
14
- async function loadConfig(configPath) {
15
- if (!(await fs_extra_1.default.pathExists(configPath))) {
16
- throw new Error(`Config file at "${configPath}" not found.`);
16
+ async function loadSiteConfig({ siteDir, customConfigFilePath, }) {
17
+ const siteConfigPath = path_1.default.resolve(siteDir, customConfigFilePath ?? utils_1.DEFAULT_CONFIG_FILE_NAME);
18
+ if (!(await fs_extra_1.default.pathExists(siteConfigPath))) {
19
+ throw new Error(`Config file at "${siteConfigPath}" not found.`);
17
20
  }
18
- const importedConfig = (0, import_fresh_1.default)(configPath);
21
+ const importedConfig = (0, import_fresh_1.default)(siteConfigPath);
19
22
  const loadedConfig = typeof importedConfig === 'function'
20
23
  ? await importedConfig()
21
24
  : await importedConfig;
22
- return (0, configValidation_1.validateConfig)(loadedConfig);
25
+ const siteConfig = (0, configValidation_1.validateConfig)(loadedConfig);
26
+ return { siteConfig, siteConfigPath };
23
27
  }
24
- exports.loadConfig = loadConfig;
28
+ exports.loadSiteConfig = loadSiteConfig;
@@ -4,5 +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 type { InjectedHtmlTags, LoadedPlugin } from '@docusaurus/types';
8
- export declare function loadHtmlTags(plugins: LoadedPlugin[]): InjectedHtmlTags;
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'>;
@@ -47,6 +47,10 @@ function createHtmlTagsString(tags) {
47
47
  .map((val) => (typeof val === 'string' ? val : htmlTagObjectToString(val)))
48
48
  .join('\n');
49
49
  }
50
+ /**
51
+ * Runs the `injectHtmlTags` lifecycle, and aggregates all plugins' tags into
52
+ * directly render-able HTML markup.
53
+ */
50
54
  function loadHtmlTags(plugins) {
51
55
  const pluginHtmlTags = plugins.map((plugin) => plugin.injectHtmlTags?.({ content: plugin.content }) ?? {});
52
56
  const tagTypes = ['headTags', 'preBodyTags', 'postBodyTags'];
@@ -5,7 +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>;
10
+ export declare function loadI18n(config: DocusaurusConfig, options: Pick<LoadContextOptions, 'locale'>): Promise<I18n>;
@@ -4,19 +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, Props } from '@docusaurus/types';
7
+ import type { LoadContext, Props } from '@docusaurus/types';
8
8
  export declare type LoadContextOptions = {
9
+ /** Usually the CWD; can be overridden with command argument. */
10
+ siteDir: string;
11
+ /** Can be customized with `--out-dir` option */
9
12
  customOutDir?: string;
13
+ /** Can be customized with `--config` option */
10
14
  customConfigFilePath?: 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 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,36 +6,33 @@
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.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
12
  const lodash_1 = tslib_1.__importDefault(require("lodash"));
13
13
  const path_1 = tslib_1.__importDefault(require("path"));
14
+ const config_1 = require("./config");
14
15
  const ssr_html_template_1 = tslib_1.__importDefault(require("../webpack/templates/ssr.html.template"));
15
16
  const clientModules_1 = require("./clientModules");
16
- const config_1 = require("./config");
17
17
  const plugins_1 = require("./plugins");
18
18
  const routes_1 = require("./routes");
19
19
  const htmlTags_1 = require("./htmlTags");
20
20
  const siteMetadata_1 = require("./siteMetadata");
21
- const duplicateRoutes_1 = require("./duplicateRoutes");
22
21
  const i18n_1 = require("./i18n");
23
22
  const translations_1 = require("./translations/translations");
24
- async function loadSiteConfig({ siteDir, customConfigFilePath, }) {
25
- const siteConfigPath = path_1.default.resolve(siteDir, customConfigFilePath ?? utils_1.DEFAULT_CONFIG_FILE_NAME);
26
- const siteConfig = await (0, config_1.loadConfig)(siteConfigPath);
27
- return { siteConfig, siteConfigPath };
28
- }
29
- exports.loadSiteConfig = loadSiteConfig;
30
- async function loadContext(siteDir, options = {}) {
31
- const { customOutDir, locale, customConfigFilePath } = options;
23
+ /**
24
+ * Loading context is the very first step in site building. Its options are
25
+ * directly acquired from CLI options. It mainly loads `siteConfig` and the i18n
26
+ * context (which includes code translations). The `LoadContext` will be passed
27
+ * to plugin constructors.
28
+ */
29
+ async function loadContext(options) {
30
+ const { siteDir, customOutDir, locale, customConfigFilePath } = options;
32
31
  const generatedFilesDir = path_1.default.resolve(siteDir, utils_1.GENERATED_FILES_DIR_NAME);
33
- const { siteConfig: initialSiteConfig, siteConfigPath } = await loadSiteConfig({
32
+ const { siteConfig: initialSiteConfig, siteConfigPath } = await (0, config_1.loadSiteConfig)({
34
33
  siteDir,
35
34
  customConfigFilePath,
36
35
  });
37
- const { ssrTemplate } = initialSiteConfig;
38
- const baseOutDir = path_1.default.resolve(siteDir, customOutDir ?? utils_1.DEFAULT_BUILD_DIR_NAME);
39
36
  const i18n = await (0, i18n_1.loadI18n)(initialSiteConfig, { locale });
40
37
  const baseUrl = (0, utils_1.localizePath)({
41
38
  path: initialSiteConfig.baseUrl,
@@ -44,7 +41,7 @@ async function loadContext(siteDir, options = {}) {
44
41
  pathType: 'url',
45
42
  });
46
43
  const outDir = (0, utils_1.localizePath)({
47
- path: baseOutDir,
44
+ path: path_1.default.resolve(siteDir, customOutDir ?? utils_1.DEFAULT_BUILD_DIR_NAME),
48
45
  i18n,
49
46
  options,
50
47
  pathType: 'fs',
@@ -64,20 +61,33 @@ async function loadContext(siteDir, options = {}) {
64
61
  outDir,
65
62
  baseUrl,
66
63
  i18n,
67
- ssrTemplate: ssrTemplate ?? ssr_html_template_1.default,
64
+ ssrTemplate: siteConfig.ssrTemplate ?? ssr_html_template_1.default,
68
65
  codeTranslations,
69
66
  };
70
67
  }
71
68
  exports.loadContext = loadContext;
72
- async function load(siteDir, options = {}) {
73
- // Context.
74
- const context = await loadContext(siteDir, options);
75
- const { generatedFilesDir, siteConfig, siteConfigPath, outDir, baseUrl, i18n, ssrTemplate, codeTranslations, } = context;
76
- // Plugins.
69
+ /**
70
+ * This is the crux of the Docusaurus server-side. It reads everything it needs—
71
+ * code translations, config file, plugin modules... Plugins then use their
72
+ * lifecycles to generate content and other data. It is side-effect-ful because
73
+ * it generates temp files in the `.docusaurus` folder for the bundler.
74
+ */
75
+ async function load(options) {
76
+ const { siteDir } = options;
77
+ const context = await loadContext(options);
78
+ const { generatedFilesDir, siteConfig, siteConfigPath, outDir, baseUrl, i18n, ssrTemplate, codeTranslations: siteCodeTranslations, } = context;
77
79
  const { plugins, pluginsRouteConfigs, globalData, themeConfigTranslated } = await (0, plugins_1.loadPlugins)(context);
78
80
  // Side-effect to replace the untranslated themeConfig by the translated one
79
81
  context.siteConfig.themeConfig = themeConfigTranslated;
80
- (0, duplicateRoutes_1.handleDuplicateRoutes)(pluginsRouteConfigs, siteConfig.onDuplicateRoutes);
82
+ const clientModules = (0, clientModules_1.loadClientModules)(plugins);
83
+ const { headTags, preBodyTags, postBodyTags } = (0, htmlTags_1.loadHtmlTags)(plugins);
84
+ const { registry, routesChunkNames, routesConfig, routesPaths } = await (0, routes_1.loadRoutes)(pluginsRouteConfigs, baseUrl, siteConfig.onDuplicateRoutes);
85
+ const codeTranslations = {
86
+ ...(await (0, translations_1.getPluginsDefaultCodeTranslationMessages)(plugins)),
87
+ ...siteCodeTranslations,
88
+ };
89
+ const siteMetadata = await (0, siteMetadata_1.loadSiteMetadata)({ plugins, siteDir });
90
+ // === Side-effects part ===
81
91
  const genWarning = (0, utils_1.generate)(generatedFilesDir, 'DONT-EDIT-THIS-FOLDER', `This folder stores temp files that Docusaurus' client bundler accesses.
82
92
 
83
93
  DO NOT hand-modify files in this folder because they will be overwritten in the
@@ -93,8 +103,6 @@ next build. You can clear all build artifacts (including this folder) with the
93
103
  */
94
104
  export default ${JSON.stringify(siteConfig, null, 2)};
95
105
  `);
96
- // Load client modules.
97
- const clientModules = (0, clientModules_1.loadClientModules)(plugins);
98
106
  const genClientModules = (0, utils_1.generate)(generatedFilesDir, 'client-modules.js', `export default [
99
107
  ${clientModules
100
108
  // import() is async so we use require() because client modules can have
@@ -103,10 +111,6 @@ ${clientModules
103
111
  .join('\n')}
104
112
  ];
105
113
  `);
106
- // Load extra head & body html tags.
107
- const { headTags, preBodyTags, postBodyTags } = (0, htmlTags_1.loadHtmlTags)(plugins);
108
- // Routing.
109
- const { registry, routesChunkNames, routesConfig, routesPaths } = await (0, routes_1.loadRoutes)(pluginsRouteConfigs, baseUrl);
110
114
  const genRegistry = (0, utils_1.generate)(generatedFilesDir, 'registry.js', `export default {
111
115
  ${Object.entries(registry)
112
116
  .sort((a, b) => a[0].localeCompare(b[0]))
@@ -117,13 +121,7 @@ ${Object.entries(registry)
117
121
  const genRoutes = (0, utils_1.generate)(generatedFilesDir, 'routes.js', routesConfig);
118
122
  const genGlobalData = (0, utils_1.generate)(generatedFilesDir, 'globalData.json', JSON.stringify(globalData, null, 2));
119
123
  const genI18n = (0, utils_1.generate)(generatedFilesDir, 'i18n.json', JSON.stringify(i18n, null, 2));
120
- const codeTranslationsWithFallbacks = {
121
- ...(await (0, translations_1.getPluginsDefaultCodeTranslationMessages)(plugins)),
122
- ...codeTranslations,
123
- };
124
- const genCodeTranslations = (0, utils_1.generate)(generatedFilesDir, 'codeTranslations.json', JSON.stringify(codeTranslationsWithFallbacks, null, 2));
125
- // Version metadata.
126
- const siteMetadata = await (0, siteMetadata_1.loadSiteMetadata)({ plugins, siteDir });
124
+ const genCodeTranslations = (0, utils_1.generate)(generatedFilesDir, 'codeTranslations.json', JSON.stringify(codeTranslations, null, 2));
127
125
  const genSiteMetadata = (0, utils_1.generate)(generatedFilesDir, 'site-metadata.json', JSON.stringify(siteMetadata, null, 2));
128
126
  await Promise.all([
129
127
  genWarning,
@@ -137,7 +135,7 @@ ${Object.entries(registry)
137
135
  genI18n,
138
136
  genCodeTranslations,
139
137
  ]);
140
- const props = {
138
+ return {
141
139
  siteConfig,
142
140
  siteConfigPath,
143
141
  siteMetadata,
@@ -155,6 +153,5 @@ ${Object.entries(registry)
155
153
  ssrTemplate,
156
154
  codeTranslations,
157
155
  };
158
- return props;
159
156
  }
160
157
  exports.load = load;
@@ -4,5 +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 type { LoadContext, PluginConfig } from '@docusaurus/types';
8
- export declare function loadPluginConfigs(context: LoadContext): Promise<PluginConfig[]>;
7
+ import type { LoadContext, NormalizedPluginConfig } from '@docusaurus/types';
8
+ /**
9
+ * Reads the site config's `presets`, `themes`, and `plugins`, imports them, and
10
+ * normalizes the return value. Plugin configs are ordered, mostly for theme
11
+ * alias shadowing. Site themes have the highest priority, and preset plugins
12
+ * are the lowest.
13
+ */
14
+ export declare function loadPluginConfigs(context: LoadContext): Promise<NormalizedPluginConfig[]>;
@@ -7,21 +7,79 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.loadPluginConfigs = void 0;
10
+ const tslib_1 = require("tslib");
10
11
  const module_1 = require("module");
12
+ const import_fresh_1 = tslib_1.__importDefault(require("import-fresh"));
11
13
  const presets_1 = require("./presets");
12
- const moduleShorthand_1 = require("../moduleShorthand");
14
+ const moduleShorthand_1 = require("./moduleShorthand");
15
+ async function normalizePluginConfig(pluginConfig, configPath, pluginRequire) {
16
+ // plugins: ["./plugin"]
17
+ if (typeof pluginConfig === 'string') {
18
+ const pluginModuleImport = pluginConfig;
19
+ const pluginPath = pluginRequire.resolve(pluginModuleImport);
20
+ const pluginModule = (0, import_fresh_1.default)(pluginPath);
21
+ return {
22
+ plugin: pluginModule?.default ?? pluginModule,
23
+ options: {},
24
+ pluginModule: {
25
+ path: pluginModuleImport,
26
+ module: pluginModule,
27
+ },
28
+ entryPath: pluginPath,
29
+ };
30
+ }
31
+ // plugins: [() => {...}]
32
+ if (typeof pluginConfig === 'function') {
33
+ return {
34
+ plugin: pluginConfig,
35
+ options: {},
36
+ entryPath: configPath,
37
+ };
38
+ }
39
+ // plugins: [
40
+ // ["./plugin",options],
41
+ // ]
42
+ if (typeof pluginConfig[0] === 'string') {
43
+ const pluginModuleImport = pluginConfig[0];
44
+ const pluginPath = pluginRequire.resolve(pluginModuleImport);
45
+ const pluginModule = (0, import_fresh_1.default)(pluginPath);
46
+ return {
47
+ plugin: pluginModule?.default ?? pluginModule,
48
+ options: pluginConfig[1],
49
+ pluginModule: {
50
+ path: pluginModuleImport,
51
+ module: pluginModule,
52
+ },
53
+ entryPath: pluginPath,
54
+ };
55
+ }
56
+ // plugins: [
57
+ // [() => {...}, options],
58
+ // ]
59
+ return {
60
+ plugin: pluginConfig[0],
61
+ options: pluginConfig[1],
62
+ entryPath: configPath,
63
+ };
64
+ }
65
+ /**
66
+ * Reads the site config's `presets`, `themes`, and `plugins`, imports them, and
67
+ * normalizes the return value. Plugin configs are ordered, mostly for theme
68
+ * alias shadowing. Site themes have the highest priority, and preset plugins
69
+ * are the lowest.
70
+ */
13
71
  async function loadPluginConfigs(context) {
14
72
  const preset = await (0, presets_1.loadPresets)(context);
15
73
  const { siteConfig, siteConfigPath } = context;
16
- const require = (0, module_1.createRequire)(siteConfigPath);
74
+ const pluginRequire = (0, module_1.createRequire)(siteConfigPath);
17
75
  function normalizeShorthand(pluginConfig, pluginType) {
18
76
  if (typeof pluginConfig === 'string') {
19
- return (0, moduleShorthand_1.resolveModuleName)(pluginConfig, require, pluginType);
77
+ return (0, moduleShorthand_1.resolveModuleName)(pluginConfig, pluginRequire, pluginType);
20
78
  }
21
79
  else if (Array.isArray(pluginConfig) &&
22
80
  typeof pluginConfig[0] === 'string') {
23
81
  return [
24
- (0, moduleShorthand_1.resolveModuleName)(pluginConfig[0], require, pluginType),
82
+ (0, moduleShorthand_1.resolveModuleName)(pluginConfig[0], pluginRequire, pluginType),
25
83
  pluginConfig[1] ?? {},
26
84
  ];
27
85
  }
@@ -31,12 +89,13 @@ async function loadPluginConfigs(context) {
31
89
  preset.themes = preset.themes.map((theme) => normalizeShorthand(theme, 'theme'));
32
90
  const standalonePlugins = siteConfig.plugins.map((plugin) => normalizeShorthand(plugin, 'plugin'));
33
91
  const standaloneThemes = siteConfig.themes.map((theme) => normalizeShorthand(theme, 'theme'));
34
- return [
92
+ const pluginConfigs = [
35
93
  ...preset.plugins,
36
94
  ...preset.themes,
37
95
  // Site config should be the highest priority.
38
96
  ...standalonePlugins,
39
97
  ...standaloneThemes,
40
98
  ];
99
+ return Promise.all(pluginConfigs.map((pluginConfig) => normalizePluginConfig(pluginConfig, context.siteConfigPath, pluginRequire)));
41
100
  }
42
101
  exports.loadPluginConfigs = loadPluginConfigs;
@@ -5,6 +5,10 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { LoadContext, RouteConfig, GlobalData, ThemeConfig, LoadedPlugin } from '@docusaurus/types';
8
+ /**
9
+ * Initializes the plugins, runs `loadContent`, `translateContent`,
10
+ * `contentLoaded`, and `translateThemeConfig`.
11
+ */
8
12
  export declare function loadPlugins(context: LoadContext): Promise<{
9
13
  plugins: LoadedPlugin[];
10
14
  pluginsRouteConfigs: RouteConfig[];