@docusaurus/core 3.1.0 → 3.2.0

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 (88) hide show
  1. package/bin/docusaurus.mjs +10 -5
  2. package/lib/client/BrokenLinksContext.js +2 -2
  3. package/lib/client/exports/Link.js +10 -2
  4. package/lib/client/{serverRenderer.d.ts → renderToHtml.d.ts} +1 -1
  5. package/lib/client/{serverRenderer.js → renderToHtml.js} +1 -1
  6. package/lib/client/serverEntry.d.ts +3 -4
  7. package/lib/client/serverEntry.js +12 -113
  8. package/lib/client/theme-fallback/Error/index.js +22 -8
  9. package/lib/commands/build.d.ts +3 -3
  10. package/lib/commands/build.js +133 -112
  11. package/lib/commands/deploy.d.ts +2 -2
  12. package/lib/commands/deploy.js +3 -3
  13. package/lib/commands/external.js +2 -2
  14. package/lib/commands/serve.d.ts +2 -2
  15. package/lib/commands/serve.js +4 -4
  16. package/lib/commands/{start.d.ts → start/start.d.ts} +3 -3
  17. package/lib/commands/start/start.js +47 -0
  18. package/lib/commands/start/utils.d.ts +31 -0
  19. package/lib/commands/start/utils.js +87 -0
  20. package/lib/commands/start/watcher.d.ts +42 -0
  21. package/lib/commands/start/watcher.js +78 -0
  22. package/lib/commands/start/webpack.d.ts +15 -0
  23. package/lib/commands/start/webpack.js +133 -0
  24. package/lib/commands/swizzle/common.d.ts +1 -0
  25. package/lib/commands/swizzle/common.js +1 -0
  26. package/lib/commands/swizzle/context.js +2 -2
  27. package/lib/commands/swizzle/index.js +32 -3
  28. package/lib/commands/writeHeadingIds.js +2 -2
  29. package/lib/commands/writeTranslations.d.ts +2 -2
  30. package/lib/commands/writeTranslations.js +3 -3
  31. package/lib/index.d.ts +1 -1
  32. package/lib/index.js +1 -1
  33. package/lib/server/brokenLinks.js +126 -39
  34. package/lib/server/clientModules.d.ts +1 -1
  35. package/lib/server/clientModules.js +3 -3
  36. package/lib/server/codegen/codegen.d.ts +20 -0
  37. package/lib/server/codegen/codegen.js +65 -0
  38. package/lib/server/codegen/codegenRoutes.d.ts +49 -0
  39. package/lib/server/codegen/codegenRoutes.js +190 -0
  40. package/lib/server/configValidation.js +6 -4
  41. package/lib/server/getHostPort.js +4 -1
  42. package/lib/server/i18n.d.ts +2 -2
  43. package/lib/server/i18n.js +20 -2
  44. package/lib/server/plugins/actions.d.ts +19 -0
  45. package/lib/server/plugins/actions.js +62 -0
  46. package/lib/server/plugins/init.js +3 -3
  47. package/lib/server/plugins/plugins.d.ts +21 -0
  48. package/lib/server/plugins/plugins.js +188 -0
  49. package/lib/server/plugins/pluginsUtils.d.ts +16 -0
  50. package/lib/server/plugins/pluginsUtils.js +75 -0
  51. package/lib/server/plugins/routeConfig.d.ts +1 -1
  52. package/lib/server/plugins/routeConfig.js +4 -4
  53. package/lib/server/plugins/synthetic.d.ts +3 -3
  54. package/lib/server/plugins/synthetic.js +0 -2
  55. package/lib/server/routes.d.ts +3 -45
  56. package/lib/server/routes.js +21 -165
  57. package/lib/server/{index.d.ts → site.d.ts} +12 -5
  58. package/lib/server/site.js +164 -0
  59. package/lib/server/siteMetadata.d.ts +5 -4
  60. package/lib/server/siteMetadata.js +14 -10
  61. package/lib/server/translations/translations.d.ts +9 -2
  62. package/lib/server/translations/translations.js +21 -4
  63. package/lib/server/utils.d.ts +0 -2
  64. package/lib/server/utils.js +1 -9
  65. package/lib/ssg.d.ts +31 -0
  66. package/lib/ssg.js +167 -0
  67. package/lib/templates/templates.d.ts +28 -0
  68. package/lib/templates/templates.js +63 -0
  69. package/lib/utils.d.ts +9 -0
  70. package/lib/utils.js +78 -0
  71. package/lib/webpack/base.d.ts +5 -1
  72. package/lib/webpack/base.js +4 -6
  73. package/lib/webpack/client.d.ts +15 -1
  74. package/lib/webpack/client.js +78 -23
  75. package/lib/webpack/minification.d.ts +8 -0
  76. package/lib/webpack/minification.js +97 -0
  77. package/lib/webpack/server.d.ts +5 -3
  78. package/lib/webpack/server.js +41 -50
  79. package/lib/webpack/utils.d.ts +13 -4
  80. package/lib/webpack/utils.js +27 -83
  81. package/package.json +13 -11
  82. package/lib/commands/start.js +0 -212
  83. package/lib/server/index.js +0 -154
  84. package/lib/server/plugins/index.d.ts +0 -18
  85. package/lib/server/plugins/index.js +0 -106
  86. /package/lib/{webpack/templates/index.html.template.ejs → templates/dev.html.template.ejs} +0 -0
  87. /package/lib/{webpack/templates → templates}/ssr.html.template.d.ts +0 -0
  88. /package/lib/{webpack/templates → templates}/ssr.html.template.js +0 -0
@@ -14,7 +14,7 @@ const os_1 = tslib_1.__importDefault(require("os"));
14
14
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
15
15
  const shelljs_1 = tslib_1.__importDefault(require("shelljs"));
16
16
  const utils_1 = require("@docusaurus/utils");
17
- const server_1 = require("../server");
17
+ const site_1 = require("../server/site");
18
18
  const build_1 = require("./build");
19
19
  // GIT_PASS env variable should not appear in logs
20
20
  function obfuscateGitPass(str) {
@@ -36,7 +36,7 @@ function shellExecLog(cmd) {
36
36
  }
37
37
  async function deploy(siteDirParam = '.', cliOptions = {}) {
38
38
  const siteDir = await fs_extra_1.default.realpath(siteDirParam);
39
- const { outDir, siteConfig, siteConfigPath } = await (0, server_1.loadContext)({
39
+ const { outDir, siteConfig, siteConfigPath } = await (0, site_1.loadContext)({
40
40
  siteDir,
41
41
  config: cliOptions.config,
42
42
  outDir: cliOptions.outDir,
@@ -184,7 +184,7 @@ You can also set the deploymentBranch property in docusaurus.config.js .`);
184
184
  if (!cliOptions.skipBuild) {
185
185
  // Build site, then push to deploymentBranch branch of specified repo.
186
186
  try {
187
- await (0, build_1.build)(siteDir, cliOptions, false).then(runDeploy);
187
+ await (0, build_1.build)(siteDir, cliOptions, false).then(() => runDeploy(outDir));
188
188
  }
189
189
  catch (err) {
190
190
  logger_1.default.error('Deployment of the build output failed.');
@@ -9,11 +9,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.externalCommand = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
- const server_1 = require("../server");
12
+ const site_1 = require("../server/site");
13
13
  const init_1 = require("../server/plugins/init");
14
14
  async function externalCommand(cli) {
15
15
  const siteDir = await fs_extra_1.default.realpath('.');
16
- const context = await (0, server_1.loadContext)({ siteDir });
16
+ const context = await (0, site_1.loadContext)({ siteDir });
17
17
  const plugins = await (0, init_1.initPlugins)(context);
18
18
  // Plugin Lifecycle - extendCli.
19
19
  plugins.forEach((plugin) => {
@@ -5,8 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { type HostPortOptions } from '../server/getHostPort';
8
- import type { LoadContextOptions } from '../server';
9
- export type ServeCLIOptions = HostPortOptions & Pick<LoadContextOptions, 'config'> & {
8
+ import type { LoadContextParams } from '../server/site';
9
+ export type ServeCLIOptions = HostPortOptions & Pick<LoadContextParams, 'config'> & {
10
10
  dir?: string;
11
11
  build?: boolean;
12
12
  open?: boolean;
@@ -21,11 +21,11 @@ const getHostPort_1 = require("../server/getHostPort");
21
21
  async function serve(siteDirParam = '.', cliOptions = {}) {
22
22
  const siteDir = await fs_extra_1.default.realpath(siteDirParam);
23
23
  const buildDir = cliOptions.dir ?? utils_1.DEFAULT_BUILD_DIR_NAME;
24
- let dir = path_1.default.resolve(siteDir, buildDir);
24
+ const outDir = path_1.default.resolve(siteDir, buildDir);
25
25
  if (cliOptions.build) {
26
- dir = await (0, build_1.build)(siteDir, {
26
+ await (0, build_1.build)(siteDir, {
27
27
  config: cliOptions.config,
28
- outDir: dir,
28
+ outDir,
29
29
  }, false);
30
30
  }
31
31
  const { host, port } = await (0, getHostPort_1.getHostPort)(cliOptions);
@@ -51,7 +51,7 @@ async function serve(siteDirParam = '.', cliOptions = {}) {
51
51
  req.url = req.url.replace(baseUrl, '/');
52
52
  (0, serve_handler_1.default)(req, res, {
53
53
  cleanUrls: true,
54
- public: dir,
54
+ public: outDir,
55
55
  trailingSlash,
56
56
  directoryListing: false,
57
57
  });
@@ -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 LoadContextOptions } from '../server';
8
- import { type HostPortOptions } from '../server/getHostPort';
9
- export type StartCLIOptions = HostPortOptions & Pick<LoadContextOptions, 'locale' | 'config'> & {
7
+ import type { LoadContextParams } from '../../server/site';
8
+ import type { HostPortOptions } from '../../server/getHostPort';
9
+ export type StartCLIOptions = HostPortOptions & Pick<LoadContextParams, 'locale' | 'config'> & {
10
10
  hotOnly?: boolean;
11
11
  open?: boolean;
12
12
  poll?: boolean | number;
@@ -0,0 +1,47 @@
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 logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
12
+ const openBrowser_1 = tslib_1.__importDefault(require("react-dev-utils/openBrowser"));
13
+ const watcher_1 = require("./watcher");
14
+ const webpack_1 = require("./webpack");
15
+ const utils_1 = require("./utils");
16
+ async function start(siteDirParam = '.', cliOptions = {}) {
17
+ logger_1.default.info('Starting the development server...');
18
+ // Temporary workaround to unlock the ability to translate the site config
19
+ // We'll remove it if a better official API can be designed
20
+ // See https://github.com/facebook/docusaurus/issues/4542
21
+ process.env.DOCUSAURUS_CURRENT_LOCALE = cliOptions.locale;
22
+ const reloadableSite = await (0, utils_1.createReloadableSite)({ siteDirParam, cliOptions });
23
+ (0, watcher_1.setupSiteFileWatchers)({ props: reloadableSite.get().props, cliOptions }, ({ plugin }) => {
24
+ if (plugin) {
25
+ reloadableSite.reloadPlugin(plugin);
26
+ }
27
+ else {
28
+ reloadableSite.reload();
29
+ }
30
+ });
31
+ const devServer = await (0, webpack_1.createWebpackDevServer)({
32
+ props: reloadableSite.get().props,
33
+ cliOptions,
34
+ openUrlContext: reloadableSite.openUrlContext,
35
+ });
36
+ ['SIGINT', 'SIGTERM'].forEach((sig) => {
37
+ process.on(sig, () => {
38
+ devServer.stop();
39
+ process.exit();
40
+ });
41
+ });
42
+ await devServer.start();
43
+ if (cliOptions.open) {
44
+ (0, openBrowser_1.default)(reloadableSite.getOpenUrl());
45
+ }
46
+ }
47
+ exports.start = start;
@@ -0,0 +1,31 @@
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 _ from 'lodash';
8
+ import type { StartCLIOptions } from './start';
9
+ import type { LoadedPlugin } from '@docusaurus/types';
10
+ export type OpenUrlContext = {
11
+ host: string;
12
+ port: number;
13
+ getOpenUrl: ({ baseUrl }: {
14
+ baseUrl: string;
15
+ }) => string;
16
+ };
17
+ export declare function createOpenUrlContext({ cliOptions, }: {
18
+ cliOptions: StartCLIOptions;
19
+ }): Promise<OpenUrlContext>;
20
+ type StartParams = {
21
+ siteDirParam: string;
22
+ cliOptions: Partial<StartCLIOptions>;
23
+ };
24
+ export declare function createReloadableSite(startParams: StartParams): Promise<{
25
+ get: () => import("../../server/site").Site;
26
+ getOpenUrl: () => string;
27
+ reload: _.DebouncedFunc<() => Promise<void>>;
28
+ reloadPlugin: (plugin: LoadedPlugin) => Promise<void>;
29
+ openUrlContext: OpenUrlContext;
30
+ }>;
31
+ export {};
@@ -0,0 +1,87 @@
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.createReloadableSite = exports.createOpenUrlContext = void 0;
10
+ const tslib_1 = require("tslib");
11
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
13
+ const WebpackDevServerUtils_1 = require("react-dev-utils/WebpackDevServerUtils");
14
+ const utils_1 = require("@docusaurus/utils");
15
+ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
16
+ const getHostPort_1 = require("../../server/getHostPort");
17
+ const utils_2 = require("../../utils");
18
+ const site_1 = require("../../server/site");
19
+ const pluginsUtils_1 = require("../../server/plugins/pluginsUtils");
20
+ async function createOpenUrlContext({ cliOptions, }) {
21
+ const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
22
+ const { host, port } = await (0, getHostPort_1.getHostPort)(cliOptions);
23
+ if (port === null) {
24
+ return process.exit();
25
+ }
26
+ const getOpenUrl = ({ baseUrl }) => {
27
+ const urls = (0, WebpackDevServerUtils_1.prepareUrls)(protocol, host, port);
28
+ return (0, utils_1.normalizeUrl)([urls.localUrlForBrowser, baseUrl]);
29
+ };
30
+ return { host, port, getOpenUrl };
31
+ }
32
+ exports.createOpenUrlContext = createOpenUrlContext;
33
+ async function createLoadSiteParams({ siteDirParam, cliOptions, }) {
34
+ const siteDir = await fs_extra_1.default.realpath(siteDirParam);
35
+ return {
36
+ siteDir,
37
+ config: cliOptions.config,
38
+ locale: cliOptions.locale,
39
+ localizePath: undefined, // Should this be configurable?
40
+ };
41
+ }
42
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
43
+ async function createReloadableSite(startParams) {
44
+ const openUrlContext = await createOpenUrlContext(startParams);
45
+ const loadSiteParams = await utils_2.PerfLogger.async('createLoadSiteParams', () => createLoadSiteParams(startParams));
46
+ let site = await utils_2.PerfLogger.async('Load site', () => (0, site_1.loadSite)(loadSiteParams));
47
+ const get = () => site;
48
+ const getOpenUrl = () => openUrlContext.getOpenUrl({
49
+ baseUrl: site.props.baseUrl,
50
+ });
51
+ const printOpenUrlMessage = () => {
52
+ logger_1.default.success `Docusaurus website is running at: url=${getOpenUrl()}`;
53
+ };
54
+ printOpenUrlMessage();
55
+ const reloadBase = async () => {
56
+ try {
57
+ const oldSite = site;
58
+ site = await utils_2.PerfLogger.async('Reload site', () => (0, site_1.reloadSite)(site));
59
+ if (oldSite.props.baseUrl !== site.props.baseUrl) {
60
+ printOpenUrlMessage();
61
+ }
62
+ }
63
+ catch (e) {
64
+ logger_1.default.error('Site reload failure');
65
+ console.error(e);
66
+ }
67
+ };
68
+ // TODO instead of debouncing we should rather add AbortController support?
69
+ const reload = lodash_1.default.debounce(reloadBase, 500);
70
+ // TODO this could be subject to plugin reloads race conditions
71
+ // In practice, it is not likely the user will hot reload 2 plugins at once
72
+ // but we should still support it and probably use a task queuing system
73
+ const reloadPlugin = async (plugin) => {
74
+ try {
75
+ site = await utils_2.PerfLogger.async(`Reload site plugin ${(0, pluginsUtils_1.formatPluginName)(plugin)}`, () => {
76
+ const pluginIdentifier = { name: plugin.name, id: plugin.options.id };
77
+ return (0, site_1.reloadSitePlugin)(site, pluginIdentifier);
78
+ });
79
+ }
80
+ catch (e) {
81
+ logger_1.default.error(`Site plugin reload failure - Plugin ${(0, pluginsUtils_1.formatPluginName)(plugin)}`);
82
+ console.error(e);
83
+ }
84
+ };
85
+ return { get, getOpenUrl, reload, reloadPlugin, openUrlContext };
86
+ }
87
+ exports.createReloadableSite = createReloadableSite;
@@ -0,0 +1,42 @@
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 { StartCLIOptions } from './start';
8
+ import type { LoadedPlugin, Props } from '@docusaurus/types';
9
+ type PollingOptions = {
10
+ usePolling: boolean;
11
+ interval: number | undefined;
12
+ };
13
+ export declare function createPollingOptions(cliOptions: StartCLIOptions): PollingOptions;
14
+ export type FileWatchEventName = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir';
15
+ export type FileWatchEvent = {
16
+ name: FileWatchEventName;
17
+ path: string;
18
+ };
19
+ type WatchParams = {
20
+ pathsToWatch: string[];
21
+ siteDir: string;
22
+ } & PollingOptions;
23
+ /**
24
+ * Watch file system paths for changes and emit events
25
+ * Returns an async handle to stop watching
26
+ */
27
+ export declare function watch(params: WatchParams, callback: (event: FileWatchEvent) => void): () => Promise<void>;
28
+ export declare function getSitePathsToWatch({ props }: {
29
+ props: Props;
30
+ }): string[];
31
+ export declare function getPluginPathsToWatch({ siteDir, plugin, }: {
32
+ siteDir: string;
33
+ plugin: LoadedPlugin;
34
+ }): string[];
35
+ export declare function setupSiteFileWatchers({ props, cliOptions, }: {
36
+ props: Props;
37
+ cliOptions: StartCLIOptions;
38
+ }, callback: (params: {
39
+ plugin: LoadedPlugin | null;
40
+ event: FileWatchEvent;
41
+ }) => void): void;
42
+ export {};
@@ -0,0 +1,78 @@
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.setupSiteFileWatchers = exports.getPluginPathsToWatch = exports.getSitePathsToWatch = exports.watch = exports.createPollingOptions = void 0;
10
+ const tslib_1 = require("tslib");
11
+ const path_1 = tslib_1.__importDefault(require("path"));
12
+ const chokidar_1 = tslib_1.__importDefault(require("chokidar"));
13
+ const utils_1 = require("@docusaurus/utils");
14
+ function createPollingOptions(cliOptions) {
15
+ return {
16
+ usePolling: !!cliOptions.poll,
17
+ interval: Number.isInteger(cliOptions.poll)
18
+ ? cliOptions.poll
19
+ : undefined,
20
+ };
21
+ }
22
+ exports.createPollingOptions = createPollingOptions;
23
+ /**
24
+ * Watch file system paths for changes and emit events
25
+ * Returns an async handle to stop watching
26
+ */
27
+ function watch(params, callback) {
28
+ const { pathsToWatch, siteDir, ...options } = params;
29
+ const fsWatcher = chokidar_1.default.watch(pathsToWatch, {
30
+ cwd: siteDir,
31
+ ignoreInitial: true,
32
+ ...options,
33
+ });
34
+ fsWatcher.on('all', (name, eventPath) => callback({ name, path: eventPath }));
35
+ return () => fsWatcher.close();
36
+ }
37
+ exports.watch = watch;
38
+ function getSitePathsToWatch({ props }) {
39
+ return [
40
+ // TODO we should also watch all imported modules!
41
+ // Use https://github.com/vercel/nft ?
42
+ props.siteConfigPath,
43
+ props.localizationDir,
44
+ ];
45
+ }
46
+ exports.getSitePathsToWatch = getSitePathsToWatch;
47
+ function getPluginPathsToWatch({ siteDir, plugin, }) {
48
+ const normalizeToSiteDir = (filepath) => {
49
+ if (filepath && path_1.default.isAbsolute(filepath)) {
50
+ return (0, utils_1.posixPath)(path_1.default.relative(siteDir, filepath));
51
+ }
52
+ return (0, utils_1.posixPath)(filepath);
53
+ };
54
+ return (plugin.getPathsToWatch?.() ?? [])
55
+ .filter(Boolean)
56
+ .map(normalizeToSiteDir);
57
+ }
58
+ exports.getPluginPathsToWatch = getPluginPathsToWatch;
59
+ function setupSiteFileWatchers({ props, cliOptions, }, callback) {
60
+ const { siteDir } = props;
61
+ const pollingOptions = createPollingOptions(cliOptions);
62
+ // TODO on config / or local plugin updates,
63
+ // the getFilePathsToWatch lifecycle code might get updated
64
+ // so we should probably reset the watchers?
65
+ watch({
66
+ pathsToWatch: getSitePathsToWatch({ props }),
67
+ siteDir: props.siteDir,
68
+ ...pollingOptions,
69
+ }, (event) => callback({ plugin: null, event }));
70
+ props.plugins.forEach((plugin) => {
71
+ watch({
72
+ pathsToWatch: getPluginPathsToWatch({ plugin, siteDir }),
73
+ siteDir,
74
+ ...pollingOptions,
75
+ }, (event) => callback({ plugin, event }));
76
+ });
77
+ }
78
+ exports.setupSiteFileWatchers = setupSiteFileWatchers;
@@ -0,0 +1,15 @@
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 WebpackDevServer from 'webpack-dev-server';
8
+ import type { StartCLIOptions } from './start';
9
+ import type { Props } from '@docusaurus/types';
10
+ import type { OpenUrlContext } from './utils';
11
+ export declare function createWebpackDevServer({ props, cliOptions, openUrlContext, }: {
12
+ props: Props;
13
+ cliOptions: StartCLIOptions;
14
+ openUrlContext: OpenUrlContext;
15
+ }): Promise<WebpackDevServer>;
@@ -0,0 +1,133 @@
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.createWebpackDevServer = void 0;
10
+ const tslib_1 = require("tslib");
11
+ const path_1 = tslib_1.__importDefault(require("path"));
12
+ const webpack_merge_1 = tslib_1.__importDefault(require("webpack-merge"));
13
+ const webpack_1 = tslib_1.__importDefault(require("webpack"));
14
+ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
15
+ const webpack_dev_server_1 = tslib_1.__importDefault(require("webpack-dev-server"));
16
+ const evalSourceMapMiddleware_1 = tslib_1.__importDefault(require("react-dev-utils/evalSourceMapMiddleware"));
17
+ const watcher_1 = require("./watcher");
18
+ const utils_1 = require("../../webpack/utils");
19
+ const client_1 = require("../../webpack/client");
20
+ // E2E_TEST=true docusaurus start
21
+ // Makes "docusaurus start" exit immediately on success/error, for E2E test
22
+ function registerWebpackE2ETestHook(compiler) {
23
+ compiler.hooks.done.tap('done', (stats) => {
24
+ const errorsWarnings = stats.toJson('errors-warnings');
25
+ const statsErrorMessage = (0, utils_1.formatStatsErrorMessage)(errorsWarnings);
26
+ if (statsErrorMessage) {
27
+ console.error(statsErrorMessage);
28
+ }
29
+ (0, utils_1.printStatsWarnings)(errorsWarnings);
30
+ if (process.env.E2E_TEST) {
31
+ if (stats.hasErrors()) {
32
+ logger_1.default.error('E2E_TEST: Project has compiler errors.');
33
+ process.exit(1);
34
+ }
35
+ logger_1.default.success('E2E_TEST: Project can compile.');
36
+ process.exit(0);
37
+ }
38
+ });
39
+ }
40
+ async function createDevServerConfig({ cliOptions, props, host, port, }) {
41
+ const { baseUrl, siteDir, siteConfig } = props;
42
+ const pollingOptions = (0, watcher_1.createPollingOptions)(cliOptions);
43
+ const httpsConfig = await (0, utils_1.getHttpsConfig)();
44
+ // https://webpack.js.org/configuration/dev-server
45
+ return {
46
+ hot: cliOptions.hotOnly ? 'only' : true,
47
+ liveReload: false,
48
+ client: {
49
+ progress: true,
50
+ overlay: {
51
+ warnings: false,
52
+ errors: true,
53
+ },
54
+ webSocketURL: {
55
+ hostname: '0.0.0.0',
56
+ port: 0,
57
+ },
58
+ },
59
+ headers: {
60
+ 'access-control-allow-origin': '*',
61
+ },
62
+ devMiddleware: {
63
+ publicPath: baseUrl,
64
+ // Reduce log verbosity, see https://github.com/facebook/docusaurus/pull/5420#issuecomment-906613105
65
+ stats: 'summary',
66
+ },
67
+ static: siteConfig.staticDirectories.map((dir) => ({
68
+ publicPath: baseUrl,
69
+ directory: path_1.default.resolve(siteDir, dir),
70
+ watch: {
71
+ // Useful options for our own monorepo using symlinks!
72
+ // See https://github.com/webpack/webpack/issues/11612#issuecomment-879259806
73
+ followSymlinks: true,
74
+ ignored: /node_modules\/(?!@docusaurus)/,
75
+ ...{ pollingOptions },
76
+ },
77
+ })),
78
+ ...(httpsConfig && {
79
+ server: typeof httpsConfig === 'object'
80
+ ? {
81
+ type: 'https',
82
+ options: httpsConfig,
83
+ }
84
+ : 'https',
85
+ }),
86
+ historyApiFallback: {
87
+ rewrites: [{ from: /\/*/, to: baseUrl }],
88
+ },
89
+ allowedHosts: 'all',
90
+ host,
91
+ port,
92
+ setupMiddlewares: (middlewares, devServer) => {
93
+ // This lets us fetch source contents from webpack for the error overlay.
94
+ middlewares.unshift((0, evalSourceMapMiddleware_1.default)(devServer));
95
+ return middlewares;
96
+ },
97
+ };
98
+ }
99
+ async function getStartClientConfig({ props, minify, poll, }) {
100
+ const { plugins, siteConfig } = props;
101
+ let { clientConfig: config } = await (0, client_1.createStartClientConfig)({
102
+ props,
103
+ minify,
104
+ poll,
105
+ });
106
+ config = (0, utils_1.executePluginsConfigurePostCss)({ plugins, config });
107
+ config = (0, utils_1.executePluginsConfigureWebpack)({
108
+ plugins,
109
+ config,
110
+ isServer: false,
111
+ jsLoader: siteConfig.webpack?.jsLoader,
112
+ });
113
+ return config;
114
+ }
115
+ async function createWebpackDevServer({ props, cliOptions, openUrlContext, }) {
116
+ const config = await getStartClientConfig({
117
+ props,
118
+ minify: cliOptions.minify ?? true,
119
+ poll: cliOptions.poll,
120
+ });
121
+ const compiler = (0, webpack_1.default)(config);
122
+ registerWebpackE2ETestHook(compiler);
123
+ const defaultDevServerConfig = await createDevServerConfig({
124
+ cliOptions,
125
+ props,
126
+ host: openUrlContext.host,
127
+ port: openUrlContext.port,
128
+ });
129
+ // Allow plugin authors to customize/override devServer config
130
+ const devServerConfig = (0, webpack_merge_1.default)([defaultDevServerConfig, config.devServer].filter(Boolean));
131
+ return new webpack_dev_server_1.default(devServerConfig, compiler);
132
+ }
133
+ exports.createWebpackDevServer = createWebpackDevServer;
@@ -23,6 +23,7 @@ export type SwizzleContext = {
23
23
  };
24
24
  export type SwizzleCLIOptions = {
25
25
  typescript: boolean;
26
+ javascript: boolean;
26
27
  danger: boolean;
27
28
  list: boolean;
28
29
  wrap: boolean;
@@ -39,6 +39,7 @@ exports.actionStatusSuffix = actionStatusSuffix;
39
39
  function normalizeOptions(options) {
40
40
  return {
41
41
  typescript: options.typescript ?? false,
42
+ javascript: options.javascript ?? false,
42
43
  danger: options.danger ?? false,
43
44
  list: options.list ?? false,
44
45
  wrap: options.wrap ?? false,
@@ -7,11 +7,11 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.initSwizzleContext = void 0;
10
- const server_1 = require("../../server");
10
+ const site_1 = require("../../server/site");
11
11
  const init_1 = require("../../server/plugins/init");
12
12
  const configs_1 = require("../../server/plugins/configs");
13
13
  async function initSwizzleContext(siteDir, options) {
14
- const context = await (0, server_1.loadContext)({ siteDir, config: options.config });
14
+ const context = await (0, site_1.loadContext)({ siteDir, config: options.config });
15
15
  const plugins = await (0, init_1.initPlugins)(context);
16
16
  const pluginConfigs = await (0, configs_1.loadPluginConfigs)(context);
17
17
  return {
@@ -10,6 +10,7 @@ exports.swizzle = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
13
+ const utils_1 = require("@docusaurus/utils");
13
14
  const themes_1 = require("./themes");
14
15
  const components_1 = require("./components");
15
16
  const tables_1 = require("./tables");
@@ -18,6 +19,24 @@ const actions_1 = require("./actions");
18
19
  const config_1 = require("./config");
19
20
  const prompts_1 = require("./prompts");
20
21
  const context_1 = require("./context");
22
+ async function getLanguageForThemeName({ themeName, plugins, options, }) {
23
+ const plugin = (0, themes_1.getPluginByThemeName)(plugins, themeName);
24
+ const supportsTS = !!plugin.instance.getTypeScriptThemePath?.();
25
+ if (options.typescript) {
26
+ if (!supportsTS) {
27
+ throw new Error(logger_1.default.interpolate `Theme name=${plugin.instance.name} does not support the code=${'--typescript'} CLI option.`);
28
+ }
29
+ return 'typescript';
30
+ }
31
+ if (options.javascript) {
32
+ return 'javascript';
33
+ }
34
+ // It's only useful to prompt the user for themes that support both JS/TS
35
+ if (supportsTS) {
36
+ return (0, utils_1.askPreferredLanguage)({ exit: true });
37
+ }
38
+ return 'javascript';
39
+ }
21
40
  async function listAllThemeComponents({ themeNames, plugins, typescript, }) {
22
41
  const themeComponentsTables = (await Promise.all(themeNames.map(async (themeName) => {
23
42
  const themePath = (0, themes_1.getThemePath)({ themeName, plugins, typescript });
@@ -61,14 +80,24 @@ If you want to swizzle it, use the code=${'--danger'} flag, or confirm that you
61
80
  async function swizzle(themeNameParam = undefined, componentNameParam = undefined, siteDirParam = '.', optionsParam = {}) {
62
81
  const siteDir = await fs_extra_1.default.realpath(siteDirParam);
63
82
  const options = (0, common_1.normalizeOptions)(optionsParam);
64
- const { list, danger, typescript } = options;
83
+ const { list, danger } = options;
65
84
  const { plugins } = await (0, context_1.initSwizzleContext)(siteDir, options);
66
85
  const themeNames = (0, themes_1.getThemeNames)(plugins);
67
86
  if (list && !themeNameParam) {
68
- await listAllThemeComponents({ themeNames, plugins, typescript });
87
+ await listAllThemeComponents({
88
+ themeNames,
89
+ plugins,
90
+ typescript: options.typescript,
91
+ });
69
92
  }
70
93
  const themeName = await (0, themes_1.getThemeName)({ themeNameParam, themeNames, list });
71
- const themePath = (0, themes_1.getThemePath)({ themeName, plugins, typescript });
94
+ const language = await getLanguageForThemeName({ themeName, plugins, options });
95
+ const typescript = language === 'typescript';
96
+ const themePath = (0, themes_1.getThemePath)({
97
+ themeName,
98
+ plugins,
99
+ typescript,
100
+ });
72
101
  const swizzleConfig = (0, config_1.getThemeSwizzleConfig)(themeName, plugins);
73
102
  const themeComponents = await (0, components_1.getThemeComponents)({
74
103
  themeName,
@@ -11,7 +11,7 @@ const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
13
13
  const utils_1 = require("@docusaurus/utils");
14
- const server_1 = require("../server");
14
+ const site_1 = require("../server/site");
15
15
  const init_1 = require("../server/plugins/init");
16
16
  const utils_2 = require("../server/utils");
17
17
  async function transformMarkdownFile(filepath, options) {
@@ -30,7 +30,7 @@ async function transformMarkdownFile(filepath, options) {
30
30
  * transformed
31
31
  */
32
32
  async function getPathsToWatch(siteDir) {
33
- const context = await (0, server_1.loadContext)({ siteDir });
33
+ const context = await (0, site_1.loadContext)({ siteDir });
34
34
  const plugins = await (0, init_1.initPlugins)(context);
35
35
  return plugins.flatMap((plugin) => plugin.getPathsToWatch?.() ?? []);
36
36
  }
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import { type LoadContextOptions } from '../server';
7
+ import { type LoadContextParams } from '../server/site';
8
8
  import { type WriteTranslationsOptions } from '../server/translations/translations';
9
- export type WriteTranslationsCLIOptions = Pick<LoadContextOptions, 'config' | 'locale'> & WriteTranslationsOptions;
9
+ export type WriteTranslationsCLIOptions = Pick<LoadContextParams, 'config' | 'locale'> & WriteTranslationsOptions;
10
10
  export declare function writeTranslations(siteDirParam?: string, options?: Partial<WriteTranslationsCLIOptions>): Promise<void>;