@docusaurus/core 3.5.2 → 3.6.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 (71) hide show
  1. package/bin/beforeCli.mjs +1 -1
  2. package/bin/docusaurus.mjs +15 -4
  3. package/lib/babel/preset.d.ts +2 -2
  4. package/lib/babel/preset.js +10 -71
  5. package/lib/client/renderToHtml.js +15 -51
  6. package/lib/client/serverEntry.d.ts +1 -1
  7. package/lib/client/serverEntry.js +2 -0
  8. package/lib/commands/{build.d.ts → build/build.d.ts} +4 -3
  9. package/lib/commands/build/build.js +94 -0
  10. package/lib/commands/build/buildLocale.d.ts +13 -0
  11. package/lib/commands/build/buildLocale.js +143 -0
  12. package/lib/commands/deploy.d.ts +2 -1
  13. package/lib/commands/deploy.js +2 -2
  14. package/lib/commands/serve.js +2 -2
  15. package/lib/commands/start/utils.js +5 -6
  16. package/lib/commands/start/webpack.js +15 -9
  17. package/lib/commands/writeHeadingIds.js +1 -2
  18. package/lib/commands/writeTranslations.js +6 -6
  19. package/lib/index.d.ts +1 -1
  20. package/lib/index.js +1 -1
  21. package/lib/server/configValidation.d.ts +3 -1
  22. package/lib/server/configValidation.js +35 -4
  23. package/lib/server/i18n.d.ts +1 -1
  24. package/lib/server/i18n.js +1 -1
  25. package/lib/server/plugins/plugins.js +13 -13
  26. package/lib/server/plugins/synthetic.d.ts +1 -1
  27. package/lib/server/plugins/synthetic.js +14 -17
  28. package/lib/server/site.js +10 -4
  29. package/lib/server/translations/translationsExtractor.d.ts +5 -11
  30. package/lib/server/translations/translationsExtractor.js +8 -196
  31. package/lib/ssg/ssg.d.ts +21 -0
  32. package/lib/{ssg.js → ssg/ssg.js} +91 -82
  33. package/lib/ssg/ssgExecutor.d.ts +16 -0
  34. package/lib/ssg/ssgExecutor.js +34 -0
  35. package/lib/{server/utils.d.ts → ssg/ssgNodeRequire.d.ts} +5 -2
  36. package/lib/ssg/ssgNodeRequire.js +40 -0
  37. package/lib/ssg/ssgParams.d.ts +28 -0
  38. package/lib/ssg/ssgParams.js +36 -0
  39. package/lib/{templates/templates.d.ts → ssg/ssgTemplate.d.ts} +7 -6
  40. package/lib/{templates/templates.js → ssg/ssgTemplate.js} +11 -9
  41. package/lib/ssg/ssgUtils.d.ts +17 -0
  42. package/lib/ssg/ssgUtils.js +58 -0
  43. package/lib/webpack/base.d.ts +4 -2
  44. package/lib/webpack/base.js +33 -20
  45. package/lib/webpack/client.d.ts +7 -3
  46. package/lib/webpack/client.js +32 -14
  47. package/lib/webpack/configure.d.ts +20 -6
  48. package/lib/webpack/configure.js +31 -16
  49. package/lib/webpack/plugins/ChunkAssetPlugin.d.ts +0 -11
  50. package/lib/webpack/plugins/ChunkAssetPlugin.js +48 -33
  51. package/lib/webpack/plugins/ForceTerminatePlugin.js +2 -2
  52. package/lib/webpack/plugins/StaticDirectoriesCopyPlugin.d.ts +2 -2
  53. package/lib/webpack/plugins/StaticDirectoriesCopyPlugin.js +5 -2
  54. package/lib/webpack/server.d.ts +3 -2
  55. package/lib/webpack/server.js +12 -10
  56. package/lib/webpack/{minification.d.ts → utils/getHttpsConfig.d.ts} +4 -2
  57. package/lib/webpack/utils/getHttpsConfig.js +60 -0
  58. package/package.json +19 -44
  59. package/lib/commands/build.js +0 -240
  60. package/lib/server/utils.js +0 -20
  61. package/lib/ssg.d.ts +0 -35
  62. package/lib/utils.d.ts +0 -9
  63. package/lib/utils.js +0 -78
  64. package/lib/webpack/minification.js +0 -96
  65. package/lib/webpack/plugins/WaitPlugin.d.ts +0 -16
  66. package/lib/webpack/plugins/WaitPlugin.js +0 -47
  67. package/lib/webpack/utils.d.ts +0 -33
  68. package/lib/webpack/utils.js +0 -215
  69. /package/lib/{templates/ssr.html.template.d.ts → ssg/ssgTemplate.html.d.ts} +0 -0
  70. /package/lib/{templates/ssr.html.template.js → ssg/ssgTemplate.html.js} +0 -0
  71. /package/lib/{templates → webpack/templates}/dev.html.template.ejs +0 -0
@@ -4,9 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import type { SSGParams } from '../ssg';
7
+ import type { SSGParams } from './ssgParams';
8
8
  import type { AppRenderResult } from '../common';
9
- export type SSRTemplateData = {
9
+ export type SSGTemplateData = {
10
10
  appHtml: string;
11
11
  baseUrl: string;
12
12
  htmlAttributes: string;
@@ -20,12 +20,13 @@ export type SSRTemplateData = {
20
20
  noIndex: boolean;
21
21
  version: string;
22
22
  };
23
- export type SSRTemplateCompiled = (data: SSRTemplateData) => string;
24
- export declare function compileSSRTemplate(template: string): Promise<SSRTemplateCompiled>;
25
- export declare function renderSSRTemplate({ params, result, }: {
23
+ export type SSGTemplateCompiled = (data: SSGTemplateData) => string;
24
+ export declare function compileSSGTemplate(template: string): Promise<SSGTemplateCompiled>;
25
+ export declare function renderSSGTemplate({ params, result, ssgTemplate, }: {
26
26
  params: SSGParams;
27
27
  result: AppRenderResult;
28
+ ssgTemplate: SSGTemplateCompiled;
28
29
  }): string;
29
30
  export declare function renderHashRouterTemplate({ params, }: {
30
31
  params: SSGParams;
31
- }): string;
32
+ }): Promise<string>;
@@ -6,13 +6,14 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.compileSSRTemplate = compileSSRTemplate;
10
- exports.renderSSRTemplate = renderSSRTemplate;
9
+ exports.compileSSGTemplate = compileSSGTemplate;
10
+ exports.renderSSGTemplate = renderSSGTemplate;
11
11
  exports.renderHashRouterTemplate = renderHashRouterTemplate;
12
12
  const tslib_1 = require("tslib");
13
13
  const eta = tslib_1.__importStar(require("eta"));
14
14
  const react_loadable_ssr_addon_v5_slorber_1 = require("react-loadable-ssr-addon-v5-slorber");
15
- async function compileSSRTemplate(template) {
15
+ const logger_1 = require("@docusaurus/logger");
16
+ async function compileSSGTemplate(template) {
16
17
  const compiledTemplate = eta.compile(template.trim(), {
17
18
  rmWhitespace: true,
18
19
  });
@@ -32,8 +33,8 @@ function getScriptsAndStylesheets({ modules, manifest, }) {
32
33
  const scripts = (bundles.js ?? []).map((b) => b.file);
33
34
  return { scripts, stylesheets };
34
35
  }
35
- function renderSSRTemplate({ params, result, }) {
36
- const { baseUrl, headTags, preBodyTags, postBodyTags, manifest, noIndex, DOCUSAURUS_VERSION, ssrTemplate, } = params;
36
+ function renderSSGTemplate({ params, result, ssgTemplate, }) {
37
+ const { baseUrl, headTags, preBodyTags, postBodyTags, manifest, noIndex, DOCUSAURUS_VERSION, } = params;
37
38
  const { html: appHtml, collectedData: { modules, helmet }, } = result;
38
39
  const { scripts, stylesheets } = getScriptsAndStylesheets({ manifest, modules });
39
40
  const htmlAttributes = helmet.htmlAttributes.toString();
@@ -59,12 +60,13 @@ function renderSSRTemplate({ params, result, }) {
59
60
  noIndex,
60
61
  version: DOCUSAURUS_VERSION,
61
62
  };
62
- return ssrTemplate(data);
63
+ return ssgTemplate(data);
63
64
  }
64
- function renderHashRouterTemplate({ params, }) {
65
+ async function renderHashRouterTemplate({ params, }) {
65
66
  const {
66
67
  // baseUrl,
67
- headTags, preBodyTags, postBodyTags, manifest, DOCUSAURUS_VERSION, ssrTemplate, } = params;
68
+ headTags, preBodyTags, postBodyTags, manifest, DOCUSAURUS_VERSION, ssgTemplateContent, } = params;
69
+ const ssgTemplate = await logger_1.PerfLogger.async('Compile SSG template', () => compileSSGTemplate(ssgTemplateContent));
68
70
  const { scripts, stylesheets } = getScriptsAndStylesheets({
69
71
  manifest,
70
72
  modules: [],
@@ -83,5 +85,5 @@ function renderHashRouterTemplate({ params, }) {
83
85
  noIndex: false,
84
86
  version: DOCUSAURUS_VERSION,
85
87
  };
86
- return ssrTemplate(data);
88
+ return ssgTemplate(data);
87
89
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import type { SSGParams } from './ssgParams';
8
+ export declare const SSGConcurrency: number;
9
+ export declare function generateHashRouterEntrypoint({ content, params, }: {
10
+ content: string;
11
+ params: SSGParams;
12
+ }): Promise<void>;
13
+ export declare function writeStaticFile({ content, pathname, params, }: {
14
+ content: string;
15
+ pathname: string;
16
+ params: SSGParams;
17
+ }): Promise<void>;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Facebook, Inc. and its affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.SSGConcurrency = void 0;
10
+ exports.generateHashRouterEntrypoint = generateHashRouterEntrypoint;
11
+ exports.writeStaticFile = writeStaticFile;
12
+ const tslib_1 = require("tslib");
13
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
14
+ const path_1 = tslib_1.__importDefault(require("path"));
15
+ // Secret way to set SSR plugin concurrency option
16
+ // Waiting for feedback before documenting this officially?
17
+ exports.SSGConcurrency = process.env.DOCUSAURUS_SSR_CONCURRENCY
18
+ ? parseInt(process.env.DOCUSAURUS_SSR_CONCURRENCY, 10)
19
+ : // Not easy to define a reasonable option default
20
+ // Will still be better than Infinity
21
+ // See also https://github.com/sindresorhus/p-map/issues/24
22
+ 32;
23
+ function pathnameToFilename({ pathname, trailingSlash, }) {
24
+ const outputFileName = pathname.replace(/^[/\\]/, ''); // Remove leading slashes for webpack-dev-server
25
+ // Paths ending with .html are left untouched
26
+ if (/\.html?$/i.test(outputFileName)) {
27
+ return outputFileName;
28
+ }
29
+ // Legacy retro-compatible behavior
30
+ if (typeof trailingSlash === 'undefined') {
31
+ return path_1.default.join(outputFileName, 'index.html');
32
+ }
33
+ // New behavior: we can say if we prefer file/folder output
34
+ // Useful resource: https://github.com/slorber/trailing-slash-guide
35
+ if (pathname === '' || pathname.endsWith('/') || trailingSlash) {
36
+ return path_1.default.join(outputFileName, 'index.html');
37
+ }
38
+ return `${outputFileName}.html`;
39
+ }
40
+ async function generateHashRouterEntrypoint({ content, params, }) {
41
+ await writeStaticFile({
42
+ pathname: '/',
43
+ content,
44
+ params,
45
+ });
46
+ }
47
+ async function writeStaticFile({ content, pathname, params, }) {
48
+ function removeBaseUrl(p, baseUrl) {
49
+ return baseUrl === '/' ? p : p.replace(new RegExp(`^${baseUrl}`), '/');
50
+ }
51
+ const filename = pathnameToFilename({
52
+ pathname: removeBaseUrl(pathname, params.baseUrl),
53
+ trailingSlash: params.trailingSlash,
54
+ });
55
+ const filePath = path_1.default.join(params.outDir, filename);
56
+ await fs_extra_1.default.ensureDir(path_1.default.dirname(filePath));
57
+ await fs_extra_1.default.writeFile(filePath, content);
58
+ }
@@ -5,11 +5,13 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { Configuration } from 'webpack';
8
- import type { Props } from '@docusaurus/types';
8
+ import type { ConfigureWebpackUtils, FasterConfig, Props } from '@docusaurus/types';
9
9
  export declare const clientDir: string;
10
10
  export declare function excludeJS(modulePath: string): boolean;
11
- export declare function createBaseConfig({ props, isServer, minify, }: {
11
+ export declare function createBaseConfig({ props, isServer, minify, faster, configureWebpackUtils, }: {
12
12
  props: Props;
13
13
  isServer: boolean;
14
14
  minify: boolean;
15
+ faster: FasterConfig;
16
+ configureWebpackUtils: ConfigureWebpackUtils;
15
17
  }): Promise<Configuration>;
@@ -12,10 +12,9 @@ exports.createBaseConfig = createBaseConfig;
12
12
  const tslib_1 = require("tslib");
13
13
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
14
14
  const path_1 = tslib_1.__importDefault(require("path"));
15
- const mini_css_extract_plugin_1 = tslib_1.__importDefault(require("mini-css-extract-plugin"));
15
+ const babel_1 = require("@docusaurus/babel");
16
+ const bundler_1 = require("@docusaurus/bundler");
16
17
  const utils_1 = require("@docusaurus/utils");
17
- const utils_2 = require("./utils");
18
- const minification_1 = require("./minification");
19
18
  const aliases_1 = require("./aliases");
20
19
  const CSS_REGEX = /\.css$/i;
21
20
  const CSS_MODULE_REGEX = /\.module\.css$/i;
@@ -42,19 +41,27 @@ function excludeJS(modulePath) {
42
41
  !/docusaurus(?:(?!node_modules).)*\.jsx?$/.test(modulePath) &&
43
42
  !LibrariesToTranspileRegex.test(modulePath));
44
43
  }
45
- async function createBaseConfig({ props, isServer, minify, }) {
44
+ async function createBaseConfig({ props, isServer, minify, faster, configureWebpackUtils, }) {
46
45
  const { outDir, siteDir, siteConfig, siteConfigPath, baseUrl, generatedFilesDir, routesPaths, siteMetadata, plugins, } = props;
47
46
  const totalPages = routesPaths.length;
48
47
  const isProd = process.env.NODE_ENV === 'production';
49
48
  const minimizeEnabled = minify && isProd;
50
- const fileLoaderUtils = (0, utils_1.getFileLoaderUtils)();
49
+ const fileLoaderUtils = (0, utils_1.getFileLoaderUtils)(isServer);
51
50
  const name = isServer ? 'server' : 'client';
52
51
  const mode = isProd ? 'production' : 'development';
53
52
  const themeAliases = await (0, aliases_1.loadThemeAliases)({ siteDir, plugins });
54
- return {
55
- mode,
56
- name,
57
- cache: {
53
+ const createJsLoader = await (0, bundler_1.createJsLoaderFactory)({ siteConfig });
54
+ const CSSExtractPlugin = await (0, bundler_1.getCSSExtractPlugin)({
55
+ currentBundler: props.currentBundler,
56
+ });
57
+ function getCache() {
58
+ if (props.currentBundler.name === 'rspack') {
59
+ // TODO Rspack only supports memory cache (as of Sept 2024)
60
+ // TODO re-enable file persistent cache one Rspack supports it
61
+ // See also https://rspack.dev/config/cache#cache
62
+ return undefined;
63
+ }
64
+ return {
58
65
  type: 'filesystem',
59
66
  // Can we share the same cache across locales?
60
67
  // Exploring that question at https://github.com/webpack/webpack/issues/13034
@@ -80,7 +87,12 @@ async function createBaseConfig({ props, isServer, minify, }) {
80
87
  siteConfigPath,
81
88
  ],
82
89
  },
83
- },
90
+ };
91
+ }
92
+ return {
93
+ mode,
94
+ name,
95
+ cache: getCache(),
84
96
  output: {
85
97
  pathinfo: false,
86
98
  path: outDir,
@@ -97,7 +109,6 @@ async function createBaseConfig({ props, isServer, minify, }) {
97
109
  },
98
110
  devtool: isProd ? undefined : 'eval-cheap-module-source-map',
99
111
  resolve: {
100
- unsafeCache: false, // Not enabled, does not seem to improve perf much
101
112
  extensions: ['.wasm', '.mjs', '.js', '.jsx', '.ts', '.tsx', '.json'],
102
113
  symlinks: true, // See https://github.com/facebook/docusaurus/issues/3272
103
114
  roots: [
@@ -134,7 +145,9 @@ async function createBaseConfig({ props, isServer, minify, }) {
134
145
  // Only minimize client bundle in production because server bundle is only
135
146
  // used for static site generation
136
147
  minimize: minimizeEnabled,
137
- minimizer: minimizeEnabled ? (0, minification_1.getMinimizer)() : undefined,
148
+ minimizer: minimizeEnabled
149
+ ? await (0, bundler_1.getMinimizers)({ faster, currentBundler: props.currentBundler })
150
+ : undefined,
138
151
  splitChunks: isServer
139
152
  ? false
140
153
  : {
@@ -175,16 +188,16 @@ async function createBaseConfig({ props, isServer, minify, }) {
175
188
  test: /\.[jt]sx?$/i,
176
189
  exclude: excludeJS,
177
190
  use: [
178
- (0, utils_2.getCustomizableJSLoader)(siteConfig.webpack?.jsLoader)({
191
+ createJsLoader({
179
192
  isServer,
180
- babelOptions: await (0, utils_2.getCustomBabelConfigFilePath)(siteDir),
193
+ babelOptions: await (0, babel_1.getCustomBabelConfigFilePath)(siteDir),
181
194
  }),
182
195
  ],
183
196
  },
184
197
  {
185
198
  test: CSS_REGEX,
186
199
  exclude: CSS_MODULE_REGEX,
187
- use: (0, utils_2.getStyleLoaders)(isServer, {
200
+ use: configureWebpackUtils.getStyleLoaders(isServer, {
188
201
  importLoaders: 1,
189
202
  sourceMap: !isProd,
190
203
  }),
@@ -193,11 +206,11 @@ async function createBaseConfig({ props, isServer, minify, }) {
193
206
  // using the extension .module.css
194
207
  {
195
208
  test: CSS_MODULE_REGEX,
196
- use: (0, utils_2.getStyleLoaders)(isServer, {
209
+ use: configureWebpackUtils.getStyleLoaders(isServer, {
197
210
  modules: {
198
- localIdentName: isProd
199
- ? `[local]_[contenthash:base64:4]`
200
- : `[local]_[path][name]`,
211
+ // Using the same CSS Module class pattern in dev/prod on purpose
212
+ // See https://github.com/facebook/docusaurus/pull/10423
213
+ localIdentName: `[local]_[contenthash:base64:4]`,
201
214
  exportOnlyLocals: isServer,
202
215
  },
203
216
  importLoaders: 1,
@@ -207,7 +220,7 @@ async function createBaseConfig({ props, isServer, minify, }) {
207
220
  ],
208
221
  },
209
222
  plugins: [
210
- new mini_css_extract_plugin_1.default({
223
+ new CSSExtractPlugin({
211
224
  filename: isProd
212
225
  ? 'assets/css/[name].[contenthash:8].css'
213
226
  : '[name].css',
@@ -4,18 +4,22 @@
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 { Props } from '@docusaurus/types';
7
+ import type { ConfigureWebpackUtils, FasterConfig, Props } from '@docusaurus/types';
8
8
  import type { Configuration } from 'webpack';
9
- export declare function createStartClientConfig({ props, minify, poll, }: {
9
+ export declare function createStartClientConfig({ props, minify, poll, faster, configureWebpackUtils, }: {
10
10
  props: Props;
11
11
  minify: boolean;
12
12
  poll: number | boolean | undefined;
13
+ faster: FasterConfig;
14
+ configureWebpackUtils: ConfigureWebpackUtils;
13
15
  }): Promise<{
14
16
  clientConfig: Configuration;
15
17
  }>;
16
- export declare function createBuildClientConfig({ props, minify, bundleAnalyzer, }: {
18
+ export declare function createBuildClientConfig({ props, minify, faster, configureWebpackUtils, bundleAnalyzer, }: {
17
19
  props: Props;
18
20
  minify: boolean;
21
+ faster: FasterConfig;
22
+ configureWebpackUtils: ConfigureWebpackUtils;
19
23
  bundleAnalyzer: boolean;
20
24
  }): Promise<{
21
25
  config: Configuration;
@@ -11,18 +11,26 @@ exports.createBuildClientConfig = createBuildClientConfig;
11
11
  const tslib_1 = require("tslib");
12
12
  const path_1 = tslib_1.__importDefault(require("path"));
13
13
  const webpack_merge_1 = tslib_1.__importDefault(require("webpack-merge"));
14
- const webpackbar_1 = tslib_1.__importDefault(require("webpackbar"));
15
- const webpack_1 = tslib_1.__importDefault(require("webpack"));
16
14
  const webpack_bundle_analyzer_1 = require("webpack-bundle-analyzer");
17
15
  const react_loadable_ssr_addon_v5_slorber_1 = tslib_1.__importDefault(require("react-loadable-ssr-addon-v5-slorber"));
18
16
  const html_webpack_plugin_1 = tslib_1.__importDefault(require("html-webpack-plugin"));
17
+ const bundler_1 = require("@docusaurus/bundler");
19
18
  const base_1 = require("./base");
20
19
  const ChunkAssetPlugin_1 = tslib_1.__importDefault(require("./plugins/ChunkAssetPlugin"));
21
20
  const CleanWebpackPlugin_1 = tslib_1.__importDefault(require("./plugins/CleanWebpackPlugin"));
22
21
  const ForceTerminatePlugin_1 = tslib_1.__importDefault(require("./plugins/ForceTerminatePlugin"));
23
22
  const StaticDirectoriesCopyPlugin_1 = require("./plugins/StaticDirectoriesCopyPlugin");
24
- async function createBaseClientConfig({ props, hydrate, minify, }) {
25
- const baseConfig = await (0, base_1.createBaseConfig)({ props, isServer: false, minify });
23
+ async function createBaseClientConfig({ props, hydrate, minify, faster, configureWebpackUtils, }) {
24
+ const baseConfig = await (0, base_1.createBaseConfig)({
25
+ props,
26
+ isServer: false,
27
+ minify,
28
+ faster,
29
+ configureWebpackUtils,
30
+ });
31
+ const ProgressBarPlugin = await (0, bundler_1.getProgressBarPlugin)({
32
+ currentBundler: props.currentBundler,
33
+ });
26
34
  return (0, webpack_merge_1.default)(baseConfig, {
27
35
  // Useless, disabled on purpose (errors on existing sites with no
28
36
  // browserslist config)
@@ -30,29 +38,33 @@ async function createBaseClientConfig({ props, hydrate, minify, }) {
30
38
  entry: path_1.default.resolve(__dirname, '../client/clientEntry.js'),
31
39
  optimization: {
32
40
  // Keep the runtime chunk separated to enable long term caching
33
- // https://twitter.com/wSokra/status/969679223278505985
41
+ // https://x.com/wSokra/status/969679223278505985
34
42
  runtimeChunk: true,
35
43
  },
36
44
  plugins: [
37
- new webpack_1.default.DefinePlugin({
45
+ new props.currentBundler.instance.DefinePlugin({
38
46
  'process.env.HYDRATE_CLIENT_ENTRY': JSON.stringify(hydrate),
39
47
  }),
40
48
  new ChunkAssetPlugin_1.default(),
41
- // Show compilation progress bar and build time.
42
- new webpackbar_1.default({
49
+ new ProgressBarPlugin({
43
50
  name: 'Client',
51
+ color: 'green',
52
+ }),
53
+ await (0, StaticDirectoriesCopyPlugin_1.createStaticDirectoriesCopyPlugin)({
54
+ props,
44
55
  }),
45
- await (0, StaticDirectoriesCopyPlugin_1.createStaticDirectoriesCopyPlugin)({ props }),
46
56
  ].filter(Boolean),
47
57
  });
48
58
  }
49
59
  // client config when running "docusaurus start"
50
- async function createStartClientConfig({ props, minify, poll, }) {
60
+ async function createStartClientConfig({ props, minify, poll, faster, configureWebpackUtils, }) {
51
61
  const { siteConfig, headTags, preBodyTags, postBodyTags } = props;
52
62
  const clientConfig = (0, webpack_merge_1.default)(await createBaseClientConfig({
53
63
  props,
54
64
  minify,
55
65
  hydrate: false,
66
+ faster,
67
+ configureWebpackUtils,
56
68
  }), {
57
69
  watchOptions: {
58
70
  ignored: /node_modules\/(?!@docusaurus)/,
@@ -65,7 +77,7 @@ async function createStartClientConfig({ props, minify, poll, }) {
65
77
  plugins: [
66
78
  // Generates an `index.html` file with the <script> injected.
67
79
  new html_webpack_plugin_1.default({
68
- template: path_1.default.join(__dirname, '../templates/dev.html.template.ejs'),
80
+ template: path_1.default.join(__dirname, './templates/dev.html.template.ejs'),
69
81
  // So we can define the position where the scripts are injected.
70
82
  inject: false,
71
83
  filename: 'index.html',
@@ -79,7 +91,7 @@ async function createStartClientConfig({ props, minify, poll, }) {
79
91
  return { clientConfig };
80
92
  }
81
93
  // client config when running "docusaurus build"
82
- async function createBuildClientConfig({ props, minify, bundleAnalyzer, }) {
94
+ async function createBuildClientConfig({ props, minify, faster, configureWebpackUtils, bundleAnalyzer, }) {
83
95
  // Apply user webpack config.
84
96
  const { generatedFilesDir, siteConfig } = props;
85
97
  const router = siteConfig.future.experimental_router;
@@ -87,7 +99,13 @@ async function createBuildClientConfig({ props, minify, bundleAnalyzer, }) {
87
99
  // This is because it will always be a client-rendered React app
88
100
  const hydrate = router !== 'hash';
89
101
  const clientManifestPath = path_1.default.join(generatedFilesDir, 'client-manifest.json');
90
- const config = (0, webpack_merge_1.default)(await createBaseClientConfig({ props, minify, hydrate }), {
102
+ const config = (0, webpack_merge_1.default)(await createBaseClientConfig({
103
+ props,
104
+ minify,
105
+ faster,
106
+ configureWebpackUtils,
107
+ hydrate,
108
+ }), {
91
109
  plugins: [
92
110
  new ForceTerminatePlugin_1.default(),
93
111
  // Remove/clean build folders before building bundles.
@@ -99,7 +117,7 @@ async function createBuildClientConfig({ props, minify, bundleAnalyzer, }) {
99
117
  new react_loadable_ssr_addon_v5_slorber_1.default({
100
118
  filename: clientManifestPath,
101
119
  }),
102
- ].filter((x) => Boolean(x)),
120
+ ],
103
121
  });
104
122
  return { config, clientManifestPath };
105
123
  }
@@ -4,22 +4,36 @@
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 { Configuration, RuleSetRule } from 'webpack';
8
- import type { Plugin, LoadedPlugin } from '@docusaurus/types';
7
+ import { getCurrentBundler, createJsLoaderFactory } from '@docusaurus/bundler';
8
+ import type { Configuration } from 'webpack';
9
+ import type { Plugin, ConfigureWebpackUtils, LoadedPlugin } from '@docusaurus/types';
10
+ /**
11
+ * Creates convenient utils to inject into the configureWebpack() lifecycle
12
+ * @param config the Docusaurus config
13
+ */
14
+ export declare function createConfigureWebpackUtils({ siteConfig, }: {
15
+ siteConfig: Parameters<typeof createJsLoaderFactory>[0]['siteConfig'] & Parameters<typeof getCurrentBundler>[0]['siteConfig'];
16
+ }): Promise<ConfigureWebpackUtils>;
9
17
  /**
10
18
  * Helper function to modify webpack config
11
19
  * @param configureWebpack a webpack config or a function to modify config
12
20
  * @param config initial webpack config
13
21
  * @param isServer indicates if this is a server webpack configuration
14
- * @param jsLoader custom js loader config
22
+ * @param utils the <code>ConfigureWebpackUtils</code> utils to inject into the configureWebpack() lifecycle
15
23
  * @param content content loaded by the plugin
16
24
  * @returns final/ modified webpack config
17
25
  */
18
- export declare function applyConfigureWebpack(configureWebpack: NonNullable<Plugin['configureWebpack']>, config: Configuration, isServer: boolean, jsLoader: 'babel' | ((isServer: boolean) => RuleSetRule) | undefined, content: unknown): Configuration;
26
+ export declare function applyConfigureWebpack({ configureWebpack, config, isServer, configureWebpackUtils, content, }: {
27
+ configureWebpack: NonNullable<Plugin['configureWebpack']>;
28
+ config: Configuration;
29
+ isServer: boolean;
30
+ configureWebpackUtils: ConfigureWebpackUtils;
31
+ content: unknown;
32
+ }): Configuration;
19
33
  export declare function applyConfigurePostCss(configurePostCss: NonNullable<Plugin['configurePostCss']>, config: Configuration): Configuration;
20
- export declare function executePluginsConfigureWebpack({ plugins, config, isServer, jsLoader, }: {
34
+ export declare function executePluginsConfigureWebpack({ plugins, config: configInput, isServer, configureWebpackUtils, }: {
21
35
  plugins: LoadedPlugin[];
22
36
  config: Configuration;
23
37
  isServer: boolean;
24
- jsLoader: 'babel' | ((isServer: boolean) => RuleSetRule) | undefined;
38
+ configureWebpackUtils: ConfigureWebpackUtils;
25
39
  }): Configuration;
@@ -6,28 +6,38 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createConfigureWebpackUtils = createConfigureWebpackUtils;
9
10
  exports.applyConfigureWebpack = applyConfigureWebpack;
10
11
  exports.applyConfigurePostCss = applyConfigurePostCss;
11
12
  exports.executePluginsConfigureWebpack = executePluginsConfigureWebpack;
12
13
  const webpack_merge_1 = require("webpack-merge");
13
- const utils_1 = require("./utils");
14
+ const bundler_1 = require("@docusaurus/bundler");
15
+ /**
16
+ * Creates convenient utils to inject into the configureWebpack() lifecycle
17
+ * @param config the Docusaurus config
18
+ */
19
+ async function createConfigureWebpackUtils({ siteConfig, }) {
20
+ const currentBundler = await (0, bundler_1.getCurrentBundler)({ siteConfig });
21
+ const getStyleLoaders = await (0, bundler_1.createStyleLoadersFactory)({ currentBundler });
22
+ const getJSLoader = await (0, bundler_1.createJsLoaderFactory)({ siteConfig });
23
+ return {
24
+ currentBundler,
25
+ getStyleLoaders,
26
+ getJSLoader,
27
+ };
28
+ }
14
29
  /**
15
30
  * Helper function to modify webpack config
16
31
  * @param configureWebpack a webpack config or a function to modify config
17
32
  * @param config initial webpack config
18
33
  * @param isServer indicates if this is a server webpack configuration
19
- * @param jsLoader custom js loader config
34
+ * @param utils the <code>ConfigureWebpackUtils</code> utils to inject into the configureWebpack() lifecycle
20
35
  * @param content content loaded by the plugin
21
36
  * @returns final/ modified webpack config
22
37
  */
23
- function applyConfigureWebpack(configureWebpack, config, isServer, jsLoader, content) {
24
- // Export some utility functions
25
- const utils = {
26
- getStyleLoaders: utils_1.getStyleLoaders,
27
- getJSLoader: (0, utils_1.getCustomizableJSLoader)(jsLoader),
28
- };
38
+ function applyConfigureWebpack({ configureWebpack, config, isServer, configureWebpackUtils, content, }) {
29
39
  if (typeof configureWebpack === 'function') {
30
- const { mergeStrategy, ...res } = configureWebpack(config, isServer, utils, content) ?? {};
40
+ const { mergeStrategy, ...res } = configureWebpack(config, isServer, configureWebpackUtils, content) ?? {};
31
41
  const customizeRules = mergeStrategy ?? {};
32
42
  return (0, webpack_merge_1.mergeWithCustomize)({
33
43
  customizeArray: (0, webpack_merge_1.customizeArray)(customizeRules),
@@ -74,14 +84,19 @@ function executePluginsConfigurePostCss({ plugins, config, }) {
74
84
  return resultConfig;
75
85
  }
76
86
  // Plugin Lifecycle - configureWebpack()
77
- function executePluginsConfigureWebpack({ plugins, config, isServer, jsLoader, }) {
87
+ function executePluginsConfigureWebpack({ plugins, config: configInput, isServer, configureWebpackUtils, }) {
88
+ let config = configInput;
78
89
  // Step1 - Configure Webpack
79
- let resultConfig = config;
80
90
  plugins.forEach((plugin) => {
81
91
  const { configureWebpack } = plugin;
82
92
  if (configureWebpack) {
83
- resultConfig = applyConfigureWebpack(configureWebpack.bind(plugin), // The plugin lifecycle may reference `this`.
84
- resultConfig, isServer, jsLoader, plugin.content);
93
+ config = applyConfigureWebpack({
94
+ configureWebpack: configureWebpack.bind(plugin), // The plugin lifecycle may reference `this`.
95
+ config,
96
+ isServer,
97
+ configureWebpackUtils,
98
+ content: plugin.content,
99
+ });
85
100
  }
86
101
  });
87
102
  // Step2 - For client code, configure PostCSS
@@ -90,10 +105,10 @@ function executePluginsConfigureWebpack({ plugins, config, isServer, jsLoader, }
90
105
  // See https://github.com/facebook/docusaurus/issues/10106
91
106
  // Note: it's useless to configure postCSS for the server
92
107
  if (!isServer) {
93
- resultConfig = executePluginsConfigurePostCss({
108
+ config = executePluginsConfigurePostCss({
94
109
  plugins,
95
- config: resultConfig,
110
+ config,
96
111
  });
97
112
  }
98
- return resultConfig;
113
+ return config;
99
114
  }
@@ -5,17 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { type Compiler } from 'webpack';
8
- /**
9
- * We modify webpack runtime to add an extra function called
10
- * "__webpack_require__.gca" that will allow us to get the corresponding chunk
11
- * asset for a webpack chunk. Pass it the chunkName or chunkId you want to load.
12
- * For example: if you have a chunk named "my-chunk-name" that will map to
13
- * "/publicPath/0a84b5e7.c8e35c7a.js" as its corresponding output path
14
- * __webpack_require__.gca("my-chunk-name") will return
15
- * "/publicPath/0a84b5e7.c8e35c7a.js"
16
- *
17
- * "gca" stands for "get chunk asset"
18
- */
19
8
  export default class ChunkAssetPlugin {
20
9
  apply(compiler: Compiler): void;
21
10
  }