refactor(core): prepare codebase for swappable bundler (#10497)

This commit is contained in:
Sébastien Lorber 2024-09-13 09:30:30 +02:00 committed by GitHub
parent 611842af91
commit 2495d059de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 430 additions and 121 deletions

View file

@ -21,6 +21,7 @@ import {sortRoutes} from '@docusaurus/core/src/server/plugins/routeConfig';
import {posixPath} from '@docusaurus/utils'; import {posixPath} from '@docusaurus/utils';
import {normalizePluginOptions} from '@docusaurus/utils-validation'; import {normalizePluginOptions} from '@docusaurus/utils-validation';
import {fromPartial} from '@total-typescript/shoehorn';
import pluginContentDocs from '../index'; import pluginContentDocs from '../index';
import {toSidebarsProp} from '../props'; import {toSidebarsProp} from '../props';
import {DefaultSidebarItemsGenerator} from '../sidebars/generator'; import {DefaultSidebarItemsGenerator} from '../sidebars/generator';
@ -288,8 +289,11 @@ describe('simple website', () => {
}, },
}, },
isServer: false, isServer: false,
utils: createConfigureWebpackUtils({ configureWebpackUtils: await createConfigureWebpackUtils({
siteConfig: {webpack: {jsLoader: 'babel'}}, siteConfig: {
webpack: {jsLoader: 'babel'},
future: {experimental_faster: fromPartial({})},
},
}), }),
content, content,
}); });

View file

@ -0,0 +1,17 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import type webpack from 'webpack';
// We use Webpack and Rspack interchangeably because most Rspack APIs are
// compatible with Webpack. So it's ok to use Webpack types for Rspack too.
// When compatibility doesn't work, use "CurrentBundler.name"
// See https://github.com/facebook/docusaurus/pull/10402
export type CurrentBundler = {
name: 'webpack' | 'rspack';
instance: typeof webpack;
};

View file

@ -127,6 +127,7 @@ export type FasterConfig = {
swcJsLoader: boolean; swcJsLoader: boolean;
swcJsMinimizer: boolean; swcJsMinimizer: boolean;
mdxCrossCompilerCache: boolean; mdxCrossCompilerCache: boolean;
rspackBundler: boolean;
}; };
export type FutureConfig = { export type FutureConfig = {

View file

@ -73,6 +73,8 @@ export {
HtmlTags, HtmlTags,
} from './plugin'; } from './plugin';
export {CurrentBundler} from './bundler';
export { export {
RouteConfig, RouteConfig,
PluginRouteConfig, PluginRouteConfig,

View file

@ -15,6 +15,7 @@ import type {ThemeConfig} from './config';
import type {LoadContext, Props} from './context'; import type {LoadContext, Props} from './context';
import type {SwizzleConfig} from './swizzle'; import type {SwizzleConfig} from './swizzle';
import type {RouteConfig} from './routing'; import type {RouteConfig} from './routing';
import type {CurrentBundler} from './bundler';
export type PluginOptions = {id?: string} & {[key: string]: unknown}; export type PluginOptions = {id?: string} & {[key: string]: unknown};
@ -54,6 +55,7 @@ export type PluginContentLoadedActions = {
}; };
export type ConfigureWebpackUtils = { export type ConfigureWebpackUtils = {
currentBundler: CurrentBundler;
getStyleLoaders: ( getStyleLoaders: (
isServer: boolean, isServer: boolean,
cssOptions: {[key: string]: unknown}, cssOptions: {[key: string]: unknown},
@ -130,7 +132,7 @@ export type Plugin<Content = unknown> = {
configureWebpack?: ( configureWebpack?: (
config: WebpackConfiguration, config: WebpackConfiguration,
isServer: boolean, isServer: boolean,
utils: ConfigureWebpackUtils, configureWebpackUtils: ConfigureWebpackUtils,
content: Content, content: Content,
) => WebpackConfiguration & { ) => WebpackConfiguration & {
mergeStrategy?: { mergeStrategy?: {

View file

@ -34,7 +34,12 @@ import defaultSSRTemplate from '../templates/ssr.html.template';
import type {SSGParams} from '../ssg'; import type {SSGParams} from '../ssg';
import type {Manifest} from 'react-loadable-ssr-addon-v5-slorber'; import type {Manifest} from 'react-loadable-ssr-addon-v5-slorber';
import type {LoadedPlugin, Props, RouterType} from '@docusaurus/types'; import type {
ConfigureWebpackUtils,
LoadedPlugin,
Props,
RouterType,
} from '@docusaurus/types';
import type {SiteCollectedData} from '../common'; import type {SiteCollectedData} from '../common';
export type BuildCLIOptions = Pick< export type BuildCLIOptions = Pick<
@ -165,6 +170,8 @@ async function buildLocale({
const router = siteConfig.future.experimental_router; const router = siteConfig.future.experimental_router;
const configureWebpackUtils = await createConfigureWebpackUtils({siteConfig});
// We can build the 2 configs in parallel // We can build the 2 configs in parallel
const [{clientConfig, clientManifestPath}, {serverConfig, serverBundlePath}] = const [{clientConfig, clientManifestPath}, {serverConfig, serverBundlePath}] =
await PerfLogger.async('Creating webpack configs', () => await PerfLogger.async('Creating webpack configs', () =>
@ -172,9 +179,11 @@ async function buildLocale({
getBuildClientConfig({ getBuildClientConfig({
props, props,
cliOptions, cliOptions,
configureWebpackUtils,
}), }),
getBuildServerConfig({ getBuildServerConfig({
props, props,
configureWebpackUtils,
}), }),
]), ]),
); );
@ -324,15 +333,18 @@ async function executeBrokenLinksCheck({
async function getBuildClientConfig({ async function getBuildClientConfig({
props, props,
cliOptions, cliOptions,
configureWebpackUtils,
}: { }: {
props: Props; props: Props;
cliOptions: BuildCLIOptions; cliOptions: BuildCLIOptions;
configureWebpackUtils: ConfigureWebpackUtils;
}) { }) {
const {plugins} = props; const {plugins} = props;
const result = await createBuildClientConfig({ const result = await createBuildClientConfig({
props, props,
minify: cliOptions.minify ?? true, minify: cliOptions.minify ?? true,
faster: props.siteConfig.future.experimental_faster, faster: props.siteConfig.future.experimental_faster,
configureWebpackUtils,
bundleAnalyzer: cliOptions.bundleAnalyzer ?? false, bundleAnalyzer: cliOptions.bundleAnalyzer ?? false,
}); });
let {config} = result; let {config} = result;
@ -340,26 +352,29 @@ async function getBuildClientConfig({
plugins, plugins,
config, config,
isServer: false, isServer: false,
utils: await createConfigureWebpackUtils({ configureWebpackUtils,
siteConfig: props.siteConfig,
}),
}); });
return {clientConfig: config, clientManifestPath: result.clientManifestPath}; return {clientConfig: config, clientManifestPath: result.clientManifestPath};
} }
async function getBuildServerConfig({props}: {props: Props}) { async function getBuildServerConfig({
props,
configureWebpackUtils,
}: {
props: Props;
configureWebpackUtils: ConfigureWebpackUtils;
}) {
const {plugins} = props; const {plugins} = props;
const result = await createServerConfig({ const result = await createServerConfig({
props, props,
configureWebpackUtils,
}); });
let {config} = result; let {config} = result;
config = executePluginsConfigureWebpack({ config = executePluginsConfigureWebpack({
plugins, plugins,
config, config,
isServer: true, isServer: true,
utils: await createConfigureWebpackUtils({ configureWebpackUtils,
siteConfig: props.siteConfig,
}),
}); });
return {serverConfig: config, serverBundlePath: result.serverBundlePath}; return {serverConfig: config, serverBundlePath: result.serverBundlePath};
} }

View file

@ -23,7 +23,7 @@ import {
} from '../../webpack/configure'; } from '../../webpack/configure';
import {createStartClientConfig} from '../../webpack/client'; import {createStartClientConfig} from '../../webpack/client';
import type {StartCLIOptions} from './start'; import type {StartCLIOptions} from './start';
import type {Props} from '@docusaurus/types'; import type {ConfigureWebpackUtils, Props} from '@docusaurus/types';
import type {Compiler} from 'webpack'; import type {Compiler} from 'webpack';
import type {OpenUrlContext} from './utils'; import type {OpenUrlContext} from './utils';
@ -127,23 +127,26 @@ async function getStartClientConfig({
props, props,
minify, minify,
poll, poll,
configureWebpackUtils,
}: { }: {
props: Props; props: Props;
minify: boolean; minify: boolean;
poll: number | boolean | undefined; poll: number | boolean | undefined;
configureWebpackUtils: ConfigureWebpackUtils;
}) { }) {
const {plugins, siteConfig} = props; const {plugins} = props;
let {clientConfig: config} = await createStartClientConfig({ let {clientConfig: config} = await createStartClientConfig({
props, props,
minify, minify,
faster: props.siteConfig.future.experimental_faster, faster: props.siteConfig.future.experimental_faster,
poll, poll,
configureWebpackUtils,
}); });
config = executePluginsConfigureWebpack({ config = executePluginsConfigureWebpack({
plugins, plugins,
config, config,
isServer: false, isServer: false,
utils: await createConfigureWebpackUtils({siteConfig}), configureWebpackUtils,
}); });
return config; return config;
} }
@ -157,10 +160,15 @@ export async function createWebpackDevServer({
cliOptions: StartCLIOptions; cliOptions: StartCLIOptions;
openUrlContext: OpenUrlContext; openUrlContext: OpenUrlContext;
}): Promise<WebpackDevServer> { }): Promise<WebpackDevServer> {
const configureWebpackUtils = await createConfigureWebpackUtils({
siteConfig: props.siteConfig,
});
const config = await getStartClientConfig({ const config = await getStartClientConfig({
props, props,
minify: cliOptions.minify ?? true, minify: cliOptions.minify ?? true,
poll: cliOptions.poll, poll: cliOptions.poll,
configureWebpackUtils,
}); });
const compiler = webpack(config); const compiler = webpack(config);

View file

@ -10,6 +10,7 @@ exports[`loadSiteConfig website with .cjs siteConfig 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },
@ -76,6 +77,7 @@ exports[`loadSiteConfig website with ts + js config 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },
@ -142,6 +144,7 @@ exports[`loadSiteConfig website with valid JS CJS config 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },
@ -208,6 +211,7 @@ exports[`loadSiteConfig website with valid JS ESM config 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },
@ -274,6 +278,7 @@ exports[`loadSiteConfig website with valid TypeScript CJS config 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },
@ -340,6 +345,7 @@ exports[`loadSiteConfig website with valid TypeScript ESM config 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },
@ -406,6 +412,7 @@ exports[`loadSiteConfig website with valid async config 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },
@ -474,6 +481,7 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },
@ -542,6 +550,7 @@ exports[`loadSiteConfig website with valid config creator function 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },
@ -613,6 +622,7 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },

View file

@ -80,6 +80,7 @@ exports[`load loads props for site with custom i18n path 1`] = `
"future": { "future": {
"experimental_faster": { "experimental_faster": {
"mdxCrossCompilerCache": false, "mdxCrossCompilerCache": false,
"rspackBundler": false,
"swcJsLoader": false, "swcJsLoader": false,
"swcJsMinimizer": false, "swcJsMinimizer": false,
}, },

View file

@ -49,6 +49,7 @@ describe('normalizeConfig', () => {
swcJsLoader: true, swcJsLoader: true,
swcJsMinimizer: true, swcJsMinimizer: true,
mdxCrossCompilerCache: true, mdxCrossCompilerCache: true,
rspackBundler: true,
}, },
experimental_storage: { experimental_storage: {
type: 'sessionStorage', type: 'sessionStorage',
@ -745,6 +746,7 @@ describe('future', () => {
swcJsLoader: true, swcJsLoader: true,
swcJsMinimizer: true, swcJsMinimizer: true,
mdxCrossCompilerCache: true, mdxCrossCompilerCache: true,
rspackBundler: true,
}, },
experimental_storage: { experimental_storage: {
type: 'sessionStorage', type: 'sessionStorage',
@ -1095,6 +1097,7 @@ describe('future', () => {
swcJsLoader: true, swcJsLoader: true,
swcJsMinimizer: true, swcJsMinimizer: true,
mdxCrossCompilerCache: true, mdxCrossCompilerCache: true,
rspackBundler: true,
}; };
expect( expect(
normalizeConfig({ normalizeConfig({
@ -1348,5 +1351,76 @@ describe('future', () => {
`); `);
}); });
}); });
describe('rspackBundler', () => {
it('accepts - undefined', () => {
const faster: Partial<FasterConfig> = {
rspackBundler: undefined,
};
expect(
normalizeConfig({
future: {
experimental_faster: faster,
},
}),
).toEqual(fasterContaining({rspackBundler: false}));
});
it('accepts - true', () => {
const faster: Partial<FasterConfig> = {
rspackBundler: true,
};
expect(
normalizeConfig({
future: {
experimental_faster: faster,
},
}),
).toEqual(fasterContaining({rspackBundler: true}));
});
it('accepts - false', () => {
const faster: Partial<FasterConfig> = {
rspackBundler: false,
};
expect(
normalizeConfig({
future: {
experimental_faster: faster,
},
}),
).toEqual(fasterContaining({rspackBundler: false}));
});
it('rejects - null', () => {
// @ts-expect-error: invalid
const faster: Partial<FasterConfig> = {rspackBundler: 42};
expect(() =>
normalizeConfig({
future: {
experimental_faster: faster,
},
}),
).toThrowErrorMatchingInlineSnapshot(`
""future.experimental_faster.rspackBundler" must be a boolean
"
`);
});
it('rejects - number', () => {
// @ts-expect-error: invalid
const faster: Partial<FasterConfig> = {rspackBundler: 42};
expect(() =>
normalizeConfig({
future: {
experimental_faster: faster,
},
}),
).toThrowErrorMatchingInlineSnapshot(`
""future.experimental_faster.rspackBundler" must be a boolean
"
`);
});
});
}); });
}); });

View file

@ -45,6 +45,7 @@ export const DEFAULT_FASTER_CONFIG: FasterConfig = {
swcJsLoader: false, swcJsLoader: false,
swcJsMinimizer: false, swcJsMinimizer: false,
mdxCrossCompilerCache: false, mdxCrossCompilerCache: false,
rspackBundler: false,
}; };
// When using the "faster: true" shortcut // When using the "faster: true" shortcut
@ -52,6 +53,7 @@ export const DEFAULT_FASTER_CONFIG_TRUE: FasterConfig = {
swcJsLoader: true, swcJsLoader: true,
swcJsMinimizer: true, swcJsMinimizer: true,
mdxCrossCompilerCache: true, mdxCrossCompilerCache: true,
rspackBundler: true,
}; };
export const DEFAULT_FUTURE_CONFIG: FutureConfig = { export const DEFAULT_FUTURE_CONFIG: FutureConfig = {
@ -222,6 +224,7 @@ const FASTER_CONFIG_SCHEMA = Joi.alternatives()
mdxCrossCompilerCache: Joi.boolean().default( mdxCrossCompilerCache: Joi.boolean().default(
DEFAULT_FASTER_CONFIG.mdxCrossCompilerCache, DEFAULT_FASTER_CONFIG.mdxCrossCompilerCache,
), ),
rspackBundler: Joi.boolean().default(DEFAULT_FASTER_CONFIG.rspackBundler),
}), }),
Joi.boolean() Joi.boolean()
.required() .required()

View file

@ -15,8 +15,15 @@ import {
DEFAULT_FASTER_CONFIG, DEFAULT_FASTER_CONFIG,
DEFAULT_FUTURE_CONFIG, DEFAULT_FUTURE_CONFIG,
} from '../../server/configValidation'; } from '../../server/configValidation';
import {createConfigureWebpackUtils} from '../configure';
import type {Props} from '@docusaurus/types'; import type {Props} from '@docusaurus/types';
function createTestConfigureWebpackUtils() {
return createConfigureWebpackUtils({
siteConfig: {webpack: {jsLoader: 'babel'}, future: DEFAULT_FUTURE_CONFIG},
});
}
describe('babel transpilation exclude logic', () => { describe('babel transpilation exclude logic', () => {
it('always transpiles client dir files', () => { it('always transpiles client dir files', () => {
const clientFiles = [ const clientFiles = [
@ -115,6 +122,7 @@ describe('base webpack config', () => {
isServer: true, isServer: true,
minify: true, minify: true,
faster: DEFAULT_FASTER_CONFIG, faster: DEFAULT_FASTER_CONFIG,
configureWebpackUtils: await createTestConfigureWebpackUtils(),
}) })
).resolve?.alias ?? {}) as {[alias: string]: string}; ).resolve?.alias ?? {}) as {[alias: string]: string};
// Make aliases relative so that test work on all computers // Make aliases relative so that test work on all computers
@ -125,7 +133,8 @@ describe('base webpack config', () => {
}); });
it('uses svg rule', async () => { it('uses svg rule', async () => {
const fileLoaderUtils = utils.getFileLoaderUtils(); const isServer = true;
const fileLoaderUtils = utils.getFileLoaderUtils(isServer);
const mockSvg = jest.spyOn(fileLoaderUtils.rules, 'svg'); const mockSvg = jest.spyOn(fileLoaderUtils.rules, 'svg');
jest jest
.spyOn(utils, 'getFileLoaderUtils') .spyOn(utils, 'getFileLoaderUtils')
@ -136,6 +145,7 @@ describe('base webpack config', () => {
isServer: false, isServer: false,
minify: false, minify: false,
faster: DEFAULT_FASTER_CONFIG, faster: DEFAULT_FASTER_CONFIG,
configureWebpackUtils: await createTestConfigureWebpackUtils(),
}); });
expect(mockSvg).toHaveBeenCalled(); expect(mockSvg).toHaveBeenCalled();
}); });

View file

@ -9,12 +9,25 @@ import webpack from 'webpack';
import {createBuildClientConfig, createStartClientConfig} from '../client'; import {createBuildClientConfig, createStartClientConfig} from '../client';
import {loadSetup} from '../../server/__tests__/testUtils'; import {loadSetup} from '../../server/__tests__/testUtils';
import {createConfigureWebpackUtils} from '../configure';
import {
DEFAULT_FASTER_CONFIG,
DEFAULT_FUTURE_CONFIG,
} from '../../server/configValidation';
function createTestConfigureWebpackUtils() {
return createConfigureWebpackUtils({
siteConfig: {webpack: {jsLoader: 'babel'}, future: DEFAULT_FUTURE_CONFIG},
});
}
describe('webpack dev config', () => { describe('webpack dev config', () => {
it('simple start', async () => { it('simple start', async () => {
const {props} = await loadSetup('simple-site'); const {props} = await loadSetup('simple-site');
const {clientConfig} = await createStartClientConfig({ const {clientConfig} = await createStartClientConfig({
props, props,
faster: DEFAULT_FASTER_CONFIG,
configureWebpackUtils: await createTestConfigureWebpackUtils(),
minify: false, minify: false,
poll: false, poll: false,
}); });
@ -25,6 +38,8 @@ describe('webpack dev config', () => {
const {props} = await loadSetup('simple-site'); const {props} = await loadSetup('simple-site');
const {config} = await createBuildClientConfig({ const {config} = await createBuildClientConfig({
props, props,
faster: DEFAULT_FASTER_CONFIG,
configureWebpackUtils: await createTestConfigureWebpackUtils(),
minify: false, minify: false,
bundleAnalyzer: false, bundleAnalyzer: false,
}); });
@ -35,6 +50,8 @@ describe('webpack dev config', () => {
const {props} = await loadSetup('custom-site'); const {props} = await loadSetup('custom-site');
const {clientConfig} = await createStartClientConfig({ const {clientConfig} = await createStartClientConfig({
props, props,
faster: DEFAULT_FASTER_CONFIG,
configureWebpackUtils: await createTestConfigureWebpackUtils(),
minify: false, minify: false,
poll: false, poll: false,
}); });
@ -45,6 +62,8 @@ describe('webpack dev config', () => {
const {props} = await loadSetup('custom-site'); const {props} = await loadSetup('custom-site');
const {config} = await createBuildClientConfig({ const {config} = await createBuildClientConfig({
props, props,
faster: DEFAULT_FASTER_CONFIG,
configureWebpackUtils: await createTestConfigureWebpackUtils(),
minify: false, minify: false,
bundleAnalyzer: false, bundleAnalyzer: false,
}); });

View file

@ -14,17 +14,22 @@ import {
executePluginsConfigureWebpack, executePluginsConfigureWebpack,
createConfigureWebpackUtils, createConfigureWebpackUtils,
} from '../configure'; } from '../configure';
import {DEFAULT_FUTURE_CONFIG} from '../../server/configValidation';
import type {Configuration} from 'webpack'; import type {Configuration} from 'webpack';
import type {LoadedPlugin, Plugin} from '@docusaurus/types'; import type {LoadedPlugin, Plugin} from '@docusaurus/types';
const utils = createConfigureWebpackUtils({ function createTestConfigureWebpackUtils() {
siteConfig: {webpack: {jsLoader: 'babel'}}, return createConfigureWebpackUtils({
}); siteConfig: {webpack: {jsLoader: 'babel'}, future: DEFAULT_FUTURE_CONFIG},
});
}
const isServer = false; const isServer = false;
describe('extending generated webpack config', () => { describe('extending generated webpack config', () => {
it('direct mutation on generated webpack config object', async () => { it('direct mutation on generated webpack config object', async () => {
const utils = await createTestConfigureWebpackUtils();
// Fake generated webpack config // Fake generated webpack config
let config: Configuration = { let config: Configuration = {
output: { output: {
@ -52,7 +57,7 @@ describe('extending generated webpack config', () => {
configureWebpack, configureWebpack,
config, config,
isServer, isServer,
utils, configureWebpackUtils: utils,
content: { content: {
content: 42, content: 42,
}, },
@ -69,6 +74,8 @@ describe('extending generated webpack config', () => {
}); });
it('webpack-merge with user webpack config object', async () => { it('webpack-merge with user webpack config object', async () => {
const utils = await createTestConfigureWebpackUtils();
let config: Configuration = { let config: Configuration = {
output: { output: {
path: __dirname, path: __dirname,
@ -88,7 +95,7 @@ describe('extending generated webpack config', () => {
configureWebpack, configureWebpack,
config, config,
isServer, isServer,
utils, configureWebpackUtils: utils,
content: { content: {
content: 42, content: 42,
}, },
@ -105,6 +112,8 @@ describe('extending generated webpack config', () => {
}); });
it('webpack-merge with custom strategy', async () => { it('webpack-merge with custom strategy', async () => {
const utils = await createTestConfigureWebpackUtils();
const config: Configuration = { const config: Configuration = {
module: { module: {
rules: [{use: 'xxx'}, {use: 'yyy'}], rules: [{use: 'xxx'}, {use: 'yyy'}],
@ -126,7 +135,7 @@ describe('extending generated webpack config', () => {
configureWebpack: createConfigureWebpack(), configureWebpack: createConfigureWebpack(),
config, config,
isServer, isServer,
utils, configureWebpackUtils: utils,
content: {content: 42}, content: {content: 42},
}); });
expect(defaultStrategyMergeConfig).toEqual({ expect(defaultStrategyMergeConfig).toEqual({
@ -139,7 +148,7 @@ describe('extending generated webpack config', () => {
configureWebpack: createConfigureWebpack({'module.rules': 'prepend'}), configureWebpack: createConfigureWebpack({'module.rules': 'prepend'}),
config, config,
isServer, isServer,
utils, configureWebpackUtils: utils,
content: {content: 42}, content: {content: 42},
}); });
expect(prependRulesStrategyConfig).toEqual({ expect(prependRulesStrategyConfig).toEqual({
@ -154,7 +163,7 @@ describe('extending generated webpack config', () => {
}), }),
config, config,
isServer, isServer,
utils, configureWebpackUtils: utils,
content: {content: 42}, content: {content: 42},
}); });
expect(uselessMergeStrategyConfig).toEqual({ expect(uselessMergeStrategyConfig).toEqual({
@ -293,11 +302,13 @@ describe('executePluginsConfigureWebpack', () => {
}); });
} }
it('can merge Webpack aliases of 2 plugins into base config', () => { it('can merge Webpack aliases of 2 plugins into base config', async () => {
const utils = await createTestConfigureWebpackUtils();
const config = executePluginsConfigureWebpack({ const config = executePluginsConfigureWebpack({
config: {resolve: {alias: {'initial-alias': 'initial-alias-value'}}}, config: {resolve: {alias: {'initial-alias': 'initial-alias-value'}}},
isServer, isServer,
utils, configureWebpackUtils: utils,
plugins: [ plugins: [
fakePlugin({ fakePlugin({
configureWebpack: () => { configureWebpack: () => {
@ -328,11 +339,13 @@ describe('executePluginsConfigureWebpack', () => {
); );
}); });
it('can configurePostCSS() for all loaders added through configureWebpack()', () => { it('can configurePostCSS() for all loaders added through configureWebpack()', async () => {
const utils = await createTestConfigureWebpackUtils();
const config = executePluginsConfigureWebpack({ const config = executePluginsConfigureWebpack({
config: {}, config: {},
isServer, isServer,
utils, configureWebpackUtils: utils,
plugins: [ plugins: [
fakePlugin({ fakePlugin({
configurePostCss: (postCssOptions) => { configurePostCss: (postCssOptions) => {

View file

@ -10,6 +10,14 @@ import webpack from 'webpack';
import createServerConfig from '../server'; import createServerConfig from '../server';
import {loadSetup} from '../../server/__tests__/testUtils'; import {loadSetup} from '../../server/__tests__/testUtils';
import {createConfigureWebpackUtils} from '../configure';
import {DEFAULT_FUTURE_CONFIG} from '../../server/configValidation';
function createTestConfigureWebpackUtils() {
return createConfigureWebpackUtils({
siteConfig: {webpack: {jsLoader: 'babel'}, future: DEFAULT_FUTURE_CONFIG},
});
}
describe('webpack production config', () => { describe('webpack production config', () => {
it('simple', async () => { it('simple', async () => {
@ -17,6 +25,7 @@ describe('webpack production config', () => {
const {props} = await loadSetup('simple-site'); const {props} = await loadSetup('simple-site');
const {config} = await createServerConfig({ const {config} = await createServerConfig({
props, props,
configureWebpackUtils: await createTestConfigureWebpackUtils(),
}); });
webpack.validate(config); webpack.validate(config);
}); });
@ -26,6 +35,7 @@ describe('webpack production config', () => {
const {props} = await loadSetup('custom-site'); const {props} = await loadSetup('custom-site');
const {config} = await createServerConfig({ const {config} = await createServerConfig({
props, props,
configureWebpackUtils: await createTestConfigureWebpackUtils(),
}); });
webpack.validate(config); webpack.validate(config);
}); });

View file

@ -7,17 +7,17 @@
import fs from 'fs-extra'; import fs from 'fs-extra';
import path from 'path'; import path from 'path';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import {md5Hash, getFileLoaderUtils} from '@docusaurus/utils'; import {md5Hash, getFileLoaderUtils} from '@docusaurus/utils';
import { import {createJsLoaderFactory, getCustomBabelConfigFilePath} from './utils';
createJsLoaderFactory,
getStyleLoaders,
getCustomBabelConfigFilePath,
} from './utils';
import {getMinimizers} from './minification'; import {getMinimizers} from './minification';
import {loadThemeAliases, loadDocusaurusAliases} from './aliases'; import {loadThemeAliases, loadDocusaurusAliases} from './aliases';
import {getCSSExtractPlugin} from './currentBundler';
import type {Configuration} from 'webpack'; import type {Configuration} from 'webpack';
import type {FasterConfig, Props} from '@docusaurus/types'; import type {
ConfigureWebpackUtils,
FasterConfig,
Props,
} from '@docusaurus/types';
const CSS_REGEX = /\.css$/i; const CSS_REGEX = /\.css$/i;
const CSS_MODULE_REGEX = /\.module\.css$/i; const CSS_MODULE_REGEX = /\.module\.css$/i;
@ -58,11 +58,13 @@ export async function createBaseConfig({
isServer, isServer,
minify, minify,
faster, faster,
configureWebpackUtils,
}: { }: {
props: Props; props: Props;
isServer: boolean; isServer: boolean;
minify: boolean; minify: boolean;
faster: FasterConfig; faster: FasterConfig;
configureWebpackUtils: ConfigureWebpackUtils;
}): Promise<Configuration> { }): Promise<Configuration> {
const { const {
outDir, outDir,
@ -88,6 +90,10 @@ export async function createBaseConfig({
const createJsLoader = await createJsLoaderFactory({siteConfig}); const createJsLoader = await createJsLoaderFactory({siteConfig});
const CSSExtractPlugin = await getCSSExtractPlugin({
currentBundler: configureWebpackUtils.currentBundler,
});
return { return {
mode, mode,
name, name,
@ -224,7 +230,7 @@ export async function createBaseConfig({
{ {
test: CSS_REGEX, test: CSS_REGEX,
exclude: CSS_MODULE_REGEX, exclude: CSS_MODULE_REGEX,
use: getStyleLoaders(isServer, { use: configureWebpackUtils.getStyleLoaders(isServer, {
importLoaders: 1, importLoaders: 1,
sourceMap: !isProd, sourceMap: !isProd,
}), }),
@ -233,7 +239,7 @@ export async function createBaseConfig({
// using the extension .module.css // using the extension .module.css
{ {
test: CSS_MODULE_REGEX, test: CSS_MODULE_REGEX,
use: getStyleLoaders(isServer, { use: configureWebpackUtils.getStyleLoaders(isServer, {
modules: { modules: {
// Using the same CSS Module class pattern in dev/prod on purpose // Using the same CSS Module class pattern in dev/prod on purpose
// See https://github.com/facebook/docusaurus/pull/10423 // See https://github.com/facebook/docusaurus/pull/10423
@ -247,7 +253,7 @@ export async function createBaseConfig({
], ],
}, },
plugins: [ plugins: [
new MiniCssExtractPlugin({ new CSSExtractPlugin({
filename: isProd filename: isProd
? 'assets/css/[name].[contenthash:8].css' ? 'assets/css/[name].[contenthash:8].css'
: '[name].css', : '[name].css',

View file

@ -17,7 +17,11 @@ import ChunkAssetPlugin from './plugins/ChunkAssetPlugin';
import CleanWebpackPlugin from './plugins/CleanWebpackPlugin'; import CleanWebpackPlugin from './plugins/CleanWebpackPlugin';
import ForceTerminatePlugin from './plugins/ForceTerminatePlugin'; import ForceTerminatePlugin from './plugins/ForceTerminatePlugin';
import {createStaticDirectoriesCopyPlugin} from './plugins/StaticDirectoriesCopyPlugin'; import {createStaticDirectoriesCopyPlugin} from './plugins/StaticDirectoriesCopyPlugin';
import type {FasterConfig, Props} from '@docusaurus/types'; import type {
ConfigureWebpackUtils,
FasterConfig,
Props,
} from '@docusaurus/types';
import type {Configuration} from 'webpack'; import type {Configuration} from 'webpack';
async function createBaseClientConfig({ async function createBaseClientConfig({
@ -25,17 +29,20 @@ async function createBaseClientConfig({
hydrate, hydrate,
minify, minify,
faster, faster,
configureWebpackUtils,
}: { }: {
props: Props; props: Props;
hydrate: boolean; hydrate: boolean;
minify: boolean; minify: boolean;
faster: FasterConfig; faster: FasterConfig;
configureWebpackUtils: ConfigureWebpackUtils;
}): Promise<Configuration> { }): Promise<Configuration> {
const baseConfig = await createBaseConfig({ const baseConfig = await createBaseConfig({
props, props,
isServer: false, isServer: false,
minify, minify,
faster, faster,
configureWebpackUtils,
}); });
return merge(baseConfig, { return merge(baseConfig, {
@ -57,7 +64,10 @@ async function createBaseClientConfig({
new WebpackBar({ new WebpackBar({
name: 'Client', name: 'Client',
}), }),
await createStaticDirectoriesCopyPlugin({props}), await createStaticDirectoriesCopyPlugin({
props,
currentBundler: configureWebpackUtils.currentBundler,
}),
].filter(Boolean), ].filter(Boolean),
}); });
} }
@ -68,11 +78,13 @@ export async function createStartClientConfig({
minify, minify,
poll, poll,
faster, faster,
configureWebpackUtils,
}: { }: {
props: Props; props: Props;
minify: boolean; minify: boolean;
poll: number | boolean | undefined; poll: number | boolean | undefined;
faster: FasterConfig; faster: FasterConfig;
configureWebpackUtils: ConfigureWebpackUtils;
}): Promise<{clientConfig: Configuration}> { }): Promise<{clientConfig: Configuration}> {
const {siteConfig, headTags, preBodyTags, postBodyTags} = props; const {siteConfig, headTags, preBodyTags, postBodyTags} = props;
@ -82,6 +94,7 @@ export async function createStartClientConfig({
minify, minify,
hydrate: false, hydrate: false,
faster, faster,
configureWebpackUtils,
}), }),
{ {
watchOptions: { watchOptions: {
@ -116,11 +129,13 @@ export async function createBuildClientConfig({
props, props,
minify, minify,
faster, faster,
configureWebpackUtils,
bundleAnalyzer, bundleAnalyzer,
}: { }: {
props: Props; props: Props;
minify: boolean; minify: boolean;
faster: FasterConfig; faster: FasterConfig;
configureWebpackUtils: ConfigureWebpackUtils;
bundleAnalyzer: boolean; bundleAnalyzer: boolean;
}): Promise<{config: Configuration; clientManifestPath: string}> { }): Promise<{config: Configuration; clientManifestPath: string}> {
// Apply user webpack config. // Apply user webpack config.
@ -137,7 +152,13 @@ export async function createBuildClientConfig({
); );
const config: Configuration = merge( const config: Configuration = merge(
await createBaseClientConfig({props, minify, faster, hydrate}), await createBaseClientConfig({
props,
minify,
faster,
configureWebpackUtils,
hydrate,
}),
{ {
plugins: [ plugins: [
new ForceTerminatePlugin(), new ForceTerminatePlugin(),

View file

@ -10,8 +10,8 @@ import {
customizeArray, customizeArray,
customizeObject, customizeObject,
} from 'webpack-merge'; } from 'webpack-merge';
import {createJsLoaderFactory, getStyleLoaders} from './utils'; import {createJsLoaderFactory, createStyleLoadersFactory} from './utils';
import {getCurrentBundler} from './currentBundler';
import type {Configuration, RuleSetRule} from 'webpack'; import type {Configuration, RuleSetRule} from 'webpack';
import type { import type {
Plugin, Plugin,
@ -27,11 +27,16 @@ import type {
export async function createConfigureWebpackUtils({ export async function createConfigureWebpackUtils({
siteConfig, siteConfig,
}: { }: {
siteConfig: Parameters<typeof createJsLoaderFactory>[0]['siteConfig']; siteConfig: Parameters<typeof createJsLoaderFactory>[0]['siteConfig'] &
Parameters<typeof getCurrentBundler>[0]['siteConfig'];
}): Promise<ConfigureWebpackUtils> { }): Promise<ConfigureWebpackUtils> {
const currentBundler = await getCurrentBundler({siteConfig});
const getStyleLoaders = await createStyleLoadersFactory({currentBundler});
const getJSLoader = await createJsLoaderFactory({siteConfig});
return { return {
currentBundler,
getStyleLoaders, getStyleLoaders,
getJSLoader: await createJsLoaderFactory({siteConfig}), getJSLoader,
}; };
} }
@ -48,18 +53,18 @@ export function applyConfigureWebpack({
configureWebpack, configureWebpack,
config, config,
isServer, isServer,
utils, configureWebpackUtils,
content, content,
}: { }: {
configureWebpack: NonNullable<Plugin['configureWebpack']>; configureWebpack: NonNullable<Plugin['configureWebpack']>;
config: Configuration; config: Configuration;
isServer: boolean; isServer: boolean;
utils: ConfigureWebpackUtils; configureWebpackUtils: ConfigureWebpackUtils;
content: unknown; content: unknown;
}): Configuration { }): Configuration {
if (typeof configureWebpack === 'function') { if (typeof configureWebpack === 'function') {
const {mergeStrategy, ...res} = const {mergeStrategy, ...res} =
configureWebpack(config, isServer, utils, content) ?? {}; configureWebpack(config, isServer, configureWebpackUtils, content) ?? {};
const customizeRules = mergeStrategy ?? {}; const customizeRules = mergeStrategy ?? {};
return mergeWithCustomize({ return mergeWithCustomize({
customizeArray: customizeArray(customizeRules), customizeArray: customizeArray(customizeRules),
@ -134,12 +139,12 @@ export function executePluginsConfigureWebpack({
plugins, plugins,
config: configInput, config: configInput,
isServer, isServer,
utils, configureWebpackUtils,
}: { }: {
plugins: LoadedPlugin[]; plugins: LoadedPlugin[];
config: Configuration; config: Configuration;
isServer: boolean; isServer: boolean;
utils: ConfigureWebpackUtils; configureWebpackUtils: ConfigureWebpackUtils;
}): Configuration { }): Configuration {
let config = configInput; let config = configInput;
@ -151,7 +156,7 @@ export function executePluginsConfigureWebpack({
configureWebpack: configureWebpack.bind(plugin), // The plugin lifecycle may reference `this`. configureWebpack: configureWebpack.bind(plugin), // The plugin lifecycle may reference `this`.
config, config,
isServer, isServer,
utils, configureWebpackUtils,
content: plugin.content, content: plugin.content,
}); });
} }

View file

@ -0,0 +1,66 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import webpack from 'webpack';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import CopyWebpackPlugin from 'copy-webpack-plugin';
import logger from '@docusaurus/logger';
import type {CurrentBundler, DocusaurusConfig} from '@docusaurus/types';
// We inject a site config slice because the Rspack flag might change place
type SiteConfigSlice = {
future: {
experimental_faster: Pick<
DocusaurusConfig['future']['experimental_faster'],
'rspackBundler'
>;
};
};
function isRspack(siteConfig: SiteConfigSlice): boolean {
return siteConfig.future.experimental_faster.rspackBundler;
}
export async function getCurrentBundler({
siteConfig,
}: {
siteConfig: SiteConfigSlice;
}): Promise<CurrentBundler> {
if (isRspack(siteConfig)) {
// TODO add support for Rspack
logger.error(
'Rspack bundler is not supported yet, will use Webpack instead',
);
}
return {
name: 'webpack',
instance: webpack,
};
}
export async function getCSSExtractPlugin({
currentBundler,
}: {
currentBundler: CurrentBundler;
}): Promise<typeof MiniCssExtractPlugin> {
if (currentBundler.name === 'rspack') {
throw new Error('Rspack bundler is not supported yet');
}
return MiniCssExtractPlugin;
}
export async function getCopyPlugin({
currentBundler,
}: {
currentBundler: CurrentBundler;
}): Promise<typeof CopyWebpackPlugin> {
if (currentBundler.name === 'rspack') {
throw new Error('Rspack bundler is not supported yet');
}
// https://github.com/webpack-contrib/copy-webpack-plugin
return CopyWebpackPlugin;
}

View file

@ -7,14 +7,21 @@
import path from 'path'; import path from 'path';
import fs from 'fs-extra'; import fs from 'fs-extra';
import CopyWebpackPlugin from 'copy-webpack-plugin'; import {getCopyPlugin} from '../currentBundler';
import type {Props} from '@docusaurus/types'; import type {CurrentBundler, Props} from '@docusaurus/types';
import type {WebpackPluginInstance} from 'webpack';
export async function createStaticDirectoriesCopyPlugin({ export async function createStaticDirectoriesCopyPlugin({
props, props,
currentBundler,
}: { }: {
props: Props; props: Props;
}): Promise<CopyWebpackPlugin | undefined> { currentBundler: CurrentBundler;
}): Promise<WebpackPluginInstance | undefined> {
const CopyPlugin = await getCopyPlugin({
currentBundler,
});
const { const {
outDir, outDir,
siteDir, siteDir,
@ -44,7 +51,7 @@ export async function createStaticDirectoriesCopyPlugin({
return undefined; return undefined;
} }
return new CopyWebpackPlugin({ return new CopyPlugin({
patterns: staticDirectories.map((dir) => ({ patterns: staticDirectories.map((dir) => ({
from: dir, from: dir,
to: outDir, to: outDir,

View file

@ -10,19 +10,22 @@ import merge from 'webpack-merge';
import {NODE_MAJOR_VERSION, NODE_MINOR_VERSION} from '@docusaurus/utils'; import {NODE_MAJOR_VERSION, NODE_MINOR_VERSION} from '@docusaurus/utils';
import WebpackBar from 'webpackbar'; import WebpackBar from 'webpackbar';
import {createBaseConfig} from './base'; import {createBaseConfig} from './base';
import type {Props} from '@docusaurus/types'; import type {ConfigureWebpackUtils, Props} from '@docusaurus/types';
import type {Configuration} from 'webpack'; import type {Configuration} from 'webpack';
export default async function createServerConfig(params: { export default async function createServerConfig({
props,
configureWebpackUtils,
}: {
props: Props; props: Props;
configureWebpackUtils: ConfigureWebpackUtils;
}): Promise<{config: Configuration; serverBundlePath: string}> { }): Promise<{config: Configuration; serverBundlePath: string}> {
const {props} = params;
const baseConfig = await createBaseConfig({ const baseConfig = await createBaseConfig({
props, props,
isServer: true, isServer: true,
minify: false, minify: false,
faster: props.siteConfig.future.experimental_faster, faster: props.siteConfig.future.experimental_faster,
configureWebpackUtils,
}); });
const outputFilename = 'server.bundle.js'; const outputFilename = 'server.bundle.js';

View file

@ -10,11 +10,15 @@ import path from 'path';
import crypto from 'crypto'; import crypto from 'crypto';
import logger from '@docusaurus/logger'; import logger from '@docusaurus/logger';
import {BABEL_CONFIG_FILE_NAME} from '@docusaurus/utils'; import {BABEL_CONFIG_FILE_NAME} from '@docusaurus/utils';
import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import webpack, {type Configuration} from 'webpack';
import webpack, {type Configuration, type RuleSetRule} from 'webpack';
import formatWebpackMessages from 'react-dev-utils/formatWebpackMessages'; import formatWebpackMessages from 'react-dev-utils/formatWebpackMessages';
import {importSwcJsLoaderFactory} from '../faster'; import {importSwcJsLoaderFactory} from '../faster';
import type {ConfigureWebpackUtils, DocusaurusConfig} from '@docusaurus/types'; import {getCSSExtractPlugin} from './currentBundler';
import type {
ConfigureWebpackUtils,
CurrentBundler,
DocusaurusConfig,
} from '@docusaurus/types';
import type {TransformOptions} from '@babel/core'; import type {TransformOptions} from '@babel/core';
export function formatStatsErrorMessage( export function formatStatsErrorMessage(
@ -42,13 +46,19 @@ export function printStatsWarnings(
} }
} }
// Utility method to get style loaders export async function createStyleLoadersFactory({
export function getStyleLoaders( currentBundler,
}: {
currentBundler: CurrentBundler;
}): Promise<ConfigureWebpackUtils['getStyleLoaders']> {
const CssExtractPlugin = await getCSSExtractPlugin({currentBundler});
return function getStyleLoaders(
isServer: boolean, isServer: boolean,
cssOptionsArg: { cssOptionsArg: {
[key: string]: unknown; [key: string]: unknown;
} = {}, } = {},
): RuleSetRule[] { ) {
const cssOptions: {[key: string]: unknown} = { const cssOptions: {[key: string]: unknown} = {
// TODO turn esModule on later, see https://github.com/facebook/docusaurus/pull/6424 // TODO turn esModule on later, see https://github.com/facebook/docusaurus/pull/6424
esModule: false, esModule: false,
@ -71,7 +81,7 @@ export function getStyleLoaders(
return [ return [
{ {
loader: MiniCssExtractPlugin.loader, loader: CssExtractPlugin.loader,
options: { options: {
esModule: true, esModule: true,
}, },
@ -104,6 +114,7 @@ export function getStyleLoaders(
}, },
}, },
]; ];
};
} }
export async function getCustomBabelConfigFilePath( export async function getCustomBabelConfigFilePath(

View file

@ -313,6 +313,7 @@ rmiz
rsdoctor rsdoctor
Rsdoctor Rsdoctor
RSDOCTOR RSDOCTOR
rspack
Rspack Rspack
rtcts rtcts
rtlcss rtlcss

View file

@ -5082,7 +5082,7 @@ cacheable-request@^10.2.8:
normalize-url "^8.0.0" normalize-url "^8.0.0"
responselike "^3.0.0" responselike "^3.0.0"
call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.7: call-bind@^1.0.2, call-bind@^1.0.7:
version "1.0.7" version "1.0.7"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
@ -8260,7 +8260,7 @@ get-caller-file@^2.0.5:
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.4: get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.4:
version "1.2.4" version "1.2.4"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
@ -12816,7 +12816,7 @@ object-hash@^3.0.0:
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9"
integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==
object-inspect@^1.12.3, object-inspect@^1.13.1, object-inspect@^1.9.0: object-inspect@^1.12.3, object-inspect@^1.13.1:
version "1.13.2" version "1.13.2"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff"
integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==