@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
@@ -1,20 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Facebook, Inc. and its affiliates.
4
- *
5
- * This source code is licensed under the MIT license found in the
6
- * LICENSE file in the root directory of this source tree.
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.safeGlobby = safeGlobby;
10
- const tslib_1 = require("tslib");
11
- const path_1 = tslib_1.__importDefault(require("path"));
12
- const utils_1 = require("@docusaurus/utils");
13
- // Globby that fix Windows path patterns
14
- // See https://github.com/facebook/docusaurus/pull/4222#issuecomment-795517329
15
- async function safeGlobby(patterns, options) {
16
- // Required for Windows support, as paths using \ should not be used by globby
17
- // (also using the windows hard drive prefix like c: is not a good idea)
18
- const globPaths = patterns.map((dirPath) => (0, utils_1.posixPath)(path_1.default.relative(process.cwd(), dirPath)));
19
- return (0, utils_1.Globby)(globPaths, options);
20
- }
package/lib/ssg.d.ts DELETED
@@ -1,35 +0,0 @@
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 { AppRenderer, SiteCollectedData } from './common';
8
- import type { Manifest } from 'react-loadable-ssr-addon-v5-slorber';
9
- import type { SSRTemplateCompiled } from './templates/templates';
10
- export type SSGParams = {
11
- trailingSlash: boolean | undefined;
12
- manifest: Manifest;
13
- headTags: string;
14
- preBodyTags: string;
15
- postBodyTags: string;
16
- outDir: string;
17
- baseUrl: string;
18
- noIndex: boolean;
19
- DOCUSAURUS_VERSION: string;
20
- ssrTemplate: SSRTemplateCompiled;
21
- };
22
- export declare function loadAppRenderer({ serverBundlePath, }: {
23
- serverBundlePath: string;
24
- }): Promise<AppRenderer>;
25
- export declare function generateStaticFiles({ pathnames, renderer, params, }: {
26
- pathnames: string[];
27
- renderer: AppRenderer;
28
- params: SSGParams;
29
- }): Promise<{
30
- collectedData: SiteCollectedData;
31
- }>;
32
- export declare function generateHashRouterEntrypoint({ content, params, }: {
33
- content: string;
34
- params: SSGParams;
35
- }): Promise<void>;
package/lib/utils.d.ts DELETED
@@ -1,9 +0,0 @@
1
- export declare const PerfDebuggingEnabled: boolean;
2
- type PerfLoggerAPI = {
3
- start: (label: string) => void;
4
- end: (label: string) => void;
5
- log: (message: string) => void;
6
- async: <Result>(label: string, asyncFn: () => Result | Promise<Result>) => Promise<Result>;
7
- };
8
- export declare const PerfLogger: PerfLoggerAPI;
9
- export {};
package/lib/utils.js DELETED
@@ -1,78 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PerfLogger = exports.PerfDebuggingEnabled = void 0;
4
- const tslib_1 = require("tslib");
5
- /**
6
- * Copyright (c) Facebook, Inc. and its affiliates.
7
- *
8
- * This source code is licensed under the MIT license found in the
9
- * LICENSE file in the root directory of this source tree.
10
- */
11
- const async_hooks_1 = require("async_hooks");
12
- const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
13
- // For now this is a private env variable we use internally
14
- // But we'll want to expose this feature officially some day
15
- exports.PerfDebuggingEnabled = !!process.env.DOCUSAURUS_PERF_LOGGER;
16
- const Thresholds = {
17
- min: 5,
18
- yellow: 100,
19
- red: 1000,
20
- };
21
- const PerfPrefix = logger_1.default.yellow(`[PERF] `);
22
- // This is what enables to "see the parent stack" for each log
23
- // Parent1 > Parent2 > Parent3 > child trace
24
- const ParentPrefix = new async_hooks_1.AsyncLocalStorage();
25
- function applyParentPrefix(label) {
26
- const parentPrefix = ParentPrefix.getStore();
27
- return parentPrefix ? `${parentPrefix} > ${label}` : label;
28
- }
29
- function createPerfLogger() {
30
- if (!exports.PerfDebuggingEnabled) {
31
- const noop = () => { };
32
- return {
33
- start: noop,
34
- end: noop,
35
- log: noop,
36
- async: async (_label, asyncFn) => asyncFn(),
37
- };
38
- }
39
- const formatDuration = (duration) => {
40
- if (duration > Thresholds.red) {
41
- return logger_1.default.red(`${(duration / 1000).toFixed(2)} seconds!`);
42
- }
43
- else if (duration > Thresholds.yellow) {
44
- return logger_1.default.yellow(`${duration.toFixed(2)} ms`);
45
- }
46
- else {
47
- return logger_1.default.green(`${duration.toFixed(2)} ms`);
48
- }
49
- };
50
- const logDuration = (label, duration) => {
51
- if (duration < Thresholds.min) {
52
- return;
53
- }
54
- console.log(`${PerfPrefix + label} - ${formatDuration(duration)}`);
55
- };
56
- const start = (label) => performance.mark(label);
57
- const end = (label) => {
58
- const { duration } = performance.measure(label);
59
- performance.clearMarks(label);
60
- logDuration(applyParentPrefix(label), duration);
61
- };
62
- const log = (label) => console.log(PerfPrefix + applyParentPrefix(label));
63
- const async = async (label, asyncFn) => {
64
- const finalLabel = applyParentPrefix(label);
65
- const before = performance.now();
66
- const result = await ParentPrefix.run(finalLabel, () => asyncFn());
67
- const duration = performance.now() - before;
68
- logDuration(finalLabel, duration);
69
- return result;
70
- };
71
- return {
72
- start,
73
- end,
74
- log,
75
- async,
76
- };
77
- }
78
- exports.PerfLogger = createPerfLogger();
@@ -1,96 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Facebook, Inc. and its affiliates.
4
- *
5
- * This source code is licensed under the MIT license found in the
6
- * LICENSE file in the root directory of this source tree.
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.getMinimizer = getMinimizer;
10
- const tslib_1 = require("tslib");
11
- const terser_webpack_plugin_1 = tslib_1.__importDefault(require("terser-webpack-plugin"));
12
- const css_minimizer_webpack_plugin_1 = tslib_1.__importDefault(require("css-minimizer-webpack-plugin"));
13
- // See https://github.com/webpack-contrib/terser-webpack-plugin#parallel
14
- function getTerserParallel() {
15
- let terserParallel = true;
16
- if (process.env.TERSER_PARALLEL === 'false') {
17
- terserParallel = false;
18
- }
19
- else if (process.env.TERSER_PARALLEL &&
20
- parseInt(process.env.TERSER_PARALLEL, 10) > 0) {
21
- terserParallel = parseInt(process.env.TERSER_PARALLEL, 10);
22
- }
23
- return terserParallel;
24
- }
25
- function getJsMinifierPlugin() {
26
- return new terser_webpack_plugin_1.default({
27
- parallel: getTerserParallel(),
28
- terserOptions: {
29
- parse: {
30
- // We want uglify-js to parse ecma 8 code. However, we don't want it
31
- // to apply any minification steps that turns valid ecma 5 code
32
- // into invalid ecma 5 code. This is why the 'compress' and 'output'
33
- // sections only apply transformations that are ecma 5 safe
34
- // https://github.com/facebook/create-react-app/pull/4234
35
- ecma: 2020,
36
- },
37
- compress: {
38
- ecma: 5,
39
- },
40
- mangle: {
41
- safari10: true,
42
- },
43
- output: {
44
- ecma: 5,
45
- comments: false,
46
- // Turned on because emoji and regex is not minified properly using
47
- // default. See https://github.com/facebook/create-react-app/issues/2488
48
- ascii_only: true,
49
- },
50
- },
51
- });
52
- }
53
- function getAdvancedCssMinifier() {
54
- // Using the array syntax to add 2 minimizers
55
- // see https://github.com/webpack-contrib/css-minimizer-webpack-plugin#array
56
- return new css_minimizer_webpack_plugin_1.default({
57
- minimizerOptions: [
58
- // CssNano options
59
- {
60
- preset: require.resolve('@docusaurus/cssnano-preset'),
61
- },
62
- // CleanCss options
63
- {
64
- inline: false,
65
- level: {
66
- 1: {
67
- all: false,
68
- removeWhitespace: true,
69
- },
70
- 2: {
71
- all: true,
72
- restructureRules: true,
73
- removeUnusedAtRules: false,
74
- },
75
- },
76
- },
77
- ],
78
- minify: [
79
- css_minimizer_webpack_plugin_1.default.cssnanoMinify,
80
- css_minimizer_webpack_plugin_1.default.cleanCssMinify,
81
- ],
82
- });
83
- }
84
- function getMinimizer() {
85
- // This is an historical env variable to opt-out of the advanced minifier
86
- // Sometimes there's a bug in it and people are happy to disable it
87
- const useSimpleCssMinifier = process.env.USE_SIMPLE_CSS_MINIFIER === 'true';
88
- const minimizer = [getJsMinifierPlugin()];
89
- if (useSimpleCssMinifier) {
90
- minimizer.push(new css_minimizer_webpack_plugin_1.default());
91
- }
92
- else {
93
- minimizer.push(getAdvancedCssMinifier());
94
- }
95
- return minimizer;
96
- }
@@ -1,16 +0,0 @@
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 { Compiler } from 'webpack';
8
- type WaitPluginOptions = {
9
- filepath: string;
10
- };
11
- export default class WaitPlugin {
12
- filepath: string;
13
- constructor(options: WaitPluginOptions);
14
- apply(compiler: Compiler): void;
15
- }
16
- export {};
@@ -1,47 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Facebook, Inc. and its affiliates.
4
- *
5
- * This source code is licensed under the MIT license found in the
6
- * LICENSE file in the root directory of this source tree.
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- const tslib_1 = require("tslib");
10
- const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
11
- class WaitPlugin {
12
- constructor(options) {
13
- this.filepath = options.filepath;
14
- }
15
- apply(compiler) {
16
- // Before finishing the compilation step
17
- compiler.hooks.make.tapPromise('WaitPlugin', () => waitOn(this.filepath));
18
- }
19
- }
20
- exports.default = WaitPlugin;
21
- // This is a re-implementation of the algorithm used by the "wait-on" package
22
- // https://github.com/jeffbski/wait-on/blob/master/lib/wait-on.js#L200
23
- async function waitOn(filepath) {
24
- const pollingIntervalMs = 300;
25
- const stabilityWindowMs = 750;
26
- let lastFileSize = -1;
27
- let lastFileTime = -1;
28
- for (;;) {
29
- let size = -1;
30
- try {
31
- size = (await fs_extra_1.default.stat(filepath)).size;
32
- }
33
- catch (err) { }
34
- if (size !== -1) {
35
- if (lastFileTime === -1 || size !== lastFileSize) {
36
- lastFileSize = size;
37
- lastFileTime = performance.now();
38
- }
39
- else if (performance.now() - lastFileTime >= stabilityWindowMs) {
40
- return;
41
- }
42
- }
43
- await new Promise((resolve) => {
44
- setTimeout(resolve, pollingIntervalMs);
45
- });
46
- }
47
- }
@@ -1,33 +0,0 @@
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 webpack, { type Configuration, type RuleSetRule } from 'webpack';
8
- import type { TransformOptions } from '@babel/core';
9
- export declare function formatStatsErrorMessage(statsJson: ReturnType<webpack.Stats['toJson']> | undefined): string | undefined;
10
- export declare function printStatsWarnings(statsJson: ReturnType<webpack.Stats['toJson']> | undefined): void;
11
- export declare function getStyleLoaders(isServer: boolean, cssOptionsArg?: {
12
- [key: string]: unknown;
13
- }): RuleSetRule[];
14
- export declare function getCustomBabelConfigFilePath(siteDir: string): Promise<string | undefined>;
15
- export declare function getBabelOptions({ isServer, babelOptions, }?: {
16
- isServer?: boolean;
17
- babelOptions?: TransformOptions | string;
18
- }): TransformOptions;
19
- export declare const getCustomizableJSLoader: (jsLoader?: "babel" | ((isServer: boolean) => RuleSetRule)) => ({ isServer, babelOptions, }: {
20
- isServer: boolean;
21
- babelOptions?: TransformOptions | string;
22
- }) => RuleSetRule;
23
- declare global {
24
- interface Error {
25
- /** @see https://webpack.js.org/api/node/#error-handling */
26
- details: unknown;
27
- }
28
- }
29
- export declare function compile(config: Configuration[]): Promise<webpack.MultiStats>;
30
- export declare function getHttpsConfig(): Promise<boolean | {
31
- cert: Buffer;
32
- key: Buffer;
33
- }>;
@@ -1,215 +0,0 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Facebook, Inc. and its affiliates.
4
- *
5
- * This source code is licensed under the MIT license found in the
6
- * LICENSE file in the root directory of this source tree.
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.getCustomizableJSLoader = void 0;
10
- exports.formatStatsErrorMessage = formatStatsErrorMessage;
11
- exports.printStatsWarnings = printStatsWarnings;
12
- exports.getStyleLoaders = getStyleLoaders;
13
- exports.getCustomBabelConfigFilePath = getCustomBabelConfigFilePath;
14
- exports.getBabelOptions = getBabelOptions;
15
- exports.compile = compile;
16
- exports.getHttpsConfig = getHttpsConfig;
17
- const tslib_1 = require("tslib");
18
- const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
19
- const path_1 = tslib_1.__importDefault(require("path"));
20
- const crypto_1 = tslib_1.__importDefault(require("crypto"));
21
- const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
22
- const utils_1 = require("@docusaurus/utils");
23
- const mini_css_extract_plugin_1 = tslib_1.__importDefault(require("mini-css-extract-plugin"));
24
- const webpack_1 = tslib_1.__importDefault(require("webpack"));
25
- const formatWebpackMessages_1 = tslib_1.__importDefault(require("react-dev-utils/formatWebpackMessages"));
26
- function formatStatsErrorMessage(statsJson) {
27
- if (statsJson?.errors?.length) {
28
- // TODO formatWebpackMessages does not print stack-traces
29
- // Also the error causal chain is lost here
30
- // We log the stacktrace inside serverEntry.tsx for now (not ideal)
31
- const { errors } = (0, formatWebpackMessages_1.default)(statsJson);
32
- return errors
33
- .map((str) => logger_1.default.red(str))
34
- .join(`\n\n${logger_1.default.yellow('--------------------------')}\n\n`);
35
- }
36
- return undefined;
37
- }
38
- function printStatsWarnings(statsJson) {
39
- if (statsJson?.warnings?.length) {
40
- statsJson.warnings?.forEach((warning) => {
41
- logger_1.default.warn(warning);
42
- });
43
- }
44
- }
45
- // Utility method to get style loaders
46
- function getStyleLoaders(isServer, cssOptionsArg = {}) {
47
- const cssOptions = {
48
- // TODO turn esModule on later, see https://github.com/facebook/docusaurus/pull/6424
49
- esModule: false,
50
- ...cssOptionsArg,
51
- };
52
- if (isServer) {
53
- return cssOptions.modules
54
- ? [
55
- {
56
- loader: require.resolve('css-loader'),
57
- options: cssOptions,
58
- },
59
- ]
60
- : [
61
- {
62
- loader: mini_css_extract_plugin_1.default.loader,
63
- options: {
64
- // Don't emit CSS files for SSR (previously used null-loader)
65
- // See https://github.com/webpack-contrib/mini-css-extract-plugin/issues/90#issuecomment-811991738
66
- emit: false,
67
- },
68
- },
69
- {
70
- loader: require.resolve('css-loader'),
71
- options: cssOptions,
72
- },
73
- ];
74
- }
75
- return [
76
- {
77
- loader: mini_css_extract_plugin_1.default.loader,
78
- options: {
79
- esModule: true,
80
- },
81
- },
82
- {
83
- loader: require.resolve('css-loader'),
84
- options: cssOptions,
85
- },
86
- {
87
- // Options for PostCSS as we reference these options twice
88
- // Adds vendor prefixing based on your specified browser support in
89
- // package.json
90
- loader: require.resolve('postcss-loader'),
91
- options: {
92
- postcssOptions: {
93
- // Necessary for external CSS imports to work
94
- // https://github.com/facebook/create-react-app/issues/2677
95
- ident: 'postcss',
96
- plugins: [
97
- // eslint-disable-next-line global-require
98
- require('autoprefixer'),
99
- ],
100
- },
101
- },
102
- },
103
- ];
104
- }
105
- async function getCustomBabelConfigFilePath(siteDir) {
106
- const customBabelConfigurationPath = path_1.default.join(siteDir, utils_1.BABEL_CONFIG_FILE_NAME);
107
- return (await fs_extra_1.default.pathExists(customBabelConfigurationPath))
108
- ? customBabelConfigurationPath
109
- : undefined;
110
- }
111
- function getBabelOptions({ isServer, babelOptions, } = {}) {
112
- if (typeof babelOptions === 'string') {
113
- return {
114
- babelrc: false,
115
- configFile: babelOptions,
116
- caller: { name: isServer ? 'server' : 'client' },
117
- };
118
- }
119
- return {
120
- ...(babelOptions ?? { presets: [require.resolve('../babel/preset')] }),
121
- babelrc: false,
122
- configFile: false,
123
- caller: { name: isServer ? 'server' : 'client' },
124
- };
125
- }
126
- // Name is generic on purpose
127
- // we want to support multiple js loader implementations (babel + esbuild)
128
- function getDefaultBabelLoader({ isServer, babelOptions, }) {
129
- return {
130
- loader: require.resolve('babel-loader'),
131
- options: getBabelOptions({ isServer, babelOptions }),
132
- };
133
- }
134
- const getCustomizableJSLoader = (jsLoader = 'babel') => ({ isServer, babelOptions, }) => jsLoader === 'babel'
135
- ? getDefaultBabelLoader({ isServer, babelOptions })
136
- : jsLoader(isServer);
137
- exports.getCustomizableJSLoader = getCustomizableJSLoader;
138
- function compile(config) {
139
- return new Promise((resolve, reject) => {
140
- const compiler = (0, webpack_1.default)(config);
141
- compiler.run((err, stats) => {
142
- if (err) {
143
- logger_1.default.error(err.stack ?? err);
144
- if (err.details) {
145
- logger_1.default.error(err.details);
146
- }
147
- reject(err);
148
- }
149
- // Let plugins consume all the stats
150
- const errorsWarnings = stats?.toJson('errors-warnings');
151
- if (stats?.hasErrors()) {
152
- const statsErrorMessage = formatStatsErrorMessage(errorsWarnings);
153
- reject(new Error(`Failed to compile due to Webpack errors.\n${statsErrorMessage}`));
154
- }
155
- printStatsWarnings(errorsWarnings);
156
- // Webpack 5 requires calling close() so that persistent caching works
157
- // See https://github.com/webpack/webpack.js.org/pull/4775
158
- compiler.close((errClose) => {
159
- if (errClose) {
160
- logger_1.default.error(`Error while closing Webpack compiler: ${errClose}`);
161
- reject(errClose);
162
- }
163
- else {
164
- resolve(stats);
165
- }
166
- });
167
- });
168
- });
169
- }
170
- // Ensure the certificate and key provided are valid and if not
171
- // throw an easy to debug error
172
- function validateKeyAndCerts({ cert, key, keyFile, crtFile, }) {
173
- let encrypted;
174
- try {
175
- // publicEncrypt will throw an error with an invalid cert
176
- encrypted = crypto_1.default.publicEncrypt(cert, Buffer.from('test'));
177
- }
178
- catch (err) {
179
- logger_1.default.error `The certificate path=${crtFile} is invalid.`;
180
- throw err;
181
- }
182
- try {
183
- // privateDecrypt will throw an error with an invalid key
184
- crypto_1.default.privateDecrypt(key, encrypted);
185
- }
186
- catch (err) {
187
- logger_1.default.error `The certificate key path=${keyFile} is invalid.`;
188
- throw err;
189
- }
190
- }
191
- // Read file and throw an error if it doesn't exist
192
- async function readEnvFile(file, type) {
193
- if (!(await fs_extra_1.default.pathExists(file))) {
194
- throw new Error(`You specified ${type} in your env, but the file "${file}" can't be found.`);
195
- }
196
- return fs_extra_1.default.readFile(file);
197
- }
198
- // Get the https config
199
- // Return cert files if provided in env, otherwise just true or false
200
- async function getHttpsConfig() {
201
- const appDirectory = await fs_extra_1.default.realpath(process.cwd());
202
- const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env;
203
- const isHttps = HTTPS === 'true';
204
- if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) {
205
- const crtFile = path_1.default.resolve(appDirectory, SSL_CRT_FILE);
206
- const keyFile = path_1.default.resolve(appDirectory, SSL_KEY_FILE);
207
- const config = {
208
- cert: await readEnvFile(crtFile, 'SSL_CRT_FILE'),
209
- key: await readEnvFile(keyFile, 'SSL_KEY_FILE'),
210
- };
211
- validateKeyAndCerts({ ...config, keyFile, crtFile });
212
- return config;
213
- }
214
- return isHttps;
215
- }