@docusaurus/core 0.0.0-5858 → 0.0.0-5861

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/lib/commands/build.d.ts +2 -2
  2. package/lib/commands/build.js +6 -6
  3. package/lib/commands/deploy.d.ts +2 -2
  4. package/lib/commands/deploy.js +2 -2
  5. package/lib/commands/external.js +2 -2
  6. package/lib/commands/serve.d.ts +2 -2
  7. package/lib/commands/{start.d.ts → start/start.d.ts} +3 -3
  8. package/lib/commands/start/start.js +47 -0
  9. package/lib/commands/start/utils.d.ts +31 -0
  10. package/lib/commands/start/utils.js +88 -0
  11. package/lib/commands/start/watcher.d.ts +42 -0
  12. package/lib/commands/start/watcher.js +78 -0
  13. package/lib/commands/start/webpack.d.ts +15 -0
  14. package/lib/commands/start/webpack.js +133 -0
  15. package/lib/commands/swizzle/context.js +2 -2
  16. package/lib/commands/writeHeadingIds.js +2 -2
  17. package/lib/commands/writeTranslations.d.ts +2 -2
  18. package/lib/commands/writeTranslations.js +2 -2
  19. package/lib/index.d.ts +1 -1
  20. package/lib/index.js +1 -1
  21. package/lib/server/brokenLinks.js +2 -2
  22. package/lib/server/codegen/codegen.d.ts +20 -0
  23. package/lib/server/codegen/codegen.js +65 -0
  24. package/lib/server/codegen/codegenRoutes.d.ts +49 -0
  25. package/lib/server/codegen/codegenRoutes.js +190 -0
  26. package/lib/server/i18n.d.ts +2 -2
  27. package/lib/server/plugins/actions.d.ts +19 -0
  28. package/lib/server/plugins/actions.js +61 -0
  29. package/lib/server/plugins/plugins.d.ts +27 -0
  30. package/lib/server/plugins/plugins.js +228 -0
  31. package/lib/server/plugins/routeConfig.d.ts +1 -1
  32. package/lib/server/plugins/routeConfig.js +4 -4
  33. package/lib/server/routes.d.ts +4 -45
  34. package/lib/server/routes.js +15 -166
  35. package/lib/server/{index.d.ts → site.d.ts} +12 -4
  36. package/lib/server/site.js +167 -0
  37. package/lib/server/translations/translations.d.ts +3 -0
  38. package/lib/server/translations/translations.js +7 -1
  39. package/lib/server/utils.d.ts +0 -2
  40. package/lib/server/utils.js +1 -9
  41. package/lib/utils.d.ts +1 -0
  42. package/lib/utils.js +14 -3
  43. package/package.json +11 -10
  44. package/lib/commands/start.js +0 -242
  45. package/lib/server/index.js +0 -154
  46. package/lib/server/plugins/index.d.ts +0 -18
  47. package/lib/server/plugins/index.js +0 -106
@@ -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;
@@ -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[]>;
@@ -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 = exports.getAllFinalRoutes = void 0;
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: (label) => console.time(prefix + label),
27
- end: (label) => console.timeEnd(prefix + label),
28
- log: (label) => console.log(prefix + label),
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-5858",
4
+ "version": "0.0.0-5861",
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-5858",
47
- "@docusaurus/logger": "0.0.0-5858",
48
- "@docusaurus/mdx-loader": "0.0.0-5858",
46
+ "@docusaurus/cssnano-preset": "0.0.0-5861",
47
+ "@docusaurus/logger": "0.0.0-5861",
48
+ "@docusaurus/mdx-loader": "0.0.0-5861",
49
49
  "@docusaurus/react-loadable": "5.5.2",
50
- "@docusaurus/utils": "0.0.0-5858",
51
- "@docusaurus/utils-common": "0.0.0-5858",
52
- "@docusaurus/utils-validation": "0.0.0-5858",
50
+ "@docusaurus/utils": "0.0.0-5861",
51
+ "@docusaurus/utils-common": "0.0.0-5861",
52
+ "@docusaurus/utils-validation": "0.0.0-5861",
53
53
  "@svgr/webpack": "^6.5.1",
54
54
  "autoprefixer": "^10.4.14",
55
55
  "babel-loader": "^9.1.3",
@@ -105,8 +105,9 @@
105
105
  "webpackbar": "^5.0.2"
106
106
  },
107
107
  "devDependencies": {
108
- "@docusaurus/module-type-aliases": "0.0.0-5858",
109
- "@docusaurus/types": "0.0.0-5858",
108
+ "@docusaurus/module-type-aliases": "0.0.0-5861",
109
+ "@docusaurus/types": "0.0.0-5861",
110
+ "@total-typescript/shoehorn": "^0.1.2",
110
111
  "@types/detect-port": "^1.3.3",
111
112
  "@types/react-dom": "^18.2.7",
112
113
  "@types/react-router-config": "^5.0.7",
@@ -125,5 +126,5 @@
125
126
  "engines": {
126
127
  "node": ">=18.0"
127
128
  },
128
- "gitHead": "03c831aae7cfffd88cb38425971139a865a79a40"
129
+ "gitHead": "f6dfa0af9be06d1e24f30243244145fdc03fb25c"
129
130
  }
@@ -1,242 +0,0 @@
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.start = void 0;
10
- const tslib_1 = require("tslib");
11
- const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
- const path_1 = tslib_1.__importDefault(require("path"));
13
- const lodash_1 = tslib_1.__importDefault(require("lodash"));
14
- const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
15
- const utils_1 = require("@docusaurus/utils");
16
- const chokidar_1 = tslib_1.__importDefault(require("chokidar"));
17
- const openBrowser_1 = tslib_1.__importDefault(require("react-dev-utils/openBrowser"));
18
- const WebpackDevServerUtils_1 = require("react-dev-utils/WebpackDevServerUtils");
19
- const evalSourceMapMiddleware_1 = tslib_1.__importDefault(require("react-dev-utils/evalSourceMapMiddleware"));
20
- const webpack_1 = tslib_1.__importDefault(require("webpack"));
21
- const webpack_dev_server_1 = tslib_1.__importDefault(require("webpack-dev-server"));
22
- const webpack_merge_1 = tslib_1.__importDefault(require("webpack-merge"));
23
- const server_1 = require("../server");
24
- const client_1 = require("../webpack/client");
25
- const utils_2 = require("../webpack/utils");
26
- const getHostPort_1 = require("../server/getHostPort");
27
- const utils_3 = require("../utils");
28
- async function start(siteDirParam = '.', cliOptions = {}) {
29
- // Temporary workaround to unlock the ability to translate the site config
30
- // We'll remove it if a better official API can be designed
31
- // See https://github.com/facebook/docusaurus/issues/4542
32
- process.env.DOCUSAURUS_CURRENT_LOCALE = cliOptions.locale;
33
- const siteDir = await fs_extra_1.default.realpath(siteDirParam);
34
- logger_1.default.info('Starting the development server...');
35
- async function loadSite() {
36
- utils_3.PerfLogger.start('Loading site');
37
- const result = await (0, server_1.load)({
38
- siteDir,
39
- config: cliOptions.config,
40
- locale: cliOptions.locale,
41
- localizePath: undefined, // Should this be configurable?
42
- });
43
- utils_3.PerfLogger.end('Loading site');
44
- return result;
45
- }
46
- // Process all related files as a prop.
47
- const props = await loadSite();
48
- const { host, port, getOpenUrl } = await createUrlUtils({ cliOptions });
49
- const openUrl = getOpenUrl({ baseUrl: props.baseUrl });
50
- logger_1.default.success `Docusaurus website is running at: url=${openUrl}`;
51
- // Reload files processing.
52
- const reload = lodash_1.default.debounce(() => {
53
- loadSite()
54
- .then(({ baseUrl: newBaseUrl }) => {
55
- const newOpenUrl = getOpenUrl({ baseUrl: newBaseUrl });
56
- if (newOpenUrl !== openUrl) {
57
- logger_1.default.success `Docusaurus website is running at: url=${newOpenUrl}`;
58
- }
59
- })
60
- .catch((err) => {
61
- logger_1.default.error(err.stack);
62
- });
63
- }, 500);
64
- // TODO this is historically not optimized!
65
- // When any site file changes, we reload absolutely everything :/
66
- // At least we should try to reload only one plugin individually?
67
- setupFileWatchers({
68
- props,
69
- cliOptions,
70
- onFileChange: () => {
71
- reload();
72
- },
73
- });
74
- const config = await getStartClientConfig({
75
- props,
76
- minify: cliOptions.minify ?? true,
77
- poll: cliOptions.poll,
78
- });
79
- const compiler = (0, webpack_1.default)(config);
80
- registerE2ETestHook(compiler);
81
- const defaultDevServerConfig = await createDevServerConfig({
82
- cliOptions,
83
- props,
84
- host,
85
- port,
86
- });
87
- // Allow plugin authors to customize/override devServer config
88
- const devServerConfig = (0, webpack_merge_1.default)([defaultDevServerConfig, config.devServer].filter(Boolean));
89
- const devServer = new webpack_dev_server_1.default(devServerConfig, compiler);
90
- devServer.startCallback(() => {
91
- if (cliOptions.open) {
92
- (0, openBrowser_1.default)(openUrl);
93
- }
94
- });
95
- ['SIGINT', 'SIGTERM'].forEach((sig) => {
96
- process.on(sig, () => {
97
- devServer.stop();
98
- process.exit();
99
- });
100
- });
101
- }
102
- exports.start = start;
103
- function createPollingOptions({ cliOptions }) {
104
- return {
105
- usePolling: !!cliOptions.poll,
106
- interval: Number.isInteger(cliOptions.poll)
107
- ? cliOptions.poll
108
- : undefined,
109
- };
110
- }
111
- function setupFileWatchers({ props, cliOptions, onFileChange, }) {
112
- const { siteDir } = props;
113
- const pathsToWatch = getPathsToWatch({ props });
114
- const pollingOptions = createPollingOptions({ cliOptions });
115
- const fsWatcher = chokidar_1.default.watch(pathsToWatch, {
116
- cwd: siteDir,
117
- ignoreInitial: true,
118
- ...{ pollingOptions },
119
- });
120
- ['add', 'change', 'unlink', 'addDir', 'unlinkDir'].forEach((event) => fsWatcher.on(event, onFileChange));
121
- }
122
- function getPathsToWatch({ props }) {
123
- const { siteDir, siteConfigPath, plugins, localizationDir } = props;
124
- const normalizeToSiteDir = (filepath) => {
125
- if (filepath && path_1.default.isAbsolute(filepath)) {
126
- return (0, utils_1.posixPath)(path_1.default.relative(siteDir, filepath));
127
- }
128
- return (0, utils_1.posixPath)(filepath);
129
- };
130
- const pluginsPaths = plugins
131
- .flatMap((plugin) => plugin.getPathsToWatch?.() ?? [])
132
- .filter(Boolean)
133
- .map(normalizeToSiteDir);
134
- return [...pluginsPaths, siteConfigPath, localizationDir];
135
- }
136
- async function createUrlUtils({ cliOptions }) {
137
- const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
138
- const { host, port } = await (0, getHostPort_1.getHostPort)(cliOptions);
139
- if (port === null) {
140
- return process.exit();
141
- }
142
- const getOpenUrl = ({ baseUrl }) => {
143
- const urls = (0, WebpackDevServerUtils_1.prepareUrls)(protocol, host, port);
144
- return (0, utils_1.normalizeUrl)([urls.localUrlForBrowser, baseUrl]);
145
- };
146
- return { host, port, getOpenUrl };
147
- }
148
- async function createDevServerConfig({ cliOptions, props, host, port, }) {
149
- const { baseUrl, siteDir, siteConfig } = props;
150
- const pollingOptions = createPollingOptions({ cliOptions });
151
- const httpsConfig = await (0, utils_2.getHttpsConfig)();
152
- // https://webpack.js.org/configuration/dev-server
153
- return {
154
- hot: cliOptions.hotOnly ? 'only' : true,
155
- liveReload: false,
156
- client: {
157
- progress: true,
158
- overlay: {
159
- warnings: false,
160
- errors: true,
161
- },
162
- webSocketURL: {
163
- hostname: '0.0.0.0',
164
- port: 0,
165
- },
166
- },
167
- headers: {
168
- 'access-control-allow-origin': '*',
169
- },
170
- devMiddleware: {
171
- publicPath: baseUrl,
172
- // Reduce log verbosity, see https://github.com/facebook/docusaurus/pull/5420#issuecomment-906613105
173
- stats: 'summary',
174
- },
175
- static: siteConfig.staticDirectories.map((dir) => ({
176
- publicPath: baseUrl,
177
- directory: path_1.default.resolve(siteDir, dir),
178
- watch: {
179
- // Useful options for our own monorepo using symlinks!
180
- // See https://github.com/webpack/webpack/issues/11612#issuecomment-879259806
181
- followSymlinks: true,
182
- ignored: /node_modules\/(?!@docusaurus)/,
183
- ...{ pollingOptions },
184
- },
185
- })),
186
- ...(httpsConfig && {
187
- server: typeof httpsConfig === 'object'
188
- ? {
189
- type: 'https',
190
- options: httpsConfig,
191
- }
192
- : 'https',
193
- }),
194
- historyApiFallback: {
195
- rewrites: [{ from: /\/*/, to: baseUrl }],
196
- },
197
- allowedHosts: 'all',
198
- host,
199
- port,
200
- setupMiddlewares: (middlewares, devServer) => {
201
- // This lets us fetch source contents from webpack for the error overlay.
202
- middlewares.unshift((0, evalSourceMapMiddleware_1.default)(devServer));
203
- return middlewares;
204
- },
205
- };
206
- }
207
- // E2E_TEST=true docusaurus start
208
- // Makes "docusaurus start" exit immediately on success/error, for E2E test
209
- function registerE2ETestHook(compiler) {
210
- compiler.hooks.done.tap('done', (stats) => {
211
- const errorsWarnings = stats.toJson('errors-warnings');
212
- const statsErrorMessage = (0, utils_2.formatStatsErrorMessage)(errorsWarnings);
213
- if (statsErrorMessage) {
214
- console.error(statsErrorMessage);
215
- }
216
- (0, utils_2.printStatsWarnings)(errorsWarnings);
217
- if (process.env.E2E_TEST) {
218
- if (stats.hasErrors()) {
219
- logger_1.default.error('E2E_TEST: Project has compiler errors.');
220
- process.exit(1);
221
- }
222
- logger_1.default.success('E2E_TEST: Project can compile.');
223
- process.exit(0);
224
- }
225
- });
226
- }
227
- async function getStartClientConfig({ props, minify, poll, }) {
228
- const { plugins, siteConfig } = props;
229
- let { clientConfig: config } = await (0, client_1.createStartClientConfig)({
230
- props,
231
- minify,
232
- poll,
233
- });
234
- config = (0, utils_2.executePluginsConfigurePostCss)({ plugins, config });
235
- config = (0, utils_2.executePluginsConfigureWebpack)({
236
- plugins,
237
- config,
238
- isServer: false,
239
- jsLoader: siteConfig.webpack?.jsLoader,
240
- });
241
- return config;
242
- }