@docusaurus/core 0.0.0-6105 → 0.0.0-6109
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.
- package/lib/client/renderToHtml.js +15 -51
- package/lib/client/serverEntry.js +2 -0
- package/lib/commands/build.js +2 -41
- package/lib/ssg/ssg.d.ts +21 -0
- package/lib/{ssg.js → ssg/ssg.js} +20 -52
- package/lib/ssg/ssgExecutor.d.ts +16 -0
- package/lib/ssg/ssgExecutor.js +34 -0
- package/lib/ssg/ssgParams.d.ts +28 -0
- package/lib/ssg/ssgParams.js +36 -0
- package/lib/{templates/templates.d.ts → ssg/ssgTemplate.d.ts} +7 -6
- package/lib/{templates/templates.js → ssg/ssgTemplate.js} +11 -9
- package/lib/ssg/ssgUtils.d.ts +17 -0
- package/lib/ssg/ssgUtils.js +58 -0
- package/lib/webpack/client.js +1 -1
- package/package.json +11 -11
- package/lib/ssg.d.ts +0 -41
- /package/lib/{templates/ssr.html.template.d.ts → ssg/ssgTemplate.html.d.ts} +0 -0
- /package/lib/{templates/ssr.html.template.js → ssg/ssgTemplate.html.js} +0 -0
- /package/lib/{templates → webpack/templates}/dev.html.template.ejs +0 -0
|
@@ -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 {
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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(),
|
package/lib/commands/build.js
CHANGED
|
@@ -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
|
|
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);
|
package/lib/ssg/ssg.d.ts
ADDED
|
@@ -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
|
|
22
|
-
|
|
23
|
-
|
|
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,
|
|
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:
|
|
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,
|
|
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
|
-
|
|
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 '
|
|
7
|
+
import type { SSGParams } from './ssgParams';
|
|
8
8
|
import type { AppRenderResult } from '../common';
|
|
9
|
-
export type
|
|
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
|
|
24
|
-
export declare function
|
|
25
|
-
export declare function
|
|
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.
|
|
10
|
-
exports.
|
|
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
|
-
|
|
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
|
|
36
|
-
const { baseUrl, headTags, preBodyTags, postBodyTags, manifest, noIndex, DOCUSAURUS_VERSION,
|
|
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
|
|
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,
|
|
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
|
|
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
|
+
}
|
package/lib/webpack/client.js
CHANGED
|
@@ -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, '
|
|
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-
|
|
4
|
+
"version": "0.0.0-6109",
|
|
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-
|
|
37
|
-
"@docusaurus/bundler": "0.0.0-
|
|
38
|
-
"@docusaurus/logger": "0.0.0-
|
|
39
|
-
"@docusaurus/mdx-loader": "0.0.0-
|
|
40
|
-
"@docusaurus/utils": "0.0.0-
|
|
41
|
-
"@docusaurus/utils-common": "0.0.0-
|
|
42
|
-
"@docusaurus/utils-validation": "0.0.0-
|
|
36
|
+
"@docusaurus/babel": "0.0.0-6109",
|
|
37
|
+
"@docusaurus/bundler": "0.0.0-6109",
|
|
38
|
+
"@docusaurus/logger": "0.0.0-6109",
|
|
39
|
+
"@docusaurus/mdx-loader": "0.0.0-6109",
|
|
40
|
+
"@docusaurus/utils": "0.0.0-6109",
|
|
41
|
+
"@docusaurus/utils-common": "0.0.0-6109",
|
|
42
|
+
"@docusaurus/utils-validation": "0.0.0-6109",
|
|
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-
|
|
82
|
-
"@docusaurus/types": "0.0.0-
|
|
81
|
+
"@docusaurus/module-type-aliases": "0.0.0-6109",
|
|
82
|
+
"@docusaurus/types": "0.0.0-6109",
|
|
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": "
|
|
103
|
+
"gitHead": "d1f5cd6af4cb380de04e370bdf94781615cecd58"
|
|
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>;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|