@docusaurus/core 0.0.0-5872 → 0.0.0-5878

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.
@@ -41,17 +41,13 @@ forceTerminate = true) {
41
41
  ['SIGINT', 'SIGTERM'].forEach((sig) => {
42
42
  process.on(sig, () => process.exit());
43
43
  });
44
- async function tryToBuildLocale({ locale, isLastLocale, }) {
44
+ async function tryToBuildLocale({ locale }) {
45
45
  try {
46
- utils_3.PerfLogger.start(`Building site for locale ${locale}`);
47
- await buildLocale({
46
+ await utils_3.PerfLogger.async(`${logger_1.default.name(locale)}`, () => buildLocale({
48
47
  siteDir,
49
48
  locale,
50
49
  cliOptions,
51
- forceTerminate,
52
- isLastLocale,
53
- });
54
- utils_3.PerfLogger.end(`Building site for locale ${locale}`);
50
+ }));
55
51
  }
56
52
  catch (err) {
57
53
  throw new Error(logger_1.default.interpolate `Unable to build website for locale name=${locale}.`, {
@@ -59,18 +55,21 @@ forceTerminate = true) {
59
55
  });
60
56
  }
61
57
  }
62
- utils_3.PerfLogger.start(`Get locales to build`);
63
- const locales = await getLocalesToBuild({ siteDir, cliOptions });
64
- utils_3.PerfLogger.end(`Get locales to build`);
58
+ const locales = await utils_3.PerfLogger.async('Get locales to build', () => getLocalesToBuild({ siteDir, cliOptions }));
65
59
  if (locales.length > 1) {
66
60
  logger_1.default.info `Website will be built for all these locales: ${locales}`;
67
61
  }
68
- utils_3.PerfLogger.start(`Building ${locales.length} locales`);
69
- await (0, utils_1.mapAsyncSequential)(locales, (locale) => {
62
+ await utils_3.PerfLogger.async(`Build`, () => (0, utils_1.mapAsyncSequential)(locales, async (locale) => {
70
63
  const isLastLocale = locales.indexOf(locale) === locales.length - 1;
71
- return tryToBuildLocale({ locale, isLastLocale });
72
- });
73
- utils_3.PerfLogger.end(`Building ${locales.length} locales`);
64
+ await tryToBuildLocale({ locale });
65
+ if (isLastLocale) {
66
+ logger_1.default.info `Use code=${'npm run serve'} command to test your build locally.`;
67
+ }
68
+ // TODO do we really need this historical forceTerminate exit???
69
+ if (forceTerminate && isLastLocale && !cliOptions.bundleAnalyzer) {
70
+ process.exit(0);
71
+ }
72
+ }));
74
73
  }
75
74
  exports.build = build;
76
75
  async function getLocalesToBuild({ siteDir, cliOptions, }) {
@@ -97,26 +96,23 @@ async function getLocalesToBuild({ siteDir, cliOptions, }) {
97
96
  ...i18n.locales.filter((locale) => locale !== i18n.defaultLocale),
98
97
  ];
99
98
  }
100
- async function buildLocale({ siteDir, locale, cliOptions, forceTerminate, isLastLocale, }) {
99
+ async function buildLocale({ siteDir, locale, cliOptions, }) {
101
100
  // Temporary workaround to unlock the ability to translate the site config
102
101
  // We'll remove it if a better official API can be designed
103
102
  // See https://github.com/facebook/docusaurus/issues/4542
104
103
  process.env.DOCUSAURUS_CURRENT_LOCALE = locale;
105
104
  logger_1.default.info `name=${`[${locale}]`} Creating an optimized production build...`;
106
- utils_3.PerfLogger.start('Loading site');
107
- const site = await (0, site_1.loadSite)({
105
+ const site = await utils_3.PerfLogger.async('Load site', () => (0, site_1.loadSite)({
108
106
  siteDir,
109
107
  outDir: cliOptions.outDir,
110
108
  config: cliOptions.config,
111
109
  locale,
112
110
  localizePath: cliOptions.locale ? false : undefined,
113
- });
114
- utils_3.PerfLogger.end('Loading site');
111
+ }));
115
112
  const { props } = site;
116
113
  const { outDir, plugins } = props;
117
114
  // We can build the 2 configs in parallel
118
- utils_3.PerfLogger.start('Creating webpack configs');
119
- const [{ clientConfig, clientManifestPath }, { serverConfig, serverBundlePath }] = await Promise.all([
115
+ const [{ clientConfig, clientManifestPath }, { serverConfig, serverBundlePath }] = await utils_3.PerfLogger.async('Creating webpack configs', () => Promise.all([
120
116
  getBuildClientConfig({
121
117
  props,
122
118
  cliOptions,
@@ -124,60 +120,30 @@ async function buildLocale({ siteDir, locale, cliOptions, forceTerminate, isLast
124
120
  getBuildServerConfig({
125
121
  props,
126
122
  }),
127
- ]);
128
- utils_3.PerfLogger.end('Creating webpack configs');
129
- // Make sure generated client-manifest is cleaned first, so we don't reuse
130
- // the one from previous builds.
131
- // TODO do we really need this? .docusaurus folder is cleaned between builds
132
- utils_3.PerfLogger.start('Deleting previous client manifest');
133
- await ensureUnlink(clientManifestPath);
134
- utils_3.PerfLogger.end('Deleting previous client manifest');
123
+ ]));
135
124
  // Run webpack to build JS bundle (client) and static html files (server).
136
- utils_3.PerfLogger.start('Bundling');
137
- await (0, utils_2.compile)([clientConfig, serverConfig]);
138
- utils_3.PerfLogger.end('Bundling');
139
- utils_3.PerfLogger.start('Executing static site generation');
140
- const { collectedData } = await executeSSG({
125
+ await utils_3.PerfLogger.async('Bundling with Webpack', () => (0, utils_2.compile)([clientConfig, serverConfig]));
126
+ const { collectedData } = await utils_3.PerfLogger.async('SSG', () => executeSSG({
141
127
  props,
142
128
  serverBundlePath,
143
129
  clientManifestPath,
144
- });
145
- utils_3.PerfLogger.end('Executing static site generation');
130
+ }));
146
131
  // Remove server.bundle.js because it is not needed.
147
- utils_3.PerfLogger.start('Deleting server bundle');
148
- await ensureUnlink(serverBundlePath);
149
- utils_3.PerfLogger.end('Deleting server bundle');
132
+ await utils_3.PerfLogger.async('Deleting server bundle', () => ensureUnlink(serverBundlePath));
150
133
  // Plugin Lifecycle - postBuild.
151
- utils_3.PerfLogger.start('Executing postBuild()');
152
- await executePluginsPostBuild({ plugins, props, collectedData });
153
- utils_3.PerfLogger.end('Executing postBuild()');
134
+ await utils_3.PerfLogger.async('postBuild()', () => executePluginsPostBuild({ plugins, props, collectedData }));
154
135
  // TODO execute this in parallel to postBuild?
155
- utils_3.PerfLogger.start('Executing broken links checker');
156
- await executeBrokenLinksCheck({ props, collectedData });
157
- utils_3.PerfLogger.end('Executing broken links checker');
136
+ await utils_3.PerfLogger.async('Broken links checker', () => executeBrokenLinksCheck({ props, collectedData }));
158
137
  logger_1.default.success `Generated static files in path=${path_1.default.relative(process.cwd(), outDir)}.`;
159
- if (isLastLocale) {
160
- logger_1.default.info `Use code=${'npm run serve'} command to test your build locally.`;
161
- }
162
- if (forceTerminate && isLastLocale && !cliOptions.bundleAnalyzer) {
163
- process.exit(0);
164
- }
165
138
  return outDir;
166
139
  }
167
140
  async function executeSSG({ props, serverBundlePath, clientManifestPath, }) {
168
- utils_3.PerfLogger.start('Reading client manifest');
169
- const manifest = await fs_extra_1.default.readJSON(clientManifestPath, 'utf-8');
170
- utils_3.PerfLogger.end('Reading client manifest');
171
- utils_3.PerfLogger.start('Compiling SSR template');
172
- const ssrTemplate = await (0, templates_1.compileSSRTemplate)(props.siteConfig.ssrTemplate ?? ssr_html_template_1.default);
173
- utils_3.PerfLogger.end('Compiling SSR template');
174
- utils_3.PerfLogger.start('Loading App renderer');
175
- const renderer = await (0, ssg_1.loadAppRenderer)({
141
+ const manifest = await utils_3.PerfLogger.async('Read client manifest', () => fs_extra_1.default.readJSON(clientManifestPath, 'utf-8'));
142
+ const ssrTemplate = await utils_3.PerfLogger.async('Compile SSR template', () => (0, templates_1.compileSSRTemplate)(props.siteConfig.ssrTemplate ?? ssr_html_template_1.default));
143
+ const renderer = await utils_3.PerfLogger.async('Load App renderer', () => (0, ssg_1.loadAppRenderer)({
176
144
  serverBundlePath,
177
- });
178
- utils_3.PerfLogger.end('Loading App renderer');
179
- utils_3.PerfLogger.start('Generate static files');
180
- const ssgResult = await (0, ssg_1.generateStaticFiles)({
145
+ }));
146
+ const ssgResult = await utils_3.PerfLogger.async('Generate static files', () => (0, ssg_1.generateStaticFiles)({
181
147
  pathnames: props.routesPaths,
182
148
  renderer,
183
149
  params: {
@@ -192,8 +158,7 @@ async function executeSSG({ props, serverBundlePath, clientManifestPath, }) {
192
158
  noIndex: props.siteConfig.noIndex,
193
159
  DOCUSAURUS_VERSION: utils_1.DOCUSAURUS_VERSION,
194
160
  },
195
- });
196
- utils_3.PerfLogger.end('Generate static files');
161
+ }));
197
162
  return ssgResult;
198
163
  }
199
164
  async function executePluginsPostBuild({ plugins, props, collectedData, }) {
@@ -16,6 +16,7 @@ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
16
16
  const getHostPort_1 = require("../../server/getHostPort");
17
17
  const utils_2 = require("../../utils");
18
18
  const site_1 = require("../../server/site");
19
+ const pluginsUtils_1 = require("../../server/plugins/pluginsUtils");
19
20
  async function createOpenUrlContext({ cliOptions, }) {
20
21
  const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
21
22
  const { host, port } = await (0, getHostPort_1.getHostPort)(cliOptions);
@@ -41,10 +42,8 @@ async function createLoadSiteParams({ siteDirParam, cliOptions, }) {
41
42
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
42
43
  async function createReloadableSite(startParams) {
43
44
  const openUrlContext = await createOpenUrlContext(startParams);
44
- let site = await utils_2.PerfLogger.async('Loading site', async () => {
45
- const params = await createLoadSiteParams(startParams);
46
- return (0, site_1.loadSite)(params);
47
- });
45
+ const loadSiteParams = await utils_2.PerfLogger.async('createLoadSiteParams', () => createLoadSiteParams(startParams));
46
+ let site = await utils_2.PerfLogger.async('Load site', () => (0, site_1.loadSite)(loadSiteParams));
48
47
  const get = () => site;
49
48
  const getOpenUrl = () => openUrlContext.getOpenUrl({
50
49
  baseUrl: site.props.baseUrl,
@@ -56,7 +55,7 @@ async function createReloadableSite(startParams) {
56
55
  const reloadBase = async () => {
57
56
  try {
58
57
  const oldSite = site;
59
- site = await utils_2.PerfLogger.async('Reloading site', () => (0, site_1.reloadSite)(site));
58
+ site = await utils_2.PerfLogger.async('Reload site', () => (0, site_1.reloadSite)(site));
60
59
  if (oldSite.props.baseUrl !== site.props.baseUrl) {
61
60
  printOpenUrlMessage();
62
61
  }
@@ -73,13 +72,13 @@ async function createReloadableSite(startParams) {
73
72
  // but we should still support it and probably use a task queuing system
74
73
  const reloadPlugin = async (plugin) => {
75
74
  try {
76
- site = await utils_2.PerfLogger.async(`Reloading site plugin ${plugin.name}@${plugin.options.id}`, () => {
75
+ site = await utils_2.PerfLogger.async(`Reload site plugin ${(0, pluginsUtils_1.formatPluginName)(plugin)}`, () => {
77
76
  const pluginIdentifier = { name: plugin.name, id: plugin.options.id };
78
77
  return (0, site_1.reloadSitePlugin)(site, pluginIdentifier);
79
78
  });
80
79
  }
81
80
  catch (e) {
82
- logger_1.default.error(`Site plugin reload failure - Plugin ${plugin.name}@${plugin.options.id}`);
81
+ logger_1.default.error(`Site plugin reload failure - Plugin ${(0, pluginsUtils_1.formatPluginName)(plugin)}`);
83
82
  console.error(e);
84
83
  }
85
84
  };
@@ -72,7 +72,7 @@ Available locales are: ${context.i18n.locales.join(',')}.`);
72
72
  babelOptions: await (0, utils_1.getCustomBabelConfigFilePath)(siteDir),
73
73
  });
74
74
  const extractedCodeTranslations = await (0, translationsExtractor_1.extractSiteSourceCodeTranslations)(siteDir, plugins, babelOptions, await getExtraSourceCodeFilePaths());
75
- const defaultCodeMessages = await (0, translations_1.getPluginsDefaultCodeTranslationMessages)(plugins);
75
+ const defaultCodeMessages = await (0, translations_1.loadPluginsDefaultCodeTranslationMessages)(plugins);
76
76
  const codeTranslations = (0, translations_1.applyDefaultCodeTranslations)({
77
77
  extractedCodeTranslations,
78
78
  defaultCodeMessages,
@@ -9,4 +9,4 @@ import type { LoadedPlugin } from '@docusaurus/types';
9
9
  * Runs the `getClientModules` lifecycle. The returned file paths are all
10
10
  * absolute.
11
11
  */
12
- export declare function loadClientModules(plugins: LoadedPlugin[]): string[];
12
+ export declare function getAllClientModules(plugins: LoadedPlugin[]): string[];
@@ -6,15 +6,15 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.loadClientModules = void 0;
9
+ exports.getAllClientModules = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const path_1 = tslib_1.__importDefault(require("path"));
12
12
  /**
13
13
  * Runs the `getClientModules` lifecycle. The returned file paths are all
14
14
  * absolute.
15
15
  */
16
- function loadClientModules(plugins) {
16
+ function getAllClientModules(plugins) {
17
17
  return plugins.flatMap((plugin) => plugin.getClientModules?.().map((p) => path_1.default.resolve(plugin.path, p)) ??
18
18
  []);
19
19
  }
20
- exports.loadClientModules = loadClientModules;
20
+ exports.getAllClientModules = getAllClientModules;
@@ -24,6 +24,7 @@ async function createPluginActionsUtils({ plugin, generatedFilesDir, baseUrl, tr
24
24
  id: pluginId,
25
25
  };
26
26
  const pluginRouteContextModulePath = path_1.default.join(dataDir, `${(0, utils_1.docuHash)('pluginRouteContextModule')}.json`);
27
+ // TODO not ideal place to generate that file
27
28
  await (0, utils_1.generate)('/', pluginRouteContextModulePath, JSON.stringify(pluginRouteContext, null, 2));
28
29
  const routes = [];
29
30
  let globalData;
@@ -40,10 +40,10 @@ async function initPlugins(context) {
40
40
  // we are using `require.resolve` on those module names.
41
41
  const pluginRequire = (0, module_1.createRequire)(context.siteConfigPath);
42
42
  const pluginConfigs = await (0, configs_1.loadPluginConfigs)(context);
43
- async function doGetPluginVersion(normalizedPluginConfig) {
43
+ async function doLoadPluginVersion(normalizedPluginConfig) {
44
44
  if (normalizedPluginConfig.pluginModule?.path) {
45
45
  const pluginPath = pluginRequire.resolve(normalizedPluginConfig.pluginModule.path);
46
- return (0, siteMetadata_1.getPluginVersion)(pluginPath, context.siteDir);
46
+ return (0, siteMetadata_1.loadPluginVersion)(pluginPath, context.siteDir);
47
47
  }
48
48
  return { type: 'local' };
49
49
  }
@@ -73,7 +73,7 @@ async function initPlugins(context) {
73
73
  };
74
74
  }
75
75
  async function initializePlugin(normalizedPluginConfig) {
76
- const pluginVersion = await doGetPluginVersion(normalizedPluginConfig);
76
+ const pluginVersion = await doLoadPluginVersion(normalizedPluginConfig);
77
77
  const pluginOptions = doValidatePluginOptions(normalizedPluginConfig);
78
78
  // Side-effect: merge the normalized theme config in the original one
79
79
  context.siteConfig.themeConfig = {
@@ -34,17 +34,19 @@ async function translatePluginContent({ plugin, content, context, }) {
34
34
  return translatedContent;
35
35
  }
36
36
  async function executePluginContentLoading({ plugin, context, }) {
37
- return utils_1.PerfLogger.async(`Plugins - single plugin content loading - ${plugin.name}@${plugin.options.id}`, async () => {
38
- let content = await plugin.loadContent?.();
39
- content = await translatePluginContent({
37
+ return utils_1.PerfLogger.async(`Load ${(0, pluginsUtils_1.formatPluginName)(plugin)}`, async () => {
38
+ let content = await utils_1.PerfLogger.async('loadContent()', () => plugin.loadContent?.());
39
+ content = await utils_1.PerfLogger.async('translatePluginContent()', () => translatePluginContent({
40
40
  plugin,
41
41
  content,
42
42
  context,
43
- });
43
+ }));
44
+ const defaultCodeTranslations = (await utils_1.PerfLogger.async('getDefaultCodeTranslationMessages()', () => plugin.getDefaultCodeTranslationMessages?.())) ?? {};
44
45
  if (!plugin.contentLoaded) {
45
46
  return {
46
47
  ...plugin,
47
48
  content,
49
+ defaultCodeTranslations,
48
50
  routes: [],
49
51
  globalData: undefined,
50
52
  };
@@ -55,25 +57,28 @@ async function executePluginContentLoading({ plugin, context, }) {
55
57
  baseUrl: context.siteConfig.baseUrl,
56
58
  trailingSlash: context.siteConfig.trailingSlash,
57
59
  });
58
- await plugin.contentLoaded({
60
+ await utils_1.PerfLogger.async('contentLoaded()', () =>
61
+ // @ts-expect-error: should autofix with TS 5.4
62
+ plugin.contentLoaded({
59
63
  content,
60
64
  actions: pluginActionsUtils.getActions(),
61
- });
65
+ }));
62
66
  return {
63
67
  ...plugin,
64
68
  content,
69
+ defaultCodeTranslations,
65
70
  routes: pluginActionsUtils.getRoutes(),
66
71
  globalData: pluginActionsUtils.getGlobalData(),
67
72
  };
68
73
  });
69
74
  }
70
75
  async function executeAllPluginsContentLoading({ plugins, context, }) {
71
- return utils_1.PerfLogger.async(`Plugins - all plugins content loading`, () => {
76
+ return utils_1.PerfLogger.async(`Load plugins content`, () => {
72
77
  return Promise.all(plugins.map((plugin) => executePluginContentLoading({ plugin, context })));
73
78
  });
74
79
  }
75
80
  async function executePluginAllContentLoaded({ plugin, context, allContent, }) {
76
- return utils_1.PerfLogger.async(`Plugins - allContentLoaded - ${plugin.name}@${plugin.options.id}`, async () => {
81
+ return utils_1.PerfLogger.async(`allContentLoaded() - ${(0, pluginsUtils_1.formatPluginName)(plugin)}`, async () => {
77
82
  if (!plugin.allContentLoaded) {
78
83
  return { routes: [], globalData: undefined };
79
84
  }
@@ -94,7 +99,7 @@ async function executePluginAllContentLoaded({ plugin, context, allContent, }) {
94
99
  });
95
100
  }
96
101
  async function executeAllPluginsAllContentLoaded({ plugins, context, }) {
97
- return utils_1.PerfLogger.async(`Plugins - allContentLoaded`, async () => {
102
+ return utils_1.PerfLogger.async(`allContentLoaded()`, async () => {
98
103
  const allContent = (0, pluginsUtils_1.aggregateAllContent)(plugins);
99
104
  const routes = [];
100
105
  const globalData = {};
@@ -114,6 +119,9 @@ async function executeAllPluginsAllContentLoaded({ plugins, context, }) {
114
119
  return { routes, globalData };
115
120
  });
116
121
  }
122
+ // This merges plugins routes and global data created from both lifecycles:
123
+ // - contentLoaded()
124
+ // - allContentLoaded()
117
125
  function mergeResults({ plugins, allContentLoadedResult, }) {
118
126
  const routes = [
119
127
  ...(0, pluginsUtils_1.aggregateRoutes)(plugins),
@@ -127,8 +135,8 @@ function mergeResults({ plugins, allContentLoadedResult, }) {
127
135
  * Initializes the plugins and run their lifecycle functions.
128
136
  */
129
137
  async function loadPlugins(context) {
130
- return utils_1.PerfLogger.async('Plugins - loadPlugins', async () => {
131
- const initializedPlugins = await utils_1.PerfLogger.async('Plugins - initPlugins', () => (0, init_1.initPlugins)(context));
138
+ return utils_1.PerfLogger.async('Load plugins', async () => {
139
+ const initializedPlugins = await utils_1.PerfLogger.async('Init plugins', () => (0, init_1.initPlugins)(context));
132
140
  // TODO probably not the ideal place to hardcode those plugins
133
141
  initializedPlugins.push((0, synthetic_1.createBootstrapPlugin)(context), (0, synthetic_1.createMDXFallbackPlugin)(context));
134
142
  const plugins = await executeAllPluginsContentLoading({
@@ -148,7 +156,7 @@ async function loadPlugins(context) {
148
156
  }
149
157
  exports.loadPlugins = loadPlugins;
150
158
  async function reloadPlugin({ pluginIdentifier, plugins: previousPlugins, context, }) {
151
- return utils_1.PerfLogger.async('Plugins - reloadPlugin', async () => {
159
+ return utils_1.PerfLogger.async(`Reload plugin ${(0, pluginsUtils_1.formatPluginName)(pluginIdentifier)}`, async () => {
152
160
  const previousPlugin = (0, pluginsUtils_1.getPluginByIdentifier)({
153
161
  plugins: previousPlugins,
154
162
  pluginIdentifier,
@@ -158,12 +166,12 @@ async function reloadPlugin({ pluginIdentifier, plugins: previousPlugins, contex
158
166
  context,
159
167
  });
160
168
  /*
161
- // TODO Docusaurus v4 - upgrade to Node 20, use array.with()
162
- const plugins = previousPlugins.with(
163
- previousPlugins.indexOf(previousPlugin),
164
- plugin,
165
- );
166
- */
169
+ // TODO Docusaurus v4 - upgrade to Node 20, use array.with()
170
+ const plugins = previousPlugins.with(
171
+ previousPlugins.indexOf(previousPlugin),
172
+ plugin,
173
+ );
174
+ */
167
175
  const plugins = [...previousPlugins];
168
176
  plugins[previousPlugins.indexOf(previousPlugin)] = plugin;
169
177
  const allContentLoadedResult = await executeAllPluginsAllContentLoaded({
@@ -13,3 +13,4 @@ export declare function aggregateAllContent(loadedPlugins: LoadedPlugin[]): AllC
13
13
  export declare function aggregateRoutes(loadedPlugins: LoadedPlugin[]): RouteConfig[];
14
14
  export declare function aggregateGlobalData(loadedPlugins: LoadedPlugin[]): GlobalData;
15
15
  export declare function mergeGlobalData(...globalDataList: GlobalData[]): GlobalData;
16
+ export declare function formatPluginName(plugin: InitializedPlugin | PluginIdentifier): string;
@@ -6,14 +6,14 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.mergeGlobalData = exports.aggregateGlobalData = exports.aggregateRoutes = exports.aggregateAllContent = exports.getPluginByIdentifier = void 0;
9
+ exports.formatPluginName = exports.mergeGlobalData = exports.aggregateGlobalData = exports.aggregateRoutes = exports.aggregateAllContent = exports.getPluginByIdentifier = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const lodash_1 = tslib_1.__importDefault(require("lodash"));
12
12
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
13
13
  function getPluginByIdentifier({ plugins, pluginIdentifier, }) {
14
14
  const plugin = plugins.find((p) => p.name === pluginIdentifier.name && p.options.id === pluginIdentifier.id);
15
15
  if (!plugin) {
16
- throw new Error(logger_1.default.interpolate `Plugin not found for identifier ${pluginIdentifier.name}@${pluginIdentifier.id}`);
16
+ throw new Error(logger_1.default.interpolate `Plugin not found for identifier ${formatPluginName(pluginIdentifier)}`);
17
17
  }
18
18
  return plugin;
19
19
  }
@@ -58,3 +58,18 @@ function mergeGlobalData(...globalDataList) {
58
58
  return result;
59
59
  }
60
60
  exports.mergeGlobalData = mergeGlobalData;
61
+ // This is primarily useful for colored logging purpose
62
+ // Do not rely on this for logic
63
+ function formatPluginName(plugin) {
64
+ let formattedName = plugin.name;
65
+ // Hacky way to reduce string size for logging purpose
66
+ formattedName = formattedName.replace('docusaurus-plugin-content-', '');
67
+ formattedName = formattedName.replace('docusaurus-plugin-', '');
68
+ formattedName = formattedName.replace('docusaurus-theme-', '');
69
+ formattedName = formattedName.replace('-plugin', '');
70
+ formattedName = logger_1.default.name(formattedName);
71
+ const id = 'id' in plugin ? plugin.id : plugin.options.id;
72
+ const formattedId = logger_1.default.subdue(id);
73
+ return `${formattedName}@${formattedId}`;
74
+ }
75
+ exports.formatPluginName = formatPluginName;
@@ -30,9 +30,12 @@ const routes_1 = require("./routes");
30
30
  async function loadContext(params) {
31
31
  const { siteDir, outDir: baseOutDir = utils_1.DEFAULT_BUILD_DIR_NAME, locale, config: customConfigFilePath, } = params;
32
32
  const generatedFilesDir = path_1.default.resolve(siteDir, utils_1.GENERATED_FILES_DIR_NAME);
33
- const { siteConfig: initialSiteConfig, siteConfigPath } = await (0, config_1.loadSiteConfig)({
34
- siteDir,
35
- customConfigFilePath,
33
+ const { siteVersion, loadSiteConfig: { siteConfig: initialSiteConfig, siteConfigPath }, } = await (0, combine_promises_1.default)({
34
+ siteVersion: (0, siteMetadata_1.loadSiteVersion)(siteDir),
35
+ loadSiteConfig: (0, config_1.loadSiteConfig)({
36
+ siteDir,
37
+ customConfigFilePath,
38
+ }),
36
39
  });
37
40
  const i18n = await (0, i18n_1.loadI18n)(initialSiteConfig, { locale });
38
41
  const baseUrl = (0, utils_1.localizePath)({
@@ -52,6 +55,7 @@ async function loadContext(params) {
52
55
  const codeTranslations = await (0, translations_1.loadSiteCodeTranslations)({ localizationDir });
53
56
  return {
54
57
  siteDir,
58
+ siteVersion,
55
59
  generatedFilesDir,
56
60
  localizationDir,
57
61
  siteConfig,
@@ -63,24 +67,22 @@ async function loadContext(params) {
63
67
  };
64
68
  }
65
69
  exports.loadContext = loadContext;
66
- async function createSiteProps(params) {
70
+ function createSiteProps(params) {
67
71
  const { plugins, routes, context } = params;
68
- const { generatedFilesDir, siteDir, siteConfig, siteConfigPath, outDir, baseUrl, i18n, localizationDir, codeTranslations: siteCodeTranslations, } = context;
72
+ const { generatedFilesDir, siteDir, siteVersion, siteConfig, siteConfigPath, outDir, baseUrl, i18n, localizationDir, codeTranslations: siteCodeTranslations, } = context;
69
73
  const { headTags, preBodyTags, postBodyTags } = (0, htmlTags_1.loadHtmlTags)(plugins);
70
- const { codeTranslations, siteMetadata } = await (0, combine_promises_1.default)({
71
- // TODO code translations should be loaded as part of LoadedPlugin?
72
- codeTranslations: utils_2.PerfLogger.async('Load - loadCodeTranslations', async () => ({
73
- ...(await (0, translations_1.getPluginsDefaultCodeTranslationMessages)(plugins)),
74
- ...siteCodeTranslations,
75
- })),
76
- siteMetadata: utils_2.PerfLogger.async('Load - loadSiteMetadata', () => (0, siteMetadata_1.loadSiteMetadata)({ plugins, siteDir })),
77
- });
74
+ const siteMetadata = (0, siteMetadata_1.createSiteMetadata)({ plugins, siteVersion });
75
+ const codeTranslations = {
76
+ ...(0, translations_1.getPluginsDefaultCodeTranslations)({ plugins }),
77
+ ...siteCodeTranslations,
78
+ };
78
79
  (0, routes_1.handleDuplicateRoutes)(routes, siteConfig.onDuplicateRoutes);
79
80
  const routesPaths = (0, routes_1.getRoutesPaths)(routes, baseUrl);
80
81
  return {
81
82
  siteConfig,
82
83
  siteConfigPath,
83
84
  siteMetadata,
85
+ siteVersion,
84
86
  siteDir,
85
87
  outDir,
86
88
  baseUrl,
@@ -98,9 +100,9 @@ async function createSiteProps(params) {
98
100
  }
99
101
  // TODO global data should be part of site props?
100
102
  async function createSiteFiles({ site, globalData, }) {
101
- return utils_2.PerfLogger.async('Load - createSiteFiles', async () => {
103
+ return utils_2.PerfLogger.async('Create site files', async () => {
102
104
  const { props: { plugins, generatedFilesDir, siteConfig, siteMetadata, i18n, codeTranslations, routes, baseUrl, }, } = site;
103
- const clientModules = (0, clientModules_1.loadClientModules)(plugins);
105
+ const clientModules = (0, clientModules_1.getAllClientModules)(plugins);
104
106
  await (0, codegen_1.generateSiteFiles)({
105
107
  generatedFilesDir,
106
108
  clientModules,
@@ -121,12 +123,8 @@ async function createSiteFiles({ site, globalData, }) {
121
123
  * it generates temp files in the `.docusaurus` folder for the bundler.
122
124
  */
123
125
  async function loadSite(params) {
124
- utils_2.PerfLogger.start('Load - loadContext');
125
- const context = await loadContext(params);
126
- utils_2.PerfLogger.end('Load - loadContext');
127
- utils_2.PerfLogger.start('Load - loadPlugins');
126
+ const context = await utils_2.PerfLogger.async('Load context', () => loadContext(params));
128
127
  const { plugins, routes, globalData } = await (0, plugins_1.loadPlugins)(context);
129
- utils_2.PerfLogger.end('Load - loadPlugins');
130
128
  const props = await createSiteProps({ plugins, routes, globalData, context });
131
129
  const site = { props, params };
132
130
  await createSiteFiles({
@@ -5,8 +5,9 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { LoadedPlugin, PluginVersionInformation, SiteMetadata } from '@docusaurus/types';
8
- export declare function getPluginVersion(pluginPath: string, siteDir: string): Promise<PluginVersionInformation>;
9
- export declare function loadSiteMetadata({ plugins, siteDir, }: {
8
+ export declare function loadSiteVersion(siteDir: string): Promise<string | undefined>;
9
+ export declare function loadPluginVersion(pluginPath: string, siteDir: string): Promise<PluginVersionInformation>;
10
+ export declare function createSiteMetadata({ siteVersion, plugins, }: {
11
+ siteVersion: string | undefined;
10
12
  plugins: LoadedPlugin[];
11
- siteDir: string;
12
- }): Promise<SiteMetadata>;
13
+ }): SiteMetadata;
@@ -6,23 +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.loadSiteMetadata = exports.getPluginVersion = void 0;
9
+ exports.createSiteMetadata = exports.loadPluginVersion = exports.loadSiteVersion = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const path_1 = tslib_1.__importDefault(require("path"));
13
13
  const utils_1 = require("@docusaurus/utils");
14
- async function getPackageJsonVersion(packageJsonPath) {
14
+ async function loadPackageJsonVersion(packageJsonPath) {
15
15
  if (await fs_extra_1.default.pathExists(packageJsonPath)) {
16
16
  // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require
17
17
  return require(packageJsonPath).version;
18
18
  }
19
19
  return undefined;
20
20
  }
21
- async function getPackageJsonName(packageJsonPath) {
21
+ async function loadPackageJsonName(packageJsonPath) {
22
22
  // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require
23
23
  return require(packageJsonPath).name;
24
24
  }
25
- async function getPluginVersion(pluginPath, siteDir) {
25
+ async function loadSiteVersion(siteDir) {
26
+ return loadPackageJsonVersion(path_1.default.join(siteDir, 'package.json'));
27
+ }
28
+ exports.loadSiteVersion = loadSiteVersion;
29
+ async function loadPluginVersion(pluginPath, siteDir) {
26
30
  let potentialPluginPackageJsonDirectory = path_1.default.dirname(pluginPath);
27
31
  while (potentialPluginPackageJsonDirectory !== '/') {
28
32
  const packageJsonPath = path_1.default.join(potentialPluginPackageJsonDirectory, 'package.json');
@@ -35,8 +39,8 @@ async function getPluginVersion(pluginPath, siteDir) {
35
39
  }
36
40
  return {
37
41
  type: 'package',
38
- name: await getPackageJsonName(packageJsonPath),
39
- version: await getPackageJsonVersion(packageJsonPath),
42
+ name: await loadPackageJsonName(packageJsonPath),
43
+ version: await loadPackageJsonVersion(packageJsonPath),
40
44
  };
41
45
  }
42
46
  potentialPluginPackageJsonDirectory = path_1.default.dirname(potentialPluginPackageJsonDirectory);
@@ -46,7 +50,7 @@ async function getPluginVersion(pluginPath, siteDir) {
46
50
  // script in the parent directory of the site.
47
51
  return { type: 'local' };
48
52
  }
49
- exports.getPluginVersion = getPluginVersion;
53
+ exports.loadPluginVersion = loadPluginVersion;
50
54
  /**
51
55
  * We want all `@docusaurus/*` packages to have the exact same version!
52
56
  * @see https://github.com/facebook/docusaurus/issues/3371
@@ -65,10 +69,10 @@ Maybe you want to check, or regenerate your yarn.lock or package-lock.json file?
65
69
  }
66
70
  });
67
71
  }
68
- async function loadSiteMetadata({ plugins, siteDir, }) {
72
+ function createSiteMetadata({ siteVersion, plugins, }) {
69
73
  const siteMetadata = {
70
74
  docusaurusVersion: utils_1.DOCUSAURUS_VERSION,
71
- siteVersion: await getPackageJsonVersion(path_1.default.join(siteDir, 'package.json')),
75
+ siteVersion,
72
76
  pluginVersions: Object.fromEntries(plugins
73
77
  .filter(({ version: { type } }) => type !== 'synthetic')
74
78
  .map(({ name, version }) => [name, version])),
@@ -76,4 +80,4 @@ async function loadSiteMetadata({ plugins, siteDir, }) {
76
80
  checkDocusaurusPackagesVersion(siteMetadata);
77
81
  return siteMetadata;
78
82
  }
79
- exports.loadSiteMetadata = loadSiteMetadata;
83
+ exports.createSiteMetadata = createSiteMetadata;
@@ -4,7 +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 { TranslationFileContent, TranslationFile, CodeTranslations, InitializedPlugin } from '@docusaurus/types';
7
+ import type { TranslationFileContent, TranslationFile, CodeTranslations, InitializedPlugin, LoadedPlugin } from '@docusaurus/types';
8
8
  export type WriteTranslationsOptions = {
9
9
  override?: boolean;
10
10
  messagePrefix?: string;
@@ -23,7 +23,11 @@ export declare function localizePluginTranslationFile({ localizationDir, plugin,
23
23
  plugin: InitializedPlugin;
24
24
  translationFile: TranslationFile;
25
25
  }): Promise<TranslationFile>;
26
- export declare function getPluginsDefaultCodeTranslationMessages(plugins: InitializedPlugin[]): Promise<CodeTranslations>;
26
+ export declare function mergeCodeTranslations(codeTranslations: CodeTranslations[]): CodeTranslations;
27
+ export declare function loadPluginsDefaultCodeTranslationMessages(plugins: InitializedPlugin[]): Promise<CodeTranslations>;
28
+ export declare function getPluginsDefaultCodeTranslations({ plugins, }: {
29
+ plugins: LoadedPlugin[];
30
+ }): CodeTranslations;
27
31
  export declare function applyDefaultCodeTranslations({ extractedCodeTranslations, defaultCodeMessages, }: {
28
32
  extractedCodeTranslations: TranslationFileContent;
29
33
  defaultCodeMessages: CodeTranslations;
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.loadSiteCodeTranslations = exports.applyDefaultCodeTranslations = exports.getPluginsDefaultCodeTranslationMessages = exports.localizePluginTranslationFile = exports.writePluginTranslations = exports.writeCodeTranslations = exports.readCodeTranslationFileContent = void 0;
9
+ exports.loadSiteCodeTranslations = exports.applyDefaultCodeTranslations = exports.getPluginsDefaultCodeTranslations = exports.loadPluginsDefaultCodeTranslationMessages = exports.mergeCodeTranslations = exports.localizePluginTranslationFile = exports.writePluginTranslations = exports.writeCodeTranslations = exports.readCodeTranslationFileContent = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const path_1 = tslib_1.__importDefault(require("path"));
12
12
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
@@ -145,11 +145,22 @@ async function localizePluginTranslationFile({ localizationDir, plugin, translat
145
145
  return translationFile;
146
146
  }
147
147
  exports.localizePluginTranslationFile = localizePluginTranslationFile;
148
- async function getPluginsDefaultCodeTranslationMessages(plugins) {
148
+ function mergeCodeTranslations(codeTranslations) {
149
+ return codeTranslations.reduce((allCodeTranslations, current) => ({
150
+ ...allCodeTranslations,
151
+ ...current,
152
+ }), {});
153
+ }
154
+ exports.mergeCodeTranslations = mergeCodeTranslations;
155
+ async function loadPluginsDefaultCodeTranslationMessages(plugins) {
149
156
  const pluginsMessages = await Promise.all(plugins.map((plugin) => plugin.getDefaultCodeTranslationMessages?.() ?? {}));
150
- return pluginsMessages.reduce((allMessages, pluginMessages) => ({ ...allMessages, ...pluginMessages }), {});
157
+ return mergeCodeTranslations(pluginsMessages);
158
+ }
159
+ exports.loadPluginsDefaultCodeTranslationMessages = loadPluginsDefaultCodeTranslationMessages;
160
+ function getPluginsDefaultCodeTranslations({ plugins, }) {
161
+ return mergeCodeTranslations(plugins.map((p) => p.defaultCodeTranslations));
151
162
  }
152
- exports.getPluginsDefaultCodeTranslationMessages = getPluginsDefaultCodeTranslationMessages;
163
+ exports.getPluginsDefaultCodeTranslations = getPluginsDefaultCodeTranslations;
153
164
  function applyDefaultCodeTranslations({ extractedCodeTranslations, defaultCodeMessages, }) {
154
165
  const unusedDefaultCodeMessages = lodash_1.default.difference(Object.keys(defaultCodeMessages), Object.keys(extractedCodeTranslations));
155
166
  if (unusedDefaultCodeMessages.length > 0) {
package/lib/ssg.js CHANGED
@@ -27,11 +27,8 @@ const Concurrency = process.env.DOCUSAURUS_SSR_CONCURRENCY
27
27
  // See also https://github.com/sindresorhus/p-map/issues/24
28
28
  32;
29
29
  async function loadAppRenderer({ serverBundlePath, }) {
30
- console.log(`SSG - Load server bundle`);
31
- utils_1.PerfLogger.start(`SSG - Load server bundle`);
32
- const source = await fs_extra_1.default.readFile(serverBundlePath);
33
- utils_1.PerfLogger.end(`SSG - Load server bundle`);
34
- utils_1.PerfLogger.log(`SSG - Server bundle size = ${(source.length / 1024000).toFixed(3)} MB`);
30
+ const source = await utils_1.PerfLogger.async(`Load server bundle`, () => fs_extra_1.default.readFile(serverBundlePath));
31
+ utils_1.PerfLogger.log(`Server bundle size = ${(source.length / 1024000).toFixed(3)} MB`);
35
32
  const filename = path_1.default.basename(serverBundlePath);
36
33
  const globals = {
37
34
  // When using "new URL('file.js', import.meta.url)", Webpack will emit
@@ -43,12 +40,10 @@ async function loadAppRenderer({ serverBundlePath, }) {
43
40
  // See also: https://github.com/pierrec/node-eval/issues/33
44
41
  require: (0, module_1.createRequire)(serverBundlePath),
45
42
  };
46
- utils_1.PerfLogger.start(`SSG - Evaluate server bundle`);
47
- const serverEntry = (0, eval_1.default)(source,
43
+ const serverEntry = await utils_1.PerfLogger.async(`Evaluate server bundle`, () => (0, eval_1.default)(source,
48
44
  /* filename: */ filename,
49
45
  /* scope: */ globals,
50
- /* includeGlobals: */ true);
51
- utils_1.PerfLogger.end(`SSG - Evaluate server bundle`);
46
+ /* includeGlobals: */ true));
52
47
  if (!serverEntry?.default || typeof serverEntry.default !== 'function') {
53
48
  throw new Error(`Server bundle export from "${filename}" must be a function that renders the Docusaurus React app.`);
54
49
  }
package/lib/utils.js CHANGED
@@ -8,6 +8,7 @@ const tslib_1 = require("tslib");
8
8
  * This source code is licensed under the MIT license found in the
9
9
  * LICENSE file in the root directory of this source tree.
10
10
  */
11
+ const async_hooks_1 = require("async_hooks");
11
12
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
12
13
  // For now this is a private env variable we use internally
13
14
  // But we'll want to expose this feature officially some day
@@ -17,6 +18,14 @@ const Thresholds = {
17
18
  yellow: 100,
18
19
  red: 1000,
19
20
  };
21
+ const PerfPrefix = logger_1.default.yellow(`[PERF] `);
22
+ // This is what enables to "see the parent stack" for each log
23
+ // Parent1 > Parent2 > Parent3 > child trace
24
+ const ParentPrefix = new async_hooks_1.AsyncLocalStorage();
25
+ function applyParentPrefix(label) {
26
+ const parentPrefix = ParentPrefix.getStore();
27
+ return parentPrefix ? `${parentPrefix} > ${label}` : label;
28
+ }
20
29
  function createPerfLogger() {
21
30
  if (!exports.PerfDebuggingEnabled) {
22
31
  const noop = () => { };
@@ -27,7 +36,6 @@ function createPerfLogger() {
27
36
  async: async (_label, asyncFn) => asyncFn(),
28
37
  };
29
38
  }
30
- const prefix = logger_1.default.yellow(`[PERF] `);
31
39
  const formatDuration = (duration) => {
32
40
  if (duration > Thresholds.red) {
33
41
  return logger_1.default.red(`${(duration / 1000).toFixed(2)} seconds!`);
@@ -43,21 +51,21 @@ function createPerfLogger() {
43
51
  if (duration < Thresholds.min) {
44
52
  return;
45
53
  }
46
- console.log(`${prefix + label} - ${formatDuration(duration)}`);
54
+ console.log(`${PerfPrefix + label} - ${formatDuration(duration)}`);
47
55
  };
48
56
  const start = (label) => performance.mark(label);
49
57
  const end = (label) => {
50
58
  const { duration } = performance.measure(label);
51
59
  performance.clearMarks(label);
52
- logDuration(label, duration);
60
+ logDuration(applyParentPrefix(label), duration);
53
61
  };
54
- const log = (label) => console.log(prefix + label);
62
+ const log = (label) => console.log(PerfPrefix + applyParentPrefix(label));
55
63
  const async = async (label, asyncFn) => {
56
- start(label);
64
+ const finalLabel = applyParentPrefix(label);
57
65
  const before = performance.now();
58
- const result = await asyncFn();
66
+ const result = await ParentPrefix.run(finalLabel, () => asyncFn());
59
67
  const duration = performance.now() - before;
60
- logDuration(label, duration);
68
+ logDuration(finalLabel, duration);
61
69
  return result;
62
70
  };
63
71
  return {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@docusaurus/core",
3
3
  "description": "Easy to Maintain Open Source Documentation Websites",
4
- "version": "0.0.0-5872",
4
+ "version": "0.0.0-5878",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -43,13 +43,13 @@
43
43
  "@babel/runtime": "^7.22.6",
44
44
  "@babel/runtime-corejs3": "^7.22.6",
45
45
  "@babel/traverse": "^7.22.8",
46
- "@docusaurus/cssnano-preset": "0.0.0-5872",
47
- "@docusaurus/logger": "0.0.0-5872",
48
- "@docusaurus/mdx-loader": "0.0.0-5872",
46
+ "@docusaurus/cssnano-preset": "0.0.0-5878",
47
+ "@docusaurus/logger": "0.0.0-5878",
48
+ "@docusaurus/mdx-loader": "0.0.0-5878",
49
49
  "@docusaurus/react-loadable": "5.5.2",
50
- "@docusaurus/utils": "0.0.0-5872",
51
- "@docusaurus/utils-common": "0.0.0-5872",
52
- "@docusaurus/utils-validation": "0.0.0-5872",
50
+ "@docusaurus/utils": "0.0.0-5878",
51
+ "@docusaurus/utils-common": "0.0.0-5878",
52
+ "@docusaurus/utils-validation": "0.0.0-5878",
53
53
  "@svgr/webpack": "^6.5.1",
54
54
  "autoprefixer": "^10.4.14",
55
55
  "babel-loader": "^9.1.3",
@@ -105,8 +105,8 @@
105
105
  "webpackbar": "^5.0.2"
106
106
  },
107
107
  "devDependencies": {
108
- "@docusaurus/module-type-aliases": "0.0.0-5872",
109
- "@docusaurus/types": "0.0.0-5872",
108
+ "@docusaurus/module-type-aliases": "0.0.0-5878",
109
+ "@docusaurus/types": "0.0.0-5878",
110
110
  "@total-typescript/shoehorn": "^0.1.2",
111
111
  "@types/detect-port": "^1.3.3",
112
112
  "@types/react-dom": "^18.2.7",
@@ -126,5 +126,5 @@
126
126
  "engines": {
127
127
  "node": ">=18.0"
128
128
  },
129
- "gitHead": "b059cfb578e4a80cdd8b5cf9a3c8978fb41693e3"
129
+ "gitHead": "d12884c09795e4d0a536df1840d86a0bcbcd9a99"
130
130
  }