@docusaurus/core 0.0.0-5857 → 0.0.0-5860
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/commands/build.d.ts +2 -2
- package/lib/commands/build.js +6 -6
- package/lib/commands/deploy.d.ts +2 -2
- package/lib/commands/deploy.js +2 -2
- package/lib/commands/external.js +2 -2
- package/lib/commands/serve.d.ts +2 -2
- package/lib/commands/{start.d.ts → start/start.d.ts} +3 -3
- package/lib/commands/start/start.js +47 -0
- package/lib/commands/start/utils.d.ts +31 -0
- package/lib/commands/start/utils.js +88 -0
- package/lib/commands/start/watcher.d.ts +42 -0
- package/lib/commands/start/watcher.js +78 -0
- package/lib/commands/start/webpack.d.ts +15 -0
- package/lib/commands/start/webpack.js +133 -0
- package/lib/commands/swizzle/context.js +2 -2
- package/lib/commands/writeHeadingIds.js +2 -2
- package/lib/commands/writeTranslations.d.ts +2 -2
- package/lib/commands/writeTranslations.js +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/server/brokenLinks.js +2 -2
- package/lib/server/codegen/codegen.d.ts +20 -0
- package/lib/server/codegen/codegen.js +65 -0
- package/lib/server/codegen/codegenRoutes.d.ts +49 -0
- package/lib/server/codegen/codegenRoutes.js +190 -0
- package/lib/server/i18n.d.ts +2 -2
- package/lib/server/plugins/{index.d.ts → plugins.d.ts} +15 -4
- package/lib/server/plugins/plugins.js +176 -0
- package/lib/server/plugins/routeConfig.d.ts +1 -1
- package/lib/server/plugins/routeConfig.js +4 -4
- package/lib/server/routes.d.ts +4 -45
- package/lib/server/routes.js +15 -166
- package/lib/server/{index.d.ts → site.d.ts} +12 -4
- package/lib/server/site.js +167 -0
- package/lib/server/translations/translations.d.ts +3 -0
- package/lib/server/translations/translations.js +7 -1
- package/lib/server/utils.d.ts +0 -2
- package/lib/server/utils.js +1 -9
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +14 -3
- package/package.json +10 -10
- package/lib/commands/start.js +0 -242
- package/lib/server/index.js +0 -154
- package/lib/server/plugins/index.js +0 -106
package/lib/server/routes.js
CHANGED
|
@@ -6,115 +6,23 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
9
|
+
exports.getRoutesPaths = exports.handleDuplicateRoutes = exports.getAllFinalRoutes = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
|
-
const querystring_1 = tslib_1.__importDefault(require("querystring"));
|
|
12
|
-
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
13
11
|
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
|
|
14
12
|
const utils_1 = require("@docusaurus/utils");
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
const chunkNameCache = new Map();
|
|
21
|
-
const chunkNameCount = new Map();
|
|
22
|
-
/**
|
|
23
|
-
* Generates a unique chunk name that can be used in the chunk registry.
|
|
24
|
-
*
|
|
25
|
-
* @param modulePath A path to generate chunk name from. The actual value has no
|
|
26
|
-
* semantic significance.
|
|
27
|
-
* @param prefix A prefix to append to the chunk name, to avoid name clash.
|
|
28
|
-
* @param preferredName Chunk names default to `modulePath`, and this can supply
|
|
29
|
-
* a more human-readable name.
|
|
30
|
-
* @param shortId When `true`, the chunk name would only be a hash without any
|
|
31
|
-
* other characters. Useful for bundle size. Defaults to `true` in production.
|
|
32
|
-
*/
|
|
33
|
-
function genChunkName(modulePath, prefix, preferredName, shortId = process.env.NODE_ENV === 'production') {
|
|
34
|
-
let chunkName = chunkNameCache.get(modulePath);
|
|
35
|
-
if (!chunkName) {
|
|
36
|
-
if (shortId) {
|
|
37
|
-
chunkName = (0, utils_1.simpleHash)(modulePath, 8);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
let str = modulePath;
|
|
41
|
-
if (preferredName) {
|
|
42
|
-
const shortHash = (0, utils_1.simpleHash)(modulePath, 3);
|
|
43
|
-
str = `${preferredName}${shortHash}`;
|
|
44
|
-
}
|
|
45
|
-
const name = (0, utils_1.docuHash)(str);
|
|
46
|
-
chunkName = prefix ? `${prefix}---${name}` : name;
|
|
47
|
-
}
|
|
48
|
-
const seenCount = (chunkNameCount.get(chunkName) ?? 0) + 1;
|
|
49
|
-
if (seenCount > 1) {
|
|
50
|
-
chunkName += seenCount.toString(36);
|
|
51
|
-
}
|
|
52
|
-
chunkNameCache.set(modulePath, chunkName);
|
|
53
|
-
chunkNameCount.set(chunkName, seenCount);
|
|
54
|
-
}
|
|
55
|
-
return chunkName;
|
|
56
|
-
}
|
|
57
|
-
exports.genChunkName = genChunkName;
|
|
58
|
-
/**
|
|
59
|
-
* Takes a piece of route config, and serializes it into raw JS code. The shape
|
|
60
|
-
* is the same as react-router's `RouteConfig`. Formatting is similar to
|
|
61
|
-
* `JSON.stringify` but without all the quotes.
|
|
62
|
-
*/
|
|
63
|
-
function serializeRouteConfig({ routePath, routeHash, exact, subroutesCodeStrings, props, }) {
|
|
64
|
-
const parts = [
|
|
65
|
-
`path: '${routePath}'`,
|
|
66
|
-
`component: ComponentCreator('${routePath}', '${routeHash}')`,
|
|
67
|
-
];
|
|
68
|
-
if (exact) {
|
|
69
|
-
parts.push(`exact: true`);
|
|
13
|
+
// Recursively get the final routes (routes with no subroutes)
|
|
14
|
+
function getAllFinalRoutes(routeConfig) {
|
|
15
|
+
function getFinalRoutes(route) {
|
|
16
|
+
return route.routes ? route.routes.flatMap(getFinalRoutes) : [route];
|
|
70
17
|
}
|
|
71
|
-
|
|
72
|
-
parts.push(`routes: [
|
|
73
|
-
${indent(subroutesCodeStrings.join(',\n'))}
|
|
74
|
-
]`);
|
|
75
|
-
}
|
|
76
|
-
Object.entries(props).forEach(([propName, propValue]) => {
|
|
77
|
-
const isIdentifier = /^[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*$/u.test(propName);
|
|
78
|
-
const key = isIdentifier ? propName : JSON.stringify(propName);
|
|
79
|
-
parts.push(`${key}: ${JSON.stringify(propValue)}`);
|
|
80
|
-
});
|
|
81
|
-
return `{
|
|
82
|
-
${indent(parts.join(',\n'))}
|
|
83
|
-
}`;
|
|
18
|
+
return routeConfig.flatMap(getFinalRoutes);
|
|
84
19
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
88
|
-
!!value?.__import);
|
|
89
|
-
/**
|
|
90
|
-
* Takes a {@link Module} (which is nothing more than a path plus some metadata
|
|
91
|
-
* like query) and returns the string path it represents.
|
|
92
|
-
*/
|
|
93
|
-
function getModulePath(target) {
|
|
94
|
-
if (typeof target === 'string') {
|
|
95
|
-
return target;
|
|
96
|
-
}
|
|
97
|
-
const queryStr = target.query ? `?${querystring_1.default.stringify(target.query)}` : '';
|
|
98
|
-
return `${target.path}${queryStr}`;
|
|
99
|
-
}
|
|
100
|
-
function genChunkNames(routeModule, prefix, name, res) {
|
|
101
|
-
if (isModule(routeModule)) {
|
|
102
|
-
// This is a leaf node, no need to recurse
|
|
103
|
-
const modulePath = getModulePath(routeModule);
|
|
104
|
-
const chunkName = genChunkName(modulePath, prefix, name);
|
|
105
|
-
res.registry[chunkName] = (0, utils_1.escapePath)(modulePath);
|
|
106
|
-
return chunkName;
|
|
107
|
-
}
|
|
108
|
-
if (Array.isArray(routeModule)) {
|
|
109
|
-
return routeModule.map((val, index) => genChunkNames(val, `${index}`, name, res));
|
|
110
|
-
}
|
|
111
|
-
return lodash_1.default.mapValues(routeModule, (v, key) => genChunkNames(v, key, name, res));
|
|
112
|
-
}
|
|
113
|
-
function handleDuplicateRoutes(pluginsRouteConfigs, onDuplicateRoutes) {
|
|
20
|
+
exports.getAllFinalRoutes = getAllFinalRoutes;
|
|
21
|
+
function handleDuplicateRoutes(routes, onDuplicateRoutes) {
|
|
114
22
|
if (onDuplicateRoutes === 'ignore') {
|
|
115
23
|
return;
|
|
116
24
|
}
|
|
117
|
-
const allRoutes =
|
|
25
|
+
const allRoutes = getAllFinalRoutes(routes).map((routeConfig) => routeConfig.path);
|
|
118
26
|
const seenRoutes = new Set();
|
|
119
27
|
const duplicatePaths = allRoutes.filter((route) => {
|
|
120
28
|
if (seenRoutes.has(route)) {
|
|
@@ -129,36 +37,6 @@ This could lead to non-deterministic routing behavior.`;
|
|
|
129
37
|
}
|
|
130
38
|
}
|
|
131
39
|
exports.handleDuplicateRoutes = handleDuplicateRoutes;
|
|
132
|
-
/**
|
|
133
|
-
* This is the higher level overview of route code generation. For each route
|
|
134
|
-
* config node, it returns the node's serialized form, and mutates `registry`,
|
|
135
|
-
* `routesPaths`, and `routesChunkNames` accordingly.
|
|
136
|
-
*/
|
|
137
|
-
function genRouteCode(routeConfig, res) {
|
|
138
|
-
const { path: routePath, component, modules = {}, context, routes: subroutes, priority, exact, ...props } = routeConfig;
|
|
139
|
-
if (typeof routePath !== 'string' || !component) {
|
|
140
|
-
throw new Error(`Invalid route config: path must be a string and component is required.
|
|
141
|
-
${JSON.stringify(routeConfig)}`);
|
|
142
|
-
}
|
|
143
|
-
if (!subroutes) {
|
|
144
|
-
res.routesPaths.push(routePath);
|
|
145
|
-
}
|
|
146
|
-
const routeHash = (0, utils_1.simpleHash)(JSON.stringify(routeConfig), 3);
|
|
147
|
-
res.routesChunkNames[`${routePath}-${routeHash}`] = {
|
|
148
|
-
// Avoid clash with a prop called "component"
|
|
149
|
-
...genChunkNames({ __comp: component }, 'component', component, res),
|
|
150
|
-
...(context &&
|
|
151
|
-
genChunkNames({ __context: context }, 'context', routePath, res)),
|
|
152
|
-
...genChunkNames(modules, 'module', routePath, res),
|
|
153
|
-
};
|
|
154
|
-
return serializeRouteConfig({
|
|
155
|
-
routePath: routePath.replace(/'/g, "\\'"),
|
|
156
|
-
routeHash,
|
|
157
|
-
subroutesCodeStrings: subroutes?.map((r) => genRouteCode(r, res)),
|
|
158
|
-
exact,
|
|
159
|
-
props,
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
40
|
/**
|
|
163
41
|
* Old stuff
|
|
164
42
|
* As far as I understand, this is what permits to SSG the 404.html file
|
|
@@ -167,39 +45,10 @@ ${JSON.stringify(routeConfig)}`);
|
|
|
167
45
|
* The extension probably permits to avoid emitting "/404/index.html"
|
|
168
46
|
*/
|
|
169
47
|
const NotFoundRoutePath = '/404.html';
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
* - `routesChunkNames`, a mapping from route paths (hashed) to code-splitted
|
|
176
|
-
* chunk names.
|
|
177
|
-
* - `registry`, a mapping from chunk names to options for react-loadable.
|
|
178
|
-
*/
|
|
179
|
-
function loadRoutes(routeConfigs, baseUrl, onDuplicateRoutes) {
|
|
180
|
-
handleDuplicateRoutes(routeConfigs, onDuplicateRoutes);
|
|
181
|
-
const res = {
|
|
182
|
-
// To be written by `genRouteCode`
|
|
183
|
-
routesConfig: '',
|
|
184
|
-
routesChunkNames: {},
|
|
185
|
-
registry: {},
|
|
186
|
-
routesPaths: [(0, utils_1.normalizeUrl)([baseUrl, NotFoundRoutePath])],
|
|
187
|
-
};
|
|
188
|
-
// `genRouteCode` would mutate `res`
|
|
189
|
-
const routeConfigSerialized = routeConfigs
|
|
190
|
-
.map((r) => genRouteCode(r, res))
|
|
191
|
-
.join(',\n');
|
|
192
|
-
res.routesConfig = `import React from 'react';
|
|
193
|
-
import ComponentCreator from '@docusaurus/ComponentCreator';
|
|
194
|
-
|
|
195
|
-
export default [
|
|
196
|
-
${indent(routeConfigSerialized)},
|
|
197
|
-
{
|
|
198
|
-
path: '*',
|
|
199
|
-
component: ComponentCreator('*'),
|
|
200
|
-
},
|
|
201
|
-
];
|
|
202
|
-
`;
|
|
203
|
-
return res;
|
|
48
|
+
function getRoutesPaths(routeConfigs, baseUrl) {
|
|
49
|
+
return [
|
|
50
|
+
(0, utils_1.normalizeUrl)([baseUrl, NotFoundRoutePath]),
|
|
51
|
+
...getAllFinalRoutes(routeConfigs).map((r) => r.path),
|
|
52
|
+
];
|
|
204
53
|
}
|
|
205
|
-
exports.
|
|
54
|
+
exports.getRoutesPaths = getRoutesPaths;
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import type { LoadContext, Props } from '@docusaurus/types';
|
|
8
|
-
|
|
8
|
+
import type { PluginIdentifier } from '@docusaurus/types/src/plugin';
|
|
9
|
+
export type LoadContextParams = {
|
|
9
10
|
/** Usually the CWD; can be overridden with command argument. */
|
|
10
11
|
siteDir: string;
|
|
11
12
|
/** Custom output directory. Can be customized with `--out-dir` option */
|
|
@@ -22,17 +23,24 @@ export type LoadContextOptions = {
|
|
|
22
23
|
*/
|
|
23
24
|
localizePath?: boolean;
|
|
24
25
|
};
|
|
26
|
+
export type LoadSiteParams = LoadContextParams;
|
|
27
|
+
export type Site = {
|
|
28
|
+
props: Props;
|
|
29
|
+
params: LoadSiteParams;
|
|
30
|
+
};
|
|
25
31
|
/**
|
|
26
|
-
* Loading context is the very first step in site building. Its
|
|
32
|
+
* Loading context is the very first step in site building. Its params are
|
|
27
33
|
* directly acquired from CLI options. It mainly loads `siteConfig` and the i18n
|
|
28
34
|
* context (which includes code translations). The `LoadContext` will be passed
|
|
29
35
|
* to plugin constructors.
|
|
30
36
|
*/
|
|
31
|
-
export declare function loadContext(
|
|
37
|
+
export declare function loadContext(params: LoadContextParams): Promise<LoadContext>;
|
|
32
38
|
/**
|
|
33
39
|
* This is the crux of the Docusaurus server-side. It reads everything it needs—
|
|
34
40
|
* code translations, config file, plugin modules... Plugins then use their
|
|
35
41
|
* lifecycles to generate content and other data. It is side-effect-ful because
|
|
36
42
|
* it generates temp files in the `.docusaurus` folder for the bundler.
|
|
37
43
|
*/
|
|
38
|
-
export declare function
|
|
44
|
+
export declare function loadSite(params: LoadContextParams): Promise<Site>;
|
|
45
|
+
export declare function reloadSite(site: Site): Promise<Site>;
|
|
46
|
+
export declare function reloadSitePlugin(site: Site, pluginIdentifier: PluginIdentifier): Promise<Site>;
|
|
@@ -0,0 +1,167 @@
|
|
|
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.reloadSitePlugin = exports.reloadSite = exports.loadSite = exports.loadContext = void 0;
|
|
10
|
+
const tslib_1 = require("tslib");
|
|
11
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
12
|
+
const utils_1 = require("@docusaurus/utils");
|
|
13
|
+
const combine_promises_1 = tslib_1.__importDefault(require("combine-promises"));
|
|
14
|
+
const config_1 = require("./config");
|
|
15
|
+
const clientModules_1 = require("./clientModules");
|
|
16
|
+
const plugins_1 = require("./plugins/plugins");
|
|
17
|
+
const htmlTags_1 = require("./htmlTags");
|
|
18
|
+
const siteMetadata_1 = require("./siteMetadata");
|
|
19
|
+
const i18n_1 = require("./i18n");
|
|
20
|
+
const translations_1 = require("./translations/translations");
|
|
21
|
+
const utils_2 = require("../utils");
|
|
22
|
+
const codegen_1 = require("./codegen/codegen");
|
|
23
|
+
const routes_1 = require("./routes");
|
|
24
|
+
/**
|
|
25
|
+
* Loading context is the very first step in site building. Its params are
|
|
26
|
+
* directly acquired from CLI options. It mainly loads `siteConfig` and the i18n
|
|
27
|
+
* context (which includes code translations). The `LoadContext` will be passed
|
|
28
|
+
* to plugin constructors.
|
|
29
|
+
*/
|
|
30
|
+
async function loadContext(params) {
|
|
31
|
+
const { siteDir, outDir: baseOutDir = utils_1.DEFAULT_BUILD_DIR_NAME, locale, config: customConfigFilePath, } = params;
|
|
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,
|
|
36
|
+
});
|
|
37
|
+
const i18n = await (0, i18n_1.loadI18n)(initialSiteConfig, { locale });
|
|
38
|
+
const baseUrl = (0, utils_1.localizePath)({
|
|
39
|
+
path: initialSiteConfig.baseUrl,
|
|
40
|
+
i18n,
|
|
41
|
+
options: params,
|
|
42
|
+
pathType: 'url',
|
|
43
|
+
});
|
|
44
|
+
const outDir = (0, utils_1.localizePath)({
|
|
45
|
+
path: path_1.default.resolve(siteDir, baseOutDir),
|
|
46
|
+
i18n,
|
|
47
|
+
options: params,
|
|
48
|
+
pathType: 'fs',
|
|
49
|
+
});
|
|
50
|
+
const localizationDir = path_1.default.resolve(siteDir, i18n.path, i18n.localeConfigs[i18n.currentLocale].path);
|
|
51
|
+
const siteConfig = { ...initialSiteConfig, baseUrl };
|
|
52
|
+
const codeTranslations = await (0, translations_1.loadSiteCodeTranslations)({ localizationDir });
|
|
53
|
+
return {
|
|
54
|
+
siteDir,
|
|
55
|
+
generatedFilesDir,
|
|
56
|
+
localizationDir,
|
|
57
|
+
siteConfig,
|
|
58
|
+
siteConfigPath,
|
|
59
|
+
outDir,
|
|
60
|
+
baseUrl,
|
|
61
|
+
i18n,
|
|
62
|
+
codeTranslations,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
exports.loadContext = loadContext;
|
|
66
|
+
async function createSiteProps(params) {
|
|
67
|
+
const { plugins, routes, context } = params;
|
|
68
|
+
const { generatedFilesDir, siteDir, siteConfig, siteConfigPath, outDir, baseUrl, i18n, localizationDir, codeTranslations: siteCodeTranslations, } = context;
|
|
69
|
+
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
|
+
});
|
|
78
|
+
(0, routes_1.handleDuplicateRoutes)(routes, siteConfig.onDuplicateRoutes);
|
|
79
|
+
const routesPaths = (0, routes_1.getRoutesPaths)(routes, baseUrl);
|
|
80
|
+
return {
|
|
81
|
+
siteConfig,
|
|
82
|
+
siteConfigPath,
|
|
83
|
+
siteMetadata,
|
|
84
|
+
siteDir,
|
|
85
|
+
outDir,
|
|
86
|
+
baseUrl,
|
|
87
|
+
i18n,
|
|
88
|
+
localizationDir,
|
|
89
|
+
generatedFilesDir,
|
|
90
|
+
routes,
|
|
91
|
+
routesPaths,
|
|
92
|
+
plugins,
|
|
93
|
+
headTags,
|
|
94
|
+
preBodyTags,
|
|
95
|
+
postBodyTags,
|
|
96
|
+
codeTranslations,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// TODO global data should be part of site props?
|
|
100
|
+
async function createSiteFiles({ site, globalData, }) {
|
|
101
|
+
return utils_2.PerfLogger.async('Load - createSiteFiles', async () => {
|
|
102
|
+
const { props: { plugins, generatedFilesDir, siteConfig, siteMetadata, i18n, codeTranslations, routes, baseUrl, }, } = site;
|
|
103
|
+
const clientModules = (0, clientModules_1.loadClientModules)(plugins);
|
|
104
|
+
await (0, codegen_1.generateSiteFiles)({
|
|
105
|
+
generatedFilesDir,
|
|
106
|
+
clientModules,
|
|
107
|
+
siteConfig,
|
|
108
|
+
siteMetadata,
|
|
109
|
+
i18n,
|
|
110
|
+
codeTranslations,
|
|
111
|
+
globalData,
|
|
112
|
+
routes,
|
|
113
|
+
baseUrl,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* This is the crux of the Docusaurus server-side. It reads everything it needs—
|
|
119
|
+
* code translations, config file, plugin modules... Plugins then use their
|
|
120
|
+
* lifecycles to generate content and other data. It is side-effect-ful because
|
|
121
|
+
* it generates temp files in the `.docusaurus` folder for the bundler.
|
|
122
|
+
*/
|
|
123
|
+
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');
|
|
128
|
+
const { plugins, routes, globalData } = await (0, plugins_1.loadPlugins)(context);
|
|
129
|
+
utils_2.PerfLogger.end('Load - loadPlugins');
|
|
130
|
+
const props = await createSiteProps({ plugins, routes, globalData, context });
|
|
131
|
+
const site = { props, params };
|
|
132
|
+
await createSiteFiles({
|
|
133
|
+
site,
|
|
134
|
+
globalData,
|
|
135
|
+
});
|
|
136
|
+
return site;
|
|
137
|
+
}
|
|
138
|
+
exports.loadSite = loadSite;
|
|
139
|
+
async function reloadSite(site) {
|
|
140
|
+
// TODO this can be optimized, for example:
|
|
141
|
+
// - plugins loading same data as before should not recreate routes/bundles
|
|
142
|
+
// - codegen does not need to re-run if nothing changed
|
|
143
|
+
return loadSite(site.params);
|
|
144
|
+
}
|
|
145
|
+
exports.reloadSite = reloadSite;
|
|
146
|
+
async function reloadSitePlugin(site, pluginIdentifier) {
|
|
147
|
+
console.log(`reloadSitePlugin ${pluginIdentifier.name}@${pluginIdentifier.id}`);
|
|
148
|
+
const { plugins, routes, globalData } = await (0, plugins_1.reloadPlugin)({
|
|
149
|
+
pluginIdentifier,
|
|
150
|
+
plugins: site.props.plugins,
|
|
151
|
+
context: site.props,
|
|
152
|
+
});
|
|
153
|
+
const newProps = await createSiteProps({
|
|
154
|
+
plugins,
|
|
155
|
+
routes,
|
|
156
|
+
globalData,
|
|
157
|
+
context: site.props, // Props extends Context
|
|
158
|
+
});
|
|
159
|
+
const newSite = {
|
|
160
|
+
props: newProps,
|
|
161
|
+
params: site.params,
|
|
162
|
+
};
|
|
163
|
+
// TODO optimize, bypass useless codegen if new site is similar to old site
|
|
164
|
+
await createSiteFiles({ site: newSite, globalData });
|
|
165
|
+
return newSite;
|
|
166
|
+
}
|
|
167
|
+
exports.reloadSitePlugin = reloadSitePlugin;
|
|
@@ -28,4 +28,7 @@ export declare function applyDefaultCodeTranslations({ extractedCodeTranslations
|
|
|
28
28
|
extractedCodeTranslations: TranslationFileContent;
|
|
29
29
|
defaultCodeMessages: CodeTranslations;
|
|
30
30
|
}): TranslationFileContent;
|
|
31
|
+
export declare function loadSiteCodeTranslations({ localizationDir, }: {
|
|
32
|
+
localizationDir: string;
|
|
33
|
+
}): Promise<CodeTranslations>;
|
|
31
34
|
export {};
|
|
@@ -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.applyDefaultCodeTranslations = exports.getPluginsDefaultCodeTranslationMessages = exports.localizePluginTranslationFile = exports.writePluginTranslations = exports.writeCodeTranslations = exports.readCodeTranslationFileContent = void 0;
|
|
9
|
+
exports.loadSiteCodeTranslations = exports.applyDefaultCodeTranslations = exports.getPluginsDefaultCodeTranslationMessages = 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"));
|
|
@@ -162,3 +162,9 @@ Please report this Docusaurus issue. name=${unusedDefaultCodeMessages}`;
|
|
|
162
162
|
}));
|
|
163
163
|
}
|
|
164
164
|
exports.applyDefaultCodeTranslations = applyDefaultCodeTranslations;
|
|
165
|
+
async function loadSiteCodeTranslations({ localizationDir, }) {
|
|
166
|
+
const codeTranslationFileContent = (await readCodeTranslationFileContent({ localizationDir })) ?? {};
|
|
167
|
+
// We only need key->message for code translations
|
|
168
|
+
return lodash_1.default.mapValues(codeTranslationFileContent, (value) => value.message);
|
|
169
|
+
}
|
|
170
|
+
exports.loadSiteCodeTranslations = loadSiteCodeTranslations;
|
package/lib/server/utils.d.ts
CHANGED
|
@@ -5,6 +5,4 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import { Globby } from '@docusaurus/utils';
|
|
8
|
-
import type { RouteConfig } from '@docusaurus/types';
|
|
9
|
-
export declare function getAllFinalRoutes(routeConfig: RouteConfig[]): RouteConfig[];
|
|
10
8
|
export declare function safeGlobby(patterns: string[], options?: Globby.GlobbyOptions): Promise<string[]>;
|
package/lib/server/utils.js
CHANGED
|
@@ -6,18 +6,10 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.safeGlobby =
|
|
9
|
+
exports.safeGlobby = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
11
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
12
12
|
const utils_1 = require("@docusaurus/utils");
|
|
13
|
-
// Recursively get the final routes (routes with no subroutes)
|
|
14
|
-
function getAllFinalRoutes(routeConfig) {
|
|
15
|
-
function getFinalRoutes(route) {
|
|
16
|
-
return route.routes ? route.routes.flatMap(getFinalRoutes) : [route];
|
|
17
|
-
}
|
|
18
|
-
return routeConfig.flatMap(getFinalRoutes);
|
|
19
|
-
}
|
|
20
|
-
exports.getAllFinalRoutes = getAllFinalRoutes;
|
|
21
13
|
// Globby that fix Windows path patterns
|
|
22
14
|
// See https://github.com/facebook/docusaurus/pull/4222#issuecomment-795517329
|
|
23
15
|
async function safeGlobby(patterns, options) {
|
package/lib/utils.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ type PerfLoggerAPI = {
|
|
|
3
3
|
start: (label: string) => void;
|
|
4
4
|
end: (label: string) => void;
|
|
5
5
|
log: (message: string) => void;
|
|
6
|
+
async: <Result>(label: string, asyncFn: () => Result | Promise<Result>) => Promise<Result>;
|
|
6
7
|
};
|
|
7
8
|
export declare const PerfLogger: PerfLoggerAPI;
|
|
8
9
|
export {};
|
package/lib/utils.js
CHANGED
|
@@ -19,13 +19,24 @@ function createPerfLogger() {
|
|
|
19
19
|
start: noop,
|
|
20
20
|
end: noop,
|
|
21
21
|
log: noop,
|
|
22
|
+
async: async (_label, asyncFn) => asyncFn(),
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
const prefix = logger_1.default.yellow(`[PERF] `);
|
|
26
|
+
const start = (label) => console.time(prefix + label);
|
|
27
|
+
const end = (label) => console.timeEnd(prefix + label);
|
|
28
|
+
const log = (label) => console.log(prefix + label);
|
|
29
|
+
const async = async (label, asyncFn) => {
|
|
30
|
+
start(label);
|
|
31
|
+
const result = await asyncFn();
|
|
32
|
+
end(label);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
25
35
|
return {
|
|
26
|
-
start
|
|
27
|
-
end
|
|
28
|
-
log
|
|
36
|
+
start,
|
|
37
|
+
end,
|
|
38
|
+
log,
|
|
39
|
+
async,
|
|
29
40
|
};
|
|
30
41
|
}
|
|
31
42
|
exports.PerfLogger = createPerfLogger();
|
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-5860",
|
|
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-
|
|
47
|
-
"@docusaurus/logger": "0.0.0-
|
|
48
|
-
"@docusaurus/mdx-loader": "0.0.0-
|
|
46
|
+
"@docusaurus/cssnano-preset": "0.0.0-5860",
|
|
47
|
+
"@docusaurus/logger": "0.0.0-5860",
|
|
48
|
+
"@docusaurus/mdx-loader": "0.0.0-5860",
|
|
49
49
|
"@docusaurus/react-loadable": "5.5.2",
|
|
50
|
-
"@docusaurus/utils": "0.0.0-
|
|
51
|
-
"@docusaurus/utils-common": "0.0.0-
|
|
52
|
-
"@docusaurus/utils-validation": "0.0.0-
|
|
50
|
+
"@docusaurus/utils": "0.0.0-5860",
|
|
51
|
+
"@docusaurus/utils-common": "0.0.0-5860",
|
|
52
|
+
"@docusaurus/utils-validation": "0.0.0-5860",
|
|
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-
|
|
109
|
-
"@docusaurus/types": "0.0.0-
|
|
108
|
+
"@docusaurus/module-type-aliases": "0.0.0-5860",
|
|
109
|
+
"@docusaurus/types": "0.0.0-5860",
|
|
110
110
|
"@types/detect-port": "^1.3.3",
|
|
111
111
|
"@types/react-dom": "^18.2.7",
|
|
112
112
|
"@types/react-router-config": "^5.0.7",
|
|
@@ -125,5 +125,5 @@
|
|
|
125
125
|
"engines": {
|
|
126
126
|
"node": ">=18.0"
|
|
127
127
|
},
|
|
128
|
-
"gitHead": "
|
|
128
|
+
"gitHead": "dc91f3f6c8cf54d51409a24d823db17eee03a01a"
|
|
129
129
|
}
|