@docusaurus/core 0.0.0-6106 → 0.0.0-6110

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.
@@ -5,57 +5,21 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { renderToPipeableStream } from 'react-dom/server';
8
- import { Writable } from 'stream';
8
+ import { PassThrough } from 'node:stream';
9
+ import { text } from 'node:stream/consumers';
10
+ // See also https://github.com/facebook/react/issues/31134
11
+ // See also https://github.com/facebook/docusaurus/issues/9985#issuecomment-2396367797
9
12
  export async function renderToHtml(app) {
10
- // Inspired from
11
- // https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation
12
- // https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/cache-dir/static-entry.js
13
- const writableStream = new WritableAsPromise();
14
- const { pipe } = renderToPipeableStream(app, {
15
- onError(error) {
16
- writableStream.destroy(error);
17
- },
18
- onAllReady() {
19
- pipe(writableStream);
20
- },
21
- });
22
- return writableStream.getPromise();
23
- }
24
- // WritableAsPromise inspired by https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/cache-dir/server-utils/writable-as-promise.js
25
- /* eslint-disable no-underscore-dangle */
26
- class WritableAsPromise extends Writable {
27
- _output;
28
- _deferred;
29
- constructor() {
30
- super();
31
- this._output = ``;
32
- this._deferred = {
33
- promise: null,
34
- resolve: () => null,
35
- reject: () => null,
36
- };
37
- this._deferred.promise = new Promise((resolve, reject) => {
38
- this._deferred.resolve = resolve;
39
- this._deferred.reject = reject;
13
+ return new Promise((resolve, reject) => {
14
+ const passThrough = new PassThrough();
15
+ const { pipe } = renderToPipeableStream(app, {
16
+ onError(error) {
17
+ reject(error);
18
+ },
19
+ onAllReady() {
20
+ pipe(passThrough);
21
+ text(passThrough).then(resolve, reject);
22
+ },
40
23
  });
41
- }
42
- _write(chunk, _enc, next) {
43
- this._output += chunk.toString();
44
- next();
45
- }
46
- _destroy(error, next) {
47
- if (error instanceof Error) {
48
- this._deferred.reject(error);
49
- }
50
- else {
51
- next();
52
- }
53
- }
54
- end() {
55
- this._deferred.resolve(this._output);
56
- return this.destroy();
57
- }
58
- getPromise() {
59
- return this._deferred.promise;
60
- }
24
+ });
61
25
  }
@@ -31,6 +31,8 @@ const render = async ({ pathname }) => {
31
31
  </Loadable.Capture>);
32
32
  const html = await renderToHtml(app);
33
33
  const collectedData = {
34
+ // TODO Docusaurus v4 refactor: helmet state is non-serializable
35
+ // this makes it impossible to run SSG in a worker thread
34
36
  helmet: helmetContext.helmet,
35
37
  anchors: statefulBrokenLinks.getCollectedAnchors(),
36
38
  links: statefulBrokenLinks.getCollectedLinks(),
@@ -20,9 +20,7 @@ const client_1 = require("../webpack/client");
20
20
  const server_1 = tslib_1.__importDefault(require("../webpack/server"));
21
21
  const configure_1 = require("../webpack/configure");
22
22
  const i18n_1 = require("../server/i18n");
23
- const ssg_1 = require("../ssg");
24
- const templates_1 = require("../templates/templates");
25
- const ssr_html_template_1 = tslib_1.__importDefault(require("../templates/ssr.html.template"));
23
+ const ssgExecutor_1 = require("../ssg/ssgExecutor");
26
24
  async function build(siteDirParam = '.', cliOptions = {}) {
27
25
  process.env.BABEL_ENV = 'production';
28
26
  process.env.NODE_ENV = 'production';
@@ -121,7 +119,7 @@ async function buildLocale({ siteDir, locale, cliOptions, }) {
121
119
  currentBundler: configureWebpackUtils.currentBundler,
122
120
  });
123
121
  });
124
- const { collectedData } = await logger_1.PerfLogger.async('SSG', () => executeSSG({
122
+ const { collectedData } = await logger_1.PerfLogger.async('SSG', () => (0, ssgExecutor_1.executeSSG)({
125
123
  props,
126
124
  serverBundlePath,
127
125
  clientManifestPath,
@@ -133,43 +131,6 @@ async function buildLocale({ siteDir, locale, cliOptions, }) {
133
131
  // TODO execute this in parallel to postBuild?
134
132
  await logger_1.PerfLogger.async('Broken links checker', () => executeBrokenLinksCheck({ props, collectedData }));
135
133
  logger_1.default.success `Generated static files in path=${path_1.default.relative(process.cwd(), outDir)}.`;
136
- return outDir;
137
- }
138
- async function executeSSG({ props, serverBundlePath, clientManifestPath, router, }) {
139
- const manifest = await logger_1.PerfLogger.async('Read client manifest', () => fs_extra_1.default.readJSON(clientManifestPath, 'utf-8'));
140
- const ssrTemplate = await logger_1.PerfLogger.async('Compile SSR template', () => (0, templates_1.compileSSRTemplate)(props.siteConfig.ssrTemplate ?? ssr_html_template_1.default));
141
- const params = {
142
- trailingSlash: props.siteConfig.trailingSlash,
143
- outDir: props.outDir,
144
- baseUrl: props.baseUrl,
145
- manifest,
146
- headTags: props.headTags,
147
- preBodyTags: props.preBodyTags,
148
- postBodyTags: props.postBodyTags,
149
- ssrTemplate,
150
- noIndex: props.siteConfig.noIndex,
151
- DOCUSAURUS_VERSION: utils_1.DOCUSAURUS_VERSION,
152
- };
153
- if (router === 'hash') {
154
- logger_1.PerfLogger.start('Generate Hash Router entry point');
155
- const content = (0, templates_1.renderHashRouterTemplate)({ params });
156
- await (0, ssg_1.generateHashRouterEntrypoint)({ content, params });
157
- logger_1.PerfLogger.end('Generate Hash Router entry point');
158
- return { collectedData: {} };
159
- }
160
- const [renderer, htmlMinifier] = await Promise.all([
161
- logger_1.PerfLogger.async('Load App renderer', () => (0, ssg_1.loadAppRenderer)({
162
- serverBundlePath,
163
- })),
164
- logger_1.PerfLogger.async('Load HTML minifier', () => (0, bundler_1.getHtmlMinifier)({ siteConfig: props.siteConfig })),
165
- ]);
166
- const ssgResult = await logger_1.PerfLogger.async('Generate static files', () => (0, ssg_1.generateStaticFiles)({
167
- pathnames: props.routesPaths,
168
- renderer,
169
- params,
170
- htmlMinifier,
171
- }));
172
- return ssgResult;
173
134
  }
174
135
  async function executePluginsPostBuild({ plugins, props, collectedData, }) {
175
136
  const head = lodash_1.default.mapValues(collectedData, (d) => d.helmet);
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import type { SSGParams } from './ssgParams';
8
+ import type { AppRenderer, SiteCollectedData } from '../common';
9
+ export declare function loadAppRenderer({ serverBundlePath, }: {
10
+ serverBundlePath: string;
11
+ }): Promise<AppRenderer>;
12
+ export declare function printSSGWarnings(results: {
13
+ pathname: string;
14
+ warnings: string[];
15
+ }[]): void;
16
+ export declare function generateStaticFiles({ pathnames, params, }: {
17
+ pathnames: string[];
18
+ params: SSGParams;
19
+ }): Promise<{
20
+ collectedData: SiteCollectedData;
21
+ }>;
@@ -9,7 +9,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.loadAppRenderer = loadAppRenderer;
10
10
  exports.printSSGWarnings = printSSGWarnings;
11
11
  exports.generateStaticFiles = generateStaticFiles;
12
- exports.generateHashRouterEntrypoint = generateHashRouterEntrypoint;
13
12
  const tslib_1 = require("tslib");
14
13
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
15
14
  const module_1 = require("module");
@@ -18,15 +17,9 @@ const lodash_1 = tslib_1.__importDefault(require("lodash"));
18
17
  const eval_1 = tslib_1.__importDefault(require("eval"));
19
18
  const p_map_1 = tslib_1.__importDefault(require("p-map"));
20
19
  const logger_1 = tslib_1.__importStar(require("@docusaurus/logger"));
21
- const templates_1 = require("./templates/templates");
22
- // Secret way to set SSR plugin concurrency option
23
- // Waiting for feedback before documenting this officially?
24
- const Concurrency = process.env.DOCUSAURUS_SSR_CONCURRENCY
25
- ? parseInt(process.env.DOCUSAURUS_SSR_CONCURRENCY, 10)
26
- : // Not easy to define a reasonable option default
27
- // Will still be better than Infinity
28
- // See also https://github.com/sindresorhus/p-map/issues/24
29
- 32;
20
+ const bundler_1 = require("@docusaurus/bundler");
21
+ const ssgTemplate_1 = require("./ssgTemplate");
22
+ const ssgUtils_1 = require("./ssgUtils");
30
23
  async function loadAppRenderer({ serverBundlePath, }) {
31
24
  const source = await logger_1.PerfLogger.async(`Load server bundle`, () => fs_extra_1.default.readFile(serverBundlePath));
32
25
  logger_1.PerfLogger.log(`Server bundle size = ${(source.length / 1024000).toFixed(3)} MB`);
@@ -50,23 +43,6 @@ async function loadAppRenderer({ serverBundlePath, }) {
50
43
  }
51
44
  return serverEntry.default;
52
45
  }
53
- function pathnameToFilename({ pathname, trailingSlash, }) {
54
- const outputFileName = pathname.replace(/^[/\\]/, ''); // Remove leading slashes for webpack-dev-server
55
- // Paths ending with .html are left untouched
56
- if (/\.html?$/i.test(outputFileName)) {
57
- return outputFileName;
58
- }
59
- // Legacy retro-compatible behavior
60
- if (typeof trailingSlash === 'undefined') {
61
- return path_1.default.join(outputFileName, 'index.html');
62
- }
63
- // New behavior: we can say if we prefer file/folder output
64
- // Useful resource: https://github.com/slorber/trailing-slash-guide
65
- if (pathname === '' || pathname.endsWith('/') || trailingSlash) {
66
- return path_1.default.join(outputFileName, 'index.html');
67
- }
68
- return `${outputFileName}.html`;
69
- }
70
46
  function printSSGWarnings(results) {
71
47
  // Escape hatch because SWC is quite aggressive to report errors
72
48
  // See https://github.com/facebook/docusaurus/pull/10554
@@ -103,7 +79,16 @@ Troubleshooting guide: https://github.com/facebook/docusaurus/discussions/10580
103
79
  logger_1.default.warn(message);
104
80
  }
105
81
  }
106
- async function generateStaticFiles({ pathnames, renderer, params, htmlMinifier, }) {
82
+ async function generateStaticFiles({ pathnames, params, }) {
83
+ const [renderer, htmlMinifier, ssgTemplate] = await Promise.all([
84
+ logger_1.PerfLogger.async('Load App renderer', () => loadAppRenderer({
85
+ serverBundlePath: params.serverBundlePath,
86
+ })),
87
+ logger_1.PerfLogger.async('Load HTML minifier', () => (0, bundler_1.getHtmlMinifier)({
88
+ type: params.htmlMinifierType,
89
+ })),
90
+ logger_1.PerfLogger.async('Compile SSG template', () => (0, ssgTemplate_1.compileSSGTemplate)(params.ssgTemplateContent)),
91
+ ]);
107
92
  // Note that we catch all async errors on purpose
108
93
  // Docusaurus presents all the SSG errors to the user, not just the first one
109
94
  const results = await (0, p_map_1.default)(pathnames, async (pathname) => generateStaticFile({
@@ -111,6 +96,7 @@ async function generateStaticFiles({ pathnames, renderer, params, htmlMinifier,
111
96
  renderer,
112
97
  params,
113
98
  htmlMinifier,
99
+ ssgTemplate,
114
100
  }).then((result) => ({
115
101
  pathname,
116
102
  result,
@@ -121,7 +107,7 @@ async function generateStaticFiles({ pathnames, renderer, params, htmlMinifier,
121
107
  result: null,
122
108
  error: error,
123
109
  warnings: [],
124
- })), { concurrency: Concurrency });
110
+ })), { concurrency: ssgUtils_1.SSGConcurrency });
125
111
  printSSGWarnings(results);
126
112
  const [allSSGErrors, allSSGSuccesses] = lodash_1.default.partition(results, (result) => !!result.error);
127
113
  if (allSSGErrors.length > 0) {
@@ -140,25 +126,26 @@ async function generateStaticFiles({ pathnames, renderer, params, htmlMinifier,
140
126
  .value();
141
127
  return { collectedData };
142
128
  }
143
- async function generateStaticFile({ pathname, renderer, params, htmlMinifier, }) {
129
+ async function generateStaticFile({ pathname, renderer, params, htmlMinifier, ssgTemplate, }) {
144
130
  try {
145
131
  // This only renders the app HTML
146
132
  const result = await renderer({
147
133
  pathname,
148
134
  });
149
135
  // This renders the full page HTML, including head tags...
150
- const fullPageHtml = (0, templates_1.renderSSRTemplate)({
136
+ const fullPageHtml = (0, ssgTemplate_1.renderSSGTemplate)({
151
137
  params,
152
138
  result,
139
+ ssgTemplate,
153
140
  });
154
141
  const minifierResult = await htmlMinifier.minify(fullPageHtml);
155
- await writeStaticFile({
142
+ await (0, ssgUtils_1.writeStaticFile)({
156
143
  pathname,
157
144
  content: minifierResult.code,
158
145
  params,
159
146
  });
160
147
  return {
161
- ...result,
148
+ collectedData: result.collectedData,
162
149
  // As of today, only the html minifier can emit SSG warnings
163
150
  warnings: minifierResult.warnings,
164
151
  };
@@ -184,22 +171,3 @@ It might also require to wrap your client code in ${logger_1.default.code('useEf
184
171
  }
185
172
  return parts.join('\n');
186
173
  }
187
- async function generateHashRouterEntrypoint({ content, params, }) {
188
- await writeStaticFile({
189
- pathname: '/',
190
- content,
191
- params,
192
- });
193
- }
194
- async function writeStaticFile({ content, pathname, params, }) {
195
- function removeBaseUrl(p, baseUrl) {
196
- return baseUrl === '/' ? p : p.replace(new RegExp(`^${baseUrl}`), '/');
197
- }
198
- const filename = pathnameToFilename({
199
- pathname: removeBaseUrl(pathname, params.baseUrl),
200
- trailingSlash: params.trailingSlash,
201
- });
202
- const filePath = path_1.default.join(params.outDir, filename);
203
- await fs_extra_1.default.ensureDir(path_1.default.dirname(filePath));
204
- await fs_extra_1.default.writeFile(filePath, content);
205
- }
@@ -0,0 +1,16 @@
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, RouterType } from '@docusaurus/types';
8
+ import type { SiteCollectedData } from '../common';
9
+ export declare function executeSSG({ props, serverBundlePath, clientManifestPath, router, }: {
10
+ props: Props;
11
+ serverBundlePath: string;
12
+ clientManifestPath: string;
13
+ router: RouterType;
14
+ }): Promise<{
15
+ collectedData: SiteCollectedData;
16
+ }>;
@@ -0,0 +1,34 @@
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.executeSSG = executeSSG;
10
+ const logger_1 = require("@docusaurus/logger");
11
+ const ssgParams_1 = require("./ssgParams");
12
+ const ssg_1 = require("./ssg");
13
+ const ssgTemplate_1 = require("./ssgTemplate");
14
+ const ssgUtils_1 = require("./ssgUtils");
15
+ // TODO Docusaurus v4 - introduce SSG worker threads
16
+ async function executeSSG({ props, serverBundlePath, clientManifestPath, router, }) {
17
+ const params = await (0, ssgParams_1.createSSGParams)({
18
+ serverBundlePath,
19
+ clientManifestPath,
20
+ props,
21
+ });
22
+ if (router === 'hash') {
23
+ logger_1.PerfLogger.start('Generate Hash Router entry point');
24
+ const content = await (0, ssgTemplate_1.renderHashRouterTemplate)({ params });
25
+ await (0, ssgUtils_1.generateHashRouterEntrypoint)({ content, params });
26
+ logger_1.PerfLogger.end('Generate Hash Router entry point');
27
+ return { collectedData: {} };
28
+ }
29
+ const ssgResult = await logger_1.PerfLogger.async('Generate static files', () => (0, ssg_1.generateStaticFiles)({
30
+ pathnames: props.routesPaths,
31
+ params,
32
+ }));
33
+ return ssgResult;
34
+ }
@@ -0,0 +1,28 @@
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 { Manifest } from 'react-loadable-ssr-addon-v5-slorber';
8
+ import type { Props } from '@docusaurus/types';
9
+ import type { HtmlMinifierType } from '@docusaurus/bundler';
10
+ export type SSGParams = {
11
+ trailingSlash: boolean | undefined;
12
+ manifest: Manifest;
13
+ headTags: string;
14
+ preBodyTags: string;
15
+ postBodyTags: string;
16
+ outDir: string;
17
+ baseUrl: string;
18
+ noIndex: boolean;
19
+ DOCUSAURUS_VERSION: string;
20
+ htmlMinifierType: HtmlMinifierType;
21
+ serverBundlePath: string;
22
+ ssgTemplateContent: string;
23
+ };
24
+ export declare function createSSGParams({ props, serverBundlePath, clientManifestPath, }: {
25
+ props: Props;
26
+ serverBundlePath: string;
27
+ clientManifestPath: string;
28
+ }): Promise<SSGParams>;
@@ -0,0 +1,36 @@
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.createSSGParams = createSSGParams;
10
+ const tslib_1 = require("tslib");
11
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
+ const utils_1 = require("@docusaurus/utils");
13
+ const logger_1 = require("@docusaurus/logger");
14
+ const ssgTemplate_html_1 = tslib_1.__importDefault(require("./ssgTemplate.html"));
15
+ async function createSSGParams({ props, serverBundlePath, clientManifestPath, }) {
16
+ const manifest = await logger_1.PerfLogger.async('Read client manifest', () => fs_extra_1.default.readJSON(clientManifestPath, 'utf-8'));
17
+ const params = {
18
+ trailingSlash: props.siteConfig.trailingSlash,
19
+ outDir: props.outDir,
20
+ baseUrl: props.baseUrl,
21
+ manifest,
22
+ headTags: props.headTags,
23
+ preBodyTags: props.preBodyTags,
24
+ postBodyTags: props.postBodyTags,
25
+ ssgTemplateContent: props.siteConfig.ssrTemplate ?? ssgTemplate_html_1.default,
26
+ noIndex: props.siteConfig.noIndex,
27
+ DOCUSAURUS_VERSION: utils_1.DOCUSAURUS_VERSION,
28
+ serverBundlePath,
29
+ htmlMinifierType: props.siteConfig.future.experimental_faster
30
+ .swcHtmlMinimizer
31
+ ? 'swc'
32
+ : 'terser',
33
+ };
34
+ // Useless but ensures that SSG params remain serializable
35
+ return structuredClone(params);
36
+ }
@@ -4,9 +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 { SSGParams } from '../ssg';
7
+ import type { SSGParams } from './ssgParams';
8
8
  import type { AppRenderResult } from '../common';
9
- export type SSRTemplateData = {
9
+ export type SSGTemplateData = {
10
10
  appHtml: string;
11
11
  baseUrl: string;
12
12
  htmlAttributes: string;
@@ -20,12 +20,13 @@ export type SSRTemplateData = {
20
20
  noIndex: boolean;
21
21
  version: string;
22
22
  };
23
- export type SSRTemplateCompiled = (data: SSRTemplateData) => string;
24
- export declare function compileSSRTemplate(template: string): Promise<SSRTemplateCompiled>;
25
- export declare function renderSSRTemplate({ params, result, }: {
23
+ export type SSGTemplateCompiled = (data: SSGTemplateData) => string;
24
+ export declare function compileSSGTemplate(template: string): Promise<SSGTemplateCompiled>;
25
+ export declare function renderSSGTemplate({ params, result, ssgTemplate, }: {
26
26
  params: SSGParams;
27
27
  result: AppRenderResult;
28
+ ssgTemplate: SSGTemplateCompiled;
28
29
  }): string;
29
30
  export declare function renderHashRouterTemplate({ params, }: {
30
31
  params: SSGParams;
31
- }): string;
32
+ }): Promise<string>;
@@ -6,13 +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.compileSSRTemplate = compileSSRTemplate;
10
- exports.renderSSRTemplate = renderSSRTemplate;
9
+ exports.compileSSGTemplate = compileSSGTemplate;
10
+ exports.renderSSGTemplate = renderSSGTemplate;
11
11
  exports.renderHashRouterTemplate = renderHashRouterTemplate;
12
12
  const tslib_1 = require("tslib");
13
13
  const eta = tslib_1.__importStar(require("eta"));
14
14
  const react_loadable_ssr_addon_v5_slorber_1 = require("react-loadable-ssr-addon-v5-slorber");
15
- async function compileSSRTemplate(template) {
15
+ const logger_1 = require("@docusaurus/logger");
16
+ async function compileSSGTemplate(template) {
16
17
  const compiledTemplate = eta.compile(template.trim(), {
17
18
  rmWhitespace: true,
18
19
  });
@@ -32,8 +33,8 @@ function getScriptsAndStylesheets({ modules, manifest, }) {
32
33
  const scripts = (bundles.js ?? []).map((b) => b.file);
33
34
  return { scripts, stylesheets };
34
35
  }
35
- function renderSSRTemplate({ params, result, }) {
36
- const { baseUrl, headTags, preBodyTags, postBodyTags, manifest, noIndex, DOCUSAURUS_VERSION, ssrTemplate, } = params;
36
+ function renderSSGTemplate({ params, result, ssgTemplate, }) {
37
+ const { baseUrl, headTags, preBodyTags, postBodyTags, manifest, noIndex, DOCUSAURUS_VERSION, } = params;
37
38
  const { html: appHtml, collectedData: { modules, helmet }, } = result;
38
39
  const { scripts, stylesheets } = getScriptsAndStylesheets({ manifest, modules });
39
40
  const htmlAttributes = helmet.htmlAttributes.toString();
@@ -59,12 +60,13 @@ function renderSSRTemplate({ params, result, }) {
59
60
  noIndex,
60
61
  version: DOCUSAURUS_VERSION,
61
62
  };
62
- return ssrTemplate(data);
63
+ return ssgTemplate(data);
63
64
  }
64
- function renderHashRouterTemplate({ params, }) {
65
+ async function renderHashRouterTemplate({ params, }) {
65
66
  const {
66
67
  // baseUrl,
67
- headTags, preBodyTags, postBodyTags, manifest, DOCUSAURUS_VERSION, ssrTemplate, } = params;
68
+ headTags, preBodyTags, postBodyTags, manifest, DOCUSAURUS_VERSION, ssgTemplateContent, } = params;
69
+ const ssgTemplate = await logger_1.PerfLogger.async('Compile SSG template', () => compileSSGTemplate(ssgTemplateContent));
68
70
  const { scripts, stylesheets } = getScriptsAndStylesheets({
69
71
  manifest,
70
72
  modules: [],
@@ -83,5 +85,5 @@ function renderHashRouterTemplate({ params, }) {
83
85
  noIndex: false,
84
86
  version: DOCUSAURUS_VERSION,
85
87
  };
86
- return ssrTemplate(data);
88
+ return ssgTemplate(data);
87
89
  }
@@ -0,0 +1,17 @@
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 { SSGParams } from './ssgParams';
8
+ export declare const SSGConcurrency: number;
9
+ export declare function generateHashRouterEntrypoint({ content, params, }: {
10
+ content: string;
11
+ params: SSGParams;
12
+ }): Promise<void>;
13
+ export declare function writeStaticFile({ content, pathname, params, }: {
14
+ content: string;
15
+ pathname: string;
16
+ params: SSGParams;
17
+ }): Promise<void>;
@@ -0,0 +1,58 @@
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.SSGConcurrency = void 0;
10
+ exports.generateHashRouterEntrypoint = generateHashRouterEntrypoint;
11
+ exports.writeStaticFile = writeStaticFile;
12
+ const tslib_1 = require("tslib");
13
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
14
+ const path_1 = tslib_1.__importDefault(require("path"));
15
+ // Secret way to set SSR plugin concurrency option
16
+ // Waiting for feedback before documenting this officially?
17
+ exports.SSGConcurrency = process.env.DOCUSAURUS_SSR_CONCURRENCY
18
+ ? parseInt(process.env.DOCUSAURUS_SSR_CONCURRENCY, 10)
19
+ : // Not easy to define a reasonable option default
20
+ // Will still be better than Infinity
21
+ // See also https://github.com/sindresorhus/p-map/issues/24
22
+ 32;
23
+ function pathnameToFilename({ pathname, trailingSlash, }) {
24
+ const outputFileName = pathname.replace(/^[/\\]/, ''); // Remove leading slashes for webpack-dev-server
25
+ // Paths ending with .html are left untouched
26
+ if (/\.html?$/i.test(outputFileName)) {
27
+ return outputFileName;
28
+ }
29
+ // Legacy retro-compatible behavior
30
+ if (typeof trailingSlash === 'undefined') {
31
+ return path_1.default.join(outputFileName, 'index.html');
32
+ }
33
+ // New behavior: we can say if we prefer file/folder output
34
+ // Useful resource: https://github.com/slorber/trailing-slash-guide
35
+ if (pathname === '' || pathname.endsWith('/') || trailingSlash) {
36
+ return path_1.default.join(outputFileName, 'index.html');
37
+ }
38
+ return `${outputFileName}.html`;
39
+ }
40
+ async function generateHashRouterEntrypoint({ content, params, }) {
41
+ await writeStaticFile({
42
+ pathname: '/',
43
+ content,
44
+ params,
45
+ });
46
+ }
47
+ async function writeStaticFile({ content, pathname, params, }) {
48
+ function removeBaseUrl(p, baseUrl) {
49
+ return baseUrl === '/' ? p : p.replace(new RegExp(`^${baseUrl}`), '/');
50
+ }
51
+ const filename = pathnameToFilename({
52
+ pathname: removeBaseUrl(pathname, params.baseUrl),
53
+ trailingSlash: params.trailingSlash,
54
+ });
55
+ const filePath = path_1.default.join(params.outDir, filename);
56
+ await fs_extra_1.default.ensureDir(path_1.default.dirname(filePath));
57
+ await fs_extra_1.default.writeFile(filePath, content);
58
+ }
@@ -76,7 +76,7 @@ async function createStartClientConfig({ props, minify, poll, faster, configureW
76
76
  plugins: [
77
77
  // Generates an `index.html` file with the <script> injected.
78
78
  new html_webpack_plugin_1.default({
79
- template: path_1.default.join(__dirname, '../templates/dev.html.template.ejs'),
79
+ template: path_1.default.join(__dirname, './templates/dev.html.template.ejs'),
80
80
  // So we can define the position where the scripts are injected.
81
81
  inject: false,
82
82
  filename: 'index.html',
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-6106",
4
+ "version": "0.0.0-6110",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -33,13 +33,13 @@
33
33
  "url": "https://github.com/facebook/docusaurus/issues"
34
34
  },
35
35
  "dependencies": {
36
- "@docusaurus/babel": "0.0.0-6106",
37
- "@docusaurus/bundler": "0.0.0-6106",
38
- "@docusaurus/logger": "0.0.0-6106",
39
- "@docusaurus/mdx-loader": "0.0.0-6106",
40
- "@docusaurus/utils": "0.0.0-6106",
41
- "@docusaurus/utils-common": "0.0.0-6106",
42
- "@docusaurus/utils-validation": "0.0.0-6106",
36
+ "@docusaurus/babel": "0.0.0-6110",
37
+ "@docusaurus/bundler": "0.0.0-6110",
38
+ "@docusaurus/logger": "0.0.0-6110",
39
+ "@docusaurus/mdx-loader": "0.0.0-6110",
40
+ "@docusaurus/utils": "0.0.0-6110",
41
+ "@docusaurus/utils-common": "0.0.0-6110",
42
+ "@docusaurus/utils-validation": "0.0.0-6110",
43
43
  "boxen": "^6.2.1",
44
44
  "chalk": "^4.1.2",
45
45
  "chokidar": "^3.5.3",
@@ -78,8 +78,8 @@
78
78
  "webpack-merge": "^6.0.1"
79
79
  },
80
80
  "devDependencies": {
81
- "@docusaurus/module-type-aliases": "0.0.0-6106",
82
- "@docusaurus/types": "0.0.0-6106",
81
+ "@docusaurus/module-type-aliases": "0.0.0-6110",
82
+ "@docusaurus/types": "0.0.0-6110",
83
83
  "@total-typescript/shoehorn": "^0.1.2",
84
84
  "@types/detect-port": "^1.3.3",
85
85
  "@types/react-dom": "^18.2.7",
@@ -100,5 +100,5 @@
100
100
  "engines": {
101
101
  "node": ">=18.0"
102
102
  },
103
- "gitHead": "ca593b56b8185eaa1fbe07fb5ae9ed86494d6072"
103
+ "gitHead": "3e5c6c714c37c6d3592bfc2a0679dbff3d825b3e"
104
104
  }
package/lib/ssg.d.ts DELETED
@@ -1,41 +0,0 @@
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 { AppRenderer, SiteCollectedData } from './common';
8
- import type { HtmlMinifier } from '@docusaurus/bundler';
9
- import type { Manifest } from 'react-loadable-ssr-addon-v5-slorber';
10
- import type { SSRTemplateCompiled } from './templates/templates';
11
- export type SSGParams = {
12
- trailingSlash: boolean | undefined;
13
- manifest: Manifest;
14
- headTags: string;
15
- preBodyTags: string;
16
- postBodyTags: string;
17
- outDir: string;
18
- baseUrl: string;
19
- noIndex: boolean;
20
- DOCUSAURUS_VERSION: string;
21
- ssrTemplate: SSRTemplateCompiled;
22
- };
23
- export declare function loadAppRenderer({ serverBundlePath, }: {
24
- serverBundlePath: string;
25
- }): Promise<AppRenderer>;
26
- export declare function printSSGWarnings(results: {
27
- pathname: string;
28
- warnings: string[];
29
- }[]): void;
30
- export declare function generateStaticFiles({ pathnames, renderer, params, htmlMinifier, }: {
31
- pathnames: string[];
32
- renderer: AppRenderer;
33
- params: SSGParams;
34
- htmlMinifier: HtmlMinifier;
35
- }): Promise<{
36
- collectedData: SiteCollectedData;
37
- }>;
38
- export declare function generateHashRouterEntrypoint({ content, params, }: {
39
- content: string;
40
- params: SSGParams;
41
- }): Promise<void>;