@docusaurus/core 2.4.1 → 3.0.0-beta.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 (55) hide show
  1. package/bin/beforeCli.mjs +35 -10
  2. package/bin/docusaurus.mjs +9 -1
  3. package/lib/babel/preset.js +6 -1
  4. package/lib/client/App.js +2 -0
  5. package/lib/client/BaseUrlIssueBanner/index.d.ts +0 -7
  6. package/lib/client/BaseUrlIssueBanner/index.js +7 -19
  7. package/lib/client/ClientLifecyclesDispatcher.js +2 -2
  8. package/lib/client/LinksCollector.d.ts +2 -2
  9. package/lib/client/PendingNavigation.d.ts +2 -2
  10. package/lib/client/clientEntry.js +27 -13
  11. package/lib/client/exports/ErrorBoundary.d.ts +1 -1
  12. package/lib/client/exports/Link.d.ts +1 -1
  13. package/lib/client/exports/Link.js +1 -1
  14. package/lib/client/exports/useIsomorphicLayoutEffect.d.ts +21 -0
  15. package/lib/client/exports/useIsomorphicLayoutEffect.js +24 -0
  16. package/lib/{webpack/plugins/LogPlugin.d.ts → client/hasHydratedDataAttribute.d.ts} +2 -5
  17. package/lib/client/hasHydratedDataAttribute.js +17 -0
  18. package/lib/client/serverEntry.js +26 -18
  19. package/lib/client/serverRenderer.d.ts +8 -0
  20. package/lib/client/serverRenderer.js +61 -0
  21. package/lib/commands/build.d.ts +2 -1
  22. package/lib/commands/build.js +9 -3
  23. package/lib/commands/deploy.d.ts +1 -1
  24. package/lib/commands/deploy.js +8 -0
  25. package/lib/commands/serve.d.ts +1 -1
  26. package/lib/commands/start.d.ts +1 -1
  27. package/lib/commands/start.js +15 -5
  28. package/lib/commands/swizzle/actions.d.ts +2 -2
  29. package/lib/commands/swizzle/common.d.ts +3 -3
  30. package/lib/commands/swizzle/components.d.ts +1 -1
  31. package/lib/commands/writeTranslations.d.ts +1 -1
  32. package/lib/server/configValidation.js +23 -1
  33. package/lib/server/getHostPort.d.ts +1 -1
  34. package/lib/server/index.d.ts +1 -1
  35. package/lib/server/index.js +4 -2
  36. package/lib/server/plugins/configs.d.ts +2 -2
  37. package/lib/server/plugins/routeConfig.js +3 -1
  38. package/lib/server/plugins/synthetic.js +1 -2
  39. package/lib/server/routes.d.ts +1 -1
  40. package/lib/server/routes.js +2 -18
  41. package/lib/server/translations/translations.d.ts +2 -2
  42. package/lib/server/translations/translationsExtractor.d.ts +1 -1
  43. package/lib/webpack/aliases/index.d.ts +1 -1
  44. package/lib/webpack/client.d.ts +1 -1
  45. package/lib/webpack/client.js +10 -4
  46. package/lib/webpack/plugins/CleanWebpackPlugin.d.ts +1 -1
  47. package/lib/webpack/plugins/CleanWebpackPlugin.js +8 -0
  48. package/lib/webpack/plugins/WaitPlugin.d.ts +1 -1
  49. package/lib/webpack/server.js +2 -2
  50. package/lib/webpack/templates/ssr.html.template.d.ts +1 -1
  51. package/lib/webpack/templates/ssr.html.template.js +2 -7
  52. package/lib/webpack/utils.d.ts +3 -1
  53. package/lib/webpack/utils.js +31 -9
  54. package/package.json +57 -57
  55. package/lib/webpack/plugins/LogPlugin.js +0 -33
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { type LoadContextOptions } from '../server';
8
- export declare type DeployCLIOptions = Pick<LoadContextOptions, 'config' | 'locale' | 'outDir'> & {
8
+ export type DeployCLIOptions = Pick<LoadContextOptions, 'config' | 'locale' | 'outDir'> & {
9
9
  skipBuild?: boolean;
10
10
  };
11
11
  export declare function deploy(siteDirParam?: string, cliOptions?: Partial<DeployCLIOptions>): Promise<void>;
@@ -151,6 +151,14 @@ You can also set the deploymentBranch property in docusaurus.config.js .`);
151
151
  throw err;
152
152
  }
153
153
  shellExecLog('git add --all');
154
+ const gitUserName = process.env.GIT_USER_NAME;
155
+ if (gitUserName) {
156
+ shellExecLog(`git config user.name "${gitUserName}"`);
157
+ }
158
+ const gitUserEmail = process.env.GIT_USER_EMAIL;
159
+ if (gitUserEmail) {
160
+ shellExecLog(`git config user.email "${gitUserEmail}"`);
161
+ }
154
162
  const commitMessage = process.env.CUSTOM_COMMIT_MESSAGE ??
155
163
  `Deploy website - based on ${currentCommit}`;
156
164
  const commitResults = shellExecLog(`git commit -m "${commitMessage}"`);
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { type HostPortOptions } from '../server/getHostPort';
8
8
  import type { LoadContextOptions } from '../server';
9
- export declare type ServeCLIOptions = HostPortOptions & Pick<LoadContextOptions, 'config'> & {
9
+ export type ServeCLIOptions = HostPortOptions & Pick<LoadContextOptions, 'config'> & {
10
10
  dir?: string;
11
11
  build?: boolean;
12
12
  open?: boolean;
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { type LoadContextOptions } from '../server';
8
8
  import { type HostPortOptions } from '../server/getHostPort';
9
- export declare type StartCLIOptions = HostPortOptions & Pick<LoadContextOptions, 'locale' | 'config'> & {
9
+ export type StartCLIOptions = HostPortOptions & Pick<LoadContextOptions, 'locale' | 'config'> & {
10
10
  hotOnly?: boolean;
11
11
  open?: boolean;
12
12
  poll?: boolean | number;
@@ -89,7 +89,7 @@ async function start(siteDirParam = '.', cliOptions = {}) {
89
89
  ...{ pollingOptions },
90
90
  });
91
91
  ['add', 'change', 'unlink', 'addDir', 'unlinkDir'].forEach((event) => fsWatcher.on(event, reload));
92
- let config = (0, webpack_merge_1.default)(await (0, client_1.default)(props, cliOptions.minify), {
92
+ let config = (0, webpack_merge_1.default)(await (0, client_1.default)(props, cliOptions.minify, false), {
93
93
  watchOptions: {
94
94
  ignored: /node_modules\/(?!@docusaurus)/,
95
95
  poll: cliOptions.poll,
@@ -124,16 +124,22 @@ async function start(siteDirParam = '.', cliOptions = {}) {
124
124
  }
125
125
  });
126
126
  const compiler = (0, webpack_1.default)(config);
127
- if (process.env.E2E_TEST) {
128
- compiler.hooks.done.tap('done', (stats) => {
127
+ compiler.hooks.done.tap('done', (stats) => {
128
+ const errorsWarnings = stats.toJson('errors-warnings');
129
+ const statsErrorMessage = (0, utils_2.formatStatsErrorMessage)(errorsWarnings);
130
+ if (statsErrorMessage) {
131
+ console.error(statsErrorMessage);
132
+ }
133
+ (0, utils_2.printStatsWarnings)(errorsWarnings);
134
+ if (process.env.E2E_TEST) {
129
135
  if (stats.hasErrors()) {
130
136
  logger_1.default.error('E2E_TEST: Project has compiler errors.');
131
137
  process.exit(1);
132
138
  }
133
139
  logger_1.default.success('E2E_TEST: Project can compile.');
134
140
  process.exit(0);
135
- });
136
- }
141
+ }
142
+ });
137
143
  // https://webpack.js.org/configuration/dev-server
138
144
  const defaultDevServerConfig = {
139
145
  hot: cliOptions.hotOnly ? 'only' : true,
@@ -144,6 +150,10 @@ async function start(siteDirParam = '.', cliOptions = {}) {
144
150
  warnings: false,
145
151
  errors: true,
146
152
  },
153
+ webSocketURL: {
154
+ hostname: '0.0.0.0',
155
+ port: 0,
156
+ },
147
157
  },
148
158
  headers: {
149
159
  'access-control-allow-origin': '*',
@@ -8,13 +8,13 @@ import type { SwizzleAction, SwizzleComponentConfig } from '@docusaurus/types';
8
8
  import type { SwizzleCLIOptions } from './common';
9
9
  export declare const SwizzleActions: SwizzleAction[];
10
10
  export declare function getAction(componentConfig: SwizzleComponentConfig, options: Pick<SwizzleCLIOptions, 'wrap' | 'eject'>): Promise<SwizzleAction>;
11
- export declare type ActionParams = {
11
+ export type ActionParams = {
12
12
  siteDir: string;
13
13
  themePath: string;
14
14
  componentName: string;
15
15
  typescript: boolean;
16
16
  };
17
- export declare type ActionResult = {
17
+ export type ActionResult = {
18
18
  createdFiles: string[];
19
19
  };
20
20
  export declare function eject({ siteDir, themePath, componentName, typescript, }: ActionParams): Promise<ActionResult>;
@@ -14,14 +14,14 @@ export declare function actionStatusColor(status: SwizzleActionStatus, str: stri
14
14
  export declare function actionStatusSuffix(status: SwizzleActionStatus, options?: {
15
15
  partiallySafe?: boolean;
16
16
  }): string;
17
- export declare type SwizzlePlugin = {
17
+ export type SwizzlePlugin = {
18
18
  instance: InitializedPlugin;
19
19
  plugin: NormalizedPluginConfig;
20
20
  };
21
- export declare type SwizzleContext = {
21
+ export type SwizzleContext = {
22
22
  plugins: SwizzlePlugin[];
23
23
  };
24
- export declare type SwizzleCLIOptions = {
24
+ export type SwizzleCLIOptions = {
25
25
  typescript: boolean;
26
26
  danger: boolean;
27
27
  list: boolean;
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { SwizzleAction, SwizzleActionStatus, SwizzleComponentConfig, SwizzleConfig } from '@docusaurus/types';
8
- export declare type ThemeComponents = {
8
+ export type ThemeComponents = {
9
9
  themeName: string;
10
10
  all: string[];
11
11
  getConfig: (component: string) => SwizzleComponentConfig;
@@ -6,5 +6,5 @@
6
6
  */
7
7
  import { type LoadContextOptions } from '../server';
8
8
  import { type WriteTranslationsOptions } from '../server/translations/translations';
9
- export declare type WriteTranslationsCLIOptions = Pick<LoadContextOptions, 'config' | 'locale'> & WriteTranslationsOptions;
9
+ export type WriteTranslationsCLIOptions = Pick<LoadContextOptions, 'config' | 'locale'> & WriteTranslationsOptions;
10
10
  export declare function writeTranslations(siteDirParam?: string, options?: Partial<WriteTranslationsCLIOptions>): Promise<void>;
@@ -36,7 +36,14 @@ exports.DEFAULT_CONFIG = {
36
36
  baseUrlIssueBanner: true,
37
37
  staticDirectories: [utils_1.DEFAULT_STATIC_DIR_NAME],
38
38
  markdown: {
39
+ format: 'mdx',
39
40
  mermaid: false,
41
+ preprocessor: undefined,
42
+ mdx1Compat: {
43
+ comments: true,
44
+ admonitions: true,
45
+ headingIds: true,
46
+ },
40
47
  },
41
48
  };
42
49
  function createPluginSchema(theme) {
@@ -125,7 +132,10 @@ const SiteUrlSchema = utils_validation_1.Joi.string()
125
132
  });
126
133
  // TODO move to @docusaurus/utils-validation
127
134
  exports.ConfigSchema = utils_validation_1.Joi.object({
128
- baseUrl: utils_validation_1.Joi.string()
135
+ baseUrl: utils_validation_1.Joi
136
+ // Weird Joi trick needed, otherwise value '' is not normalized...
137
+ .alternatives()
138
+ .try(utils_validation_1.Joi.string().required().allow(''))
129
139
  .required()
130
140
  .custom((value) => (0, utils_1.addLeadingSlash)((0, utils_1.addTrailingSlash)(value))),
131
141
  baseUrlIssueBanner: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.baseUrlIssueBanner),
@@ -201,7 +211,19 @@ exports.ConfigSchema = utils_validation_1.Joi.object({
201
211
  .optional(),
202
212
  }).optional(),
203
213
  markdown: utils_validation_1.Joi.object({
214
+ format: utils_validation_1.Joi.string()
215
+ .equal('mdx', 'md', 'detect')
216
+ .default(exports.DEFAULT_CONFIG.markdown.format),
204
217
  mermaid: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.markdown.mermaid),
218
+ preprocessor: utils_validation_1.Joi.function()
219
+ .arity(1)
220
+ .optional()
221
+ .default(() => exports.DEFAULT_CONFIG.markdown.preprocessor),
222
+ mdx1Compat: utils_validation_1.Joi.object({
223
+ comments: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.markdown.mdx1Compat.comments),
224
+ admonitions: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.markdown.mdx1Compat.admonitions),
225
+ headingIds: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.markdown.mdx1Compat.headingIds),
226
+ }).default(exports.DEFAULT_CONFIG.markdown.mdx1Compat),
205
227
  }).default(exports.DEFAULT_CONFIG.markdown),
206
228
  }).messages({
207
229
  'docusaurus.configValidationWarning': 'Docusaurus config validation warning. Field {#label}: {#warningMessage}',
@@ -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
- export declare type HostPortOptions = {
7
+ export type HostPortOptions = {
8
8
  host?: string;
9
9
  port?: string;
10
10
  };
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { LoadContext, Props } from '@docusaurus/types';
8
- export declare type LoadContextOptions = {
8
+ export type LoadContextOptions = {
9
9
  /** Usually the CWD; can be overridden with command argument. */
10
10
  siteDir: string;
11
11
  /** Custom output directory. Can be customized with `--out-dir` option */
@@ -102,14 +102,16 @@ export default ${JSON.stringify(siteConfig, null, 2)};
102
102
  ${clientModules
103
103
  // Use `require()` because `import()` is async but client modules can have CSS
104
104
  // and the order matters for loading CSS.
105
- .map((clientModule) => ` require('${(0, utils_1.escapePath)(clientModule)}'),`)
105
+ .map((clientModule) => ` require("${(0, utils_1.escapePath)(clientModule)}"),`)
106
106
  .join('\n')}
107
107
  ];
108
108
  `);
109
109
  const genRegistry = (0, utils_1.generate)(generatedFilesDir, 'registry.js', `export default {
110
110
  ${Object.entries(registry)
111
111
  .sort((a, b) => a[0].localeCompare(b[0]))
112
- .map(([chunkName, modulePath]) => ` '${chunkName}': [() => import(/* webpackChunkName: '${chunkName}' */ '${modulePath}'), '${modulePath}', require.resolveWeak('${modulePath}')],`)
112
+ .map(([chunkName, modulePath]) =>
113
+ // modulePath is already escaped by escapePath
114
+ ` "${chunkName}": [() => import(/* webpackChunkName: "${chunkName}" */ "${modulePath}"), "${modulePath}", require.resolveWeak("${modulePath}")],`)
113
115
  .join('\n')}};
114
116
  `);
115
117
  const genRoutesChunkNames = (0, utils_1.generate)(generatedFilesDir, 'routesChunkNames.json', JSON.stringify(routesChunkNames, null, 2));
@@ -5,10 +5,10 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { LoadContext, PluginModule, PluginOptions } from '@docusaurus/types';
8
- declare type ImportedPluginModule = PluginModule & {
8
+ type ImportedPluginModule = PluginModule & {
9
9
  default?: PluginModule;
10
10
  };
11
- export declare type NormalizedPluginConfig = {
11
+ export type NormalizedPluginConfig = {
12
12
  /**
13
13
  * The default export of the plugin module, or alternatively, what's provided
14
14
  * in the config file as inline plugins. Note that if a file is like:
@@ -48,7 +48,9 @@ function sortConfig(routeConfigs, baseUrl = '/') {
48
48
  return a.path.localeCompare(b.path);
49
49
  });
50
50
  routeConfigs.forEach((routeConfig) => {
51
- routeConfig.routes?.sort((a, b) => a.path.localeCompare(b.path));
51
+ if (routeConfig.routes) {
52
+ sortConfig(routeConfig.routes, baseUrl);
53
+ }
52
54
  });
53
55
  }
54
56
  exports.sortConfig = sortConfig;
@@ -68,7 +68,7 @@ function createMDXFallbackPlugin({ siteDir, siteConfig, }) {
68
68
  version: { type: 'synthetic' },
69
69
  // Synthetic, the path doesn't matter much
70
70
  path: '.',
71
- configureWebpack(config, isServer, { getJSLoader }) {
71
+ configureWebpack(config) {
72
72
  // We need the mdx fallback loader to exclude files that were already
73
73
  // processed by content plugins mdx loaders. This works, but a bit
74
74
  // hacky... Not sure there's a way to handle that differently in webpack
@@ -96,7 +96,6 @@ function createMDXFallbackPlugin({ siteDir, siteConfig, }) {
96
96
  test: /\.mdx?$/i,
97
97
  exclude: getMDXFallbackExcludedPaths(),
98
98
  use: [
99
- getJSLoader({ isServer }),
100
99
  {
101
100
  loader: require.resolve('@docusaurus/mdx-loader'),
102
101
  options: mdxLoaderOptions,
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { RouteConfig, RouteChunkNames, ReportingSeverity } from '@docusaurus/types';
8
- declare type LoadedRoutes = {
8
+ type LoadedRoutes = {
9
9
  /** Serialized routes config that can be directly emitted into temp file. */
10
10
  routesConfig: string;
11
11
  /** @see {ChunkNames} */
@@ -74,24 +74,8 @@ ${indent(subroutesCodeStrings.join(',\n'))}
74
74
  ]`);
75
75
  }
76
76
  Object.entries(props).forEach(([propName, propValue]) => {
77
- // Inspired by https://github.com/armanozak/should-quote/blob/main/packages/should-quote/src/lib/should-quote.ts
78
- const shouldQuote = ((key) => {
79
- // Pre-sanitation to prevent injection
80
- if (/[.,;:}/\s]/.test(key)) {
81
- return true;
82
- }
83
- try {
84
- // If this key can be used in an expression like ({a:0}).a
85
- // eslint-disable-next-line no-eval
86
- eval(`({${key}:0}).${key}`);
87
- return false;
88
- }
89
- catch {
90
- return true;
91
- }
92
- })(propName);
93
- // Escape quotes as well
94
- const key = shouldQuote ? JSON.stringify(propName) : propName;
77
+ const isIdentifier = /^[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*$/u.test(propName);
78
+ const key = isIdentifier ? propName : JSON.stringify(propName);
95
79
  parts.push(`${key}: ${JSON.stringify(propValue)}`);
96
80
  });
97
81
  return `{
@@ -5,11 +5,11 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { TranslationFileContent, TranslationFile, CodeTranslations, InitializedPlugin } from '@docusaurus/types';
8
- export declare type WriteTranslationsOptions = {
8
+ export type WriteTranslationsOptions = {
9
9
  override?: boolean;
10
10
  messagePrefix?: string;
11
11
  };
12
- declare type TranslationContext = {
12
+ type TranslationContext = {
13
13
  localizationDir: string;
14
14
  };
15
15
  export declare function readCodeTranslationFileContent(context: TranslationContext): Promise<TranslationFileContent | undefined>;
@@ -8,7 +8,7 @@ import { type TransformOptions } from '@babel/core';
8
8
  import type { InitializedPlugin, TranslationFileContent } from '@docusaurus/types';
9
9
  export declare function globSourceCodeFilePaths(dirPaths: string[]): Promise<string[]>;
10
10
  export declare function extractSiteSourceCodeTranslations(siteDir: string, plugins: InitializedPlugin[], babelOptions: TransformOptions, extraSourceCodeFilePaths?: string[]): Promise<TranslationFileContent>;
11
- declare type SourceCodeFileTranslations = {
11
+ type SourceCodeFileTranslations = {
12
12
  sourceCodeFilePath: string;
13
13
  translations: TranslationFileContent;
14
14
  warnings: string[];
@@ -8,7 +8,7 @@ import type { LoadedPlugin } from '@docusaurus/types';
8
8
  /**
9
9
  * Aliases used for Webpack resolution (useful for implementing swizzling)
10
10
  */
11
- declare type ThemeAliases = {
11
+ type ThemeAliases = {
12
12
  [alias: string]: string;
13
13
  };
14
14
  /**
@@ -6,4 +6,4 @@
6
6
  */
7
7
  import type { Props } from '@docusaurus/types';
8
8
  import type { Configuration } from 'webpack';
9
- export default function createClientConfig(props: Props, minify?: boolean): Promise<Configuration>;
9
+ export default function createClientConfig(props: Props, minify?: boolean, hydrate?: boolean): Promise<Configuration>;
@@ -10,10 +10,12 @@ const tslib_1 = require("tslib");
10
10
  const path_1 = tslib_1.__importDefault(require("path"));
11
11
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
12
12
  const webpack_merge_1 = tslib_1.__importDefault(require("webpack-merge"));
13
+ const webpackbar_1 = tslib_1.__importDefault(require("webpackbar"));
14
+ const webpack_1 = require("webpack");
13
15
  const base_1 = require("./base");
14
16
  const ChunkAssetPlugin_1 = tslib_1.__importDefault(require("./plugins/ChunkAssetPlugin"));
15
- const LogPlugin_1 = tslib_1.__importDefault(require("./plugins/LogPlugin"));
16
- async function createClientConfig(props, minify = true) {
17
+ const utils_1 = require("./utils");
18
+ async function createClientConfig(props, minify = true, hydrate = true) {
17
19
  const isBuilding = process.argv[2] === 'build';
18
20
  const config = await (0, base_1.createBaseConfig)(props, false, minify);
19
21
  const clientConfig = (0, webpack_merge_1.default)(config, {
@@ -27,9 +29,12 @@ async function createClientConfig(props, minify = true) {
27
29
  runtimeChunk: true,
28
30
  },
29
31
  plugins: [
32
+ new webpack_1.DefinePlugin({
33
+ 'process.env.HYDRATE_CLIENT_ENTRY': JSON.stringify(hydrate),
34
+ }),
30
35
  new ChunkAssetPlugin_1.default(),
31
36
  // Show compilation progress bar and build time.
32
- new LogPlugin_1.default({
37
+ new webpackbar_1.default({
33
38
  name: 'Client',
34
39
  }),
35
40
  ],
@@ -41,7 +46,8 @@ async function createClientConfig(props, minify = true) {
41
46
  apply: (compiler) => {
42
47
  compiler.hooks.done.tap('client:done', (stats) => {
43
48
  if (stats.hasErrors()) {
44
- logger_1.default.error('Client bundle compiled with errors therefore further build is impossible.');
49
+ const errorsWarnings = stats.toJson('errors-warnings');
50
+ logger_1.default.error(`Client bundle compiled with errors therefore further build is impossible.\n${(0, utils_1.formatStatsErrorMessage)(errorsWarnings)}`);
45
51
  process.exit(1);
46
52
  }
47
53
  });
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { Compiler, Stats } from 'webpack';
8
- export declare type Options = {
8
+ export type Options = {
9
9
  /**
10
10
  * Write Logs to Console
11
11
  * (Always enabled when dry is true)
@@ -30,6 +30,7 @@ const tslib_1 = require("tslib");
30
30
  // Modified to optimize performance for Docusaurus specific use case
31
31
  // More context: https://github.com/facebook/docusaurus/pull/1839
32
32
  const path_1 = tslib_1.__importDefault(require("path"));
33
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
33
34
  const del_1 = require("del");
34
35
  class CleanWebpackPlugin {
35
36
  constructor(options = {}) {
@@ -89,6 +90,13 @@ class CleanWebpackPlugin {
89
90
  if (this.initialClean) {
90
91
  return;
91
92
  }
93
+ if (
94
+ // eslint-disable-next-line no-restricted-properties
95
+ fs_extra_1.default.pathExistsSync(this.outputPath) &&
96
+ // eslint-disable-next-line no-restricted-properties
97
+ fs_extra_1.default.statSync(this.outputPath).isFile()) {
98
+ throw new Error(`A file '${this.outputPath}' already exists. Docusaurus needs this directory to save the build output. Either remove/change the file or choose a different build directory via '--out-dir'.`);
99
+ }
92
100
  this.initialClean = true;
93
101
  this.removeFiles(this.cleanOnceBeforeBuildPatterns);
94
102
  }
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { Compiler } from 'webpack';
8
- declare type WaitPluginOptions = {
8
+ type WaitPluginOptions = {
9
9
  filepath: string;
10
10
  };
11
11
  export default class WaitPlugin {
@@ -12,9 +12,9 @@ const webpack_merge_1 = tslib_1.__importDefault(require("webpack-merge"));
12
12
  const utils_1 = require("@docusaurus/utils");
13
13
  // Forked for Docusaurus: https://github.com/slorber/static-site-generator-webpack-plugin
14
14
  const static_site_generator_webpack_plugin_1 = tslib_1.__importDefault(require("@slorber/static-site-generator-webpack-plugin"));
15
+ const webpackbar_1 = tslib_1.__importDefault(require("webpackbar"));
15
16
  const base_1 = require("./base");
16
17
  const WaitPlugin_1 = tslib_1.__importDefault(require("./plugins/WaitPlugin"));
17
- const LogPlugin_1 = tslib_1.__importDefault(require("./plugins/LogPlugin"));
18
18
  const ssr_html_template_1 = tslib_1.__importDefault(require("./templates/ssr.html.template"));
19
19
  async function createServerConfig({ props, onLinksCollected, onHeadTagsCollected, }) {
20
20
  const { baseUrl, routesPaths, generatedFilesDir, headTags, preBodyTags, postBodyTags, siteConfig: { noIndex, trailingSlash, ssrTemplate }, } = props;
@@ -72,7 +72,7 @@ async function createServerConfig({ props, onLinksCollected, onHeadTagsCollected
72
72
  : undefined,
73
73
  }),
74
74
  // Show compilation progress bar.
75
- new LogPlugin_1.default({
75
+ new webpackbar_1.default({
76
76
  name: 'Server',
77
77
  color: 'yellow',
78
78
  }),
@@ -4,5 +4,5 @@
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
- declare const _default: "\n<!DOCTYPE html>\n<html <%~ it.htmlAttributes %>>\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"generator\" content=\"Docusaurus v<%= it.version %>\">\n <% it.metaAttributes.forEach((metaAttribute) => { %>\n <%~ metaAttribute %>\n <% }); %>\n <%~ it.headTags %>\n <% it.stylesheets.forEach((stylesheet) => { %>\n <link rel=\"stylesheet\" href=\"<%= it.baseUrl %><%= stylesheet %>\" />\n <% }); %>\n <% it.scripts.forEach((script) => { %>\n <link rel=\"preload\" href=\"<%= it.baseUrl %><%= script %>\" as=\"script\">\n <% }); %>\n </head>\n <body <%~ it.bodyAttributes %>>\n <%~ it.preBodyTags %>\n <div id=\"__docusaurus\">\n <%~ it.appHtml %>\n </div>\n <% it.scripts.forEach((script) => { %>\n <script src=\"<%= it.baseUrl %><%= script %>\"></script>\n <% }); %>\n <%~ it.postBodyTags %>\n </body>\n</html>\n";
7
+ declare const _default: "\n<!DOCTYPE html>\n<html <%~ it.htmlAttributes %>>\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"generator\" content=\"Docusaurus v<%= it.version %>\">\n <% it.metaAttributes.forEach((metaAttribute) => { %>\n <%~ metaAttribute %>\n <% }); %>\n <%~ it.headTags %>\n <% it.stylesheets.forEach((stylesheet) => { %>\n <link rel=\"stylesheet\" href=\"<%= it.baseUrl %><%= stylesheet %>\" />\n <% }); %>\n <% it.scripts.forEach((script) => { %>\n <script src=\"<%= it.baseUrl %><%= script %>\" defer></script>\n <% }); %>\n </head>\n <body <%~ it.bodyAttributes %>>\n <%~ it.preBodyTags %>\n <div id=\"__docusaurus\"><%~ it.appHtml %></div>\n <%~ it.postBodyTags %>\n </body>\n</html>\n";
8
8
  export default _default;
@@ -20,17 +20,12 @@ exports.default = `
20
20
  <link rel="stylesheet" href="<%= it.baseUrl %><%= stylesheet %>" />
21
21
  <% }); %>
22
22
  <% it.scripts.forEach((script) => { %>
23
- <link rel="preload" href="<%= it.baseUrl %><%= script %>" as="script">
23
+ <script src="<%= it.baseUrl %><%= script %>" defer></script>
24
24
  <% }); %>
25
25
  </head>
26
26
  <body <%~ it.bodyAttributes %>>
27
27
  <%~ it.preBodyTags %>
28
- <div id="__docusaurus">
29
- <%~ it.appHtml %>
30
- </div>
31
- <% it.scripts.forEach((script) => { %>
32
- <script src="<%= it.baseUrl %><%= script %>"></script>
33
- <% }); %>
28
+ <div id="__docusaurus"><%~ it.appHtml %></div>
34
29
  <%~ it.postBodyTags %>
35
30
  </body>
36
31
  </html>
@@ -5,9 +5,11 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  /// <reference types="node" />
8
- import { type Configuration, type RuleSetRule, type WebpackPluginInstance } from 'webpack';
8
+ import webpack, { type Configuration, type RuleSetRule, type WebpackPluginInstance } from 'webpack';
9
9
  import type { TransformOptions } from '@babel/core';
10
10
  import type { Plugin } from '@docusaurus/types';
11
+ export declare function formatStatsErrorMessage(statsJson: ReturnType<webpack.Stats['toJson']> | undefined): string | undefined;
12
+ export declare function printStatsWarnings(statsJson: ReturnType<webpack.Stats['toJson']> | undefined): void;
11
13
  export declare function getStyleLoaders(isServer: boolean, cssOptionsArg?: {
12
14
  [key: string]: unknown;
13
15
  }): RuleSetRule[];
@@ -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.getMinimizer = exports.getHttpsConfig = exports.compile = exports.applyConfigurePostCss = exports.applyConfigureWebpack = exports.getCustomizableJSLoader = exports.getBabelOptions = exports.getCustomBabelConfigFilePath = exports.getStyleLoaders = void 0;
9
+ exports.getMinimizer = exports.getHttpsConfig = exports.compile = exports.applyConfigurePostCss = exports.applyConfigureWebpack = exports.getCustomizableJSLoader = exports.getBabelOptions = exports.getCustomBabelConfigFilePath = exports.getStyleLoaders = exports.printStatsWarnings = exports.formatStatsErrorMessage = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const path_1 = tslib_1.__importDefault(require("path"));
@@ -18,6 +18,28 @@ const webpack_merge_1 = require("webpack-merge");
18
18
  const webpack_1 = tslib_1.__importDefault(require("webpack"));
19
19
  const terser_webpack_plugin_1 = tslib_1.__importDefault(require("terser-webpack-plugin"));
20
20
  const css_minimizer_webpack_plugin_1 = tslib_1.__importDefault(require("css-minimizer-webpack-plugin"));
21
+ const formatWebpackMessages_1 = tslib_1.__importDefault(require("react-dev-utils/formatWebpackMessages"));
22
+ function formatStatsErrorMessage(statsJson) {
23
+ if (statsJson?.errors?.length) {
24
+ // TODO formatWebpackMessages does not print stack-traces
25
+ // Also the error causal chain is lost here
26
+ // We log the stacktrace inside serverEntry.tsx for now (not ideal)
27
+ const { errors } = (0, formatWebpackMessages_1.default)(statsJson);
28
+ return errors
29
+ .map((str) => logger_1.default.red(str))
30
+ .join(`\n\n${logger_1.default.yellow('--------------------------')}\n\n`);
31
+ }
32
+ return undefined;
33
+ }
34
+ exports.formatStatsErrorMessage = formatStatsErrorMessage;
35
+ function printStatsWarnings(statsJson) {
36
+ if (statsJson?.warnings?.length) {
37
+ statsJson.warnings?.forEach((warning) => {
38
+ logger_1.default.warn(warning);
39
+ });
40
+ }
41
+ }
42
+ exports.printStatsWarnings = printStatsWarnings;
21
43
  // Utility method to get style loaders
22
44
  function getStyleLoaders(isServer, cssOptionsArg = {}) {
23
45
  const cssOptions = {
@@ -151,7 +173,11 @@ function applyConfigurePostCss(configurePostCss, config) {
151
173
  entry.options.postcssOptions = configurePostCss(entry.options.postcssOptions);
152
174
  }
153
175
  else if (Array.isArray(entry.oneOf)) {
154
- entry.oneOf.forEach(overridePostCssOptions);
176
+ entry.oneOf.forEach((r) => {
177
+ if (r) {
178
+ overridePostCssOptions(r);
179
+ }
180
+ });
155
181
  }
156
182
  else if (Array.isArray(entry.use)) {
157
183
  entry.use
@@ -177,13 +203,10 @@ function compile(config) {
177
203
  // Let plugins consume all the stats
178
204
  const errorsWarnings = stats?.toJson('errors-warnings');
179
205
  if (stats?.hasErrors()) {
180
- reject(new Error('Failed to compile with errors.'));
181
- }
182
- if (errorsWarnings && stats?.hasWarnings()) {
183
- errorsWarnings.warnings?.forEach((warning) => {
184
- logger_1.default.warn(warning);
185
- });
206
+ const statsErrorMessage = formatStatsErrorMessage(errorsWarnings);
207
+ reject(new Error(`Failed to compile due to Webpack errors.\n${statsErrorMessage}`));
186
208
  }
209
+ printStatsWarnings(errorsWarnings);
187
210
  // Webpack 5 requires calling close() so that persistent caching works
188
211
  // See https://github.com/webpack/webpack.js.org/pull/4775
189
212
  compiler.close((errClose) => {
@@ -273,7 +296,6 @@ function getMinimizer(useSimpleCssMinifier = false) {
273
296
  },
274
297
  compress: {
275
298
  ecma: 5,
276
- warnings: false,
277
299
  },
278
300
  mangle: {
279
301
  safari10: true,