diff --git a/.changeset/clever-trams-grab.md b/.changeset/clever-trams-grab.md new file mode 100644 index 000000000..e7b7e0cd0 --- /dev/null +++ b/.changeset/clever-trams-grab.md @@ -0,0 +1,5 @@ +--- +"@callstack/repack": minor +--- + +Introduce `BabelSwcLoader`, available as `@callstack/repack/babel-swc-loader` which combines Babel and SWC into one loader, enabling Babel level of customiziability while maitaning good build performance. Can be run in parallel with `experiments.parallelLoader` in Rspack. diff --git a/.changeset/dirty-cups-pick.md b/.changeset/dirty-cups-pick.md new file mode 100644 index 000000000..c27f8cc74 --- /dev/null +++ b/.changeset/dirty-cups-pick.md @@ -0,0 +1,6 @@ +--- +"@callstack/repack-plugin-nativewind": minor +"@callstack/repack": minor +--- + +ReanimatedPlugin: skip running the loader when `babel-swc-loader` is detected as part of loader chain diff --git a/.changeset/mighty-plums-shout.md b/.changeset/mighty-plums-shout.md new file mode 100644 index 000000000..8e5ab4b7d --- /dev/null +++ b/.changeset/mighty-plums-shout.md @@ -0,0 +1,5 @@ +--- +"@callstack/repack": minor +--- + +Introduce `BabelLoader`, available as `@callstack/repack/babel-loader` which utilizes `hermes-parser` for JS & Flow files and default babel parser for TS files. Can be run in parallel with `experiments.parallelLoader` in Rspack. \ No newline at end of file diff --git a/apps/tester-app/__tests__/configs/webpack.config.mjs b/apps/tester-app/__tests__/configs/webpack.config.mjs index 8546cfe68..40540d133 100644 --- a/apps/tester-app/__tests__/configs/webpack.config.mjs +++ b/apps/tester-app/__tests__/configs/webpack.config.mjs @@ -8,7 +8,7 @@ export default async (env) => { path: process.env.TEST_WEBPACK_OUTPUT_DIR, }, experiments: { - ...config.output.experiments, + ...config.experiments, lazyCompilation: false, }, }; diff --git a/apps/tester-app/babel.config.js b/apps/tester-app/babel.config.js index 49f649ddd..054c21b28 100644 --- a/apps/tester-app/babel.config.js +++ b/apps/tester-app/babel.config.js @@ -1,13 +1,9 @@ module.exports = { - presets: ['module:@react-native/babel-preset'], - comments: true, + presets: ['@react-native/babel-preset'], plugins: [ [ '@babel/plugin-transform-react-jsx', - { - runtime: 'automatic', - importSource: 'nativewind', - }, + { runtime: 'automatic', importSource: 'nativewind' }, ], 'react-native-worklets/plugin', ], diff --git a/apps/tester-app/package.json b/apps/tester-app/package.json index f9d64c0db..c30cb8067 100644 --- a/apps/tester-app/package.json +++ b/apps/tester-app/package.json @@ -46,6 +46,7 @@ "@rsdoctor/rspack-plugin": "^0.4.11", "@rspack/core": "catalog:", "@svgr/webpack": "^8.1.0", + "@swc/core": "^1.13.3", "@swc/helpers": "catalog:", "@types/jest": "^29.5.13", "@types/react": "catalog:testers", @@ -58,6 +59,7 @@ "react-native-test-app": "catalog:testers", "tailwindcss": "^3.4.17", "terser-webpack-plugin": "catalog:", + "thread-loader": "^4.0.4", "typescript": "catalog:", "vitest": "catalog:", "webpack": "catalog:" diff --git a/apps/tester-app/rspack.config.mjs b/apps/tester-app/rspack.config.mjs index 3bdd1226b..8630a48ff 100644 --- a/apps/tester-app/rspack.config.mjs +++ b/apps/tester-app/rspack.config.mjs @@ -20,6 +20,9 @@ export default Repack.defineRspackConfig((env) => { mode, context, entry: './index.js', + experiments: { + parallelLoader: true, + }, resolve: { ...Repack.getResolveOptions({ enablePackageExports: true }), }, @@ -28,9 +31,15 @@ export default Repack.defineRspackConfig((env) => { }, module: { rules: [ - ...Repack.getJsTransformRules({ - swc: { importSource: 'nativewind' }, - }), + { + test: /\.[cm]?[jt]sx?$/, + use: { + loader: '@callstack/repack/babel-swc-loader', + parallel: true, + options: {}, + }, + type: 'javascript/auto', + }, { test: Repack.getAssetExtensionsRegExp( Repack.ASSET_EXTENSIONS.filter((ext) => ext !== 'svg') diff --git a/apps/tester-app/webpack.config.mjs b/apps/tester-app/webpack.config.mjs index fb9834734..37709ff0a 100644 --- a/apps/tester-app/webpack.config.mjs +++ b/apps/tester-app/webpack.config.mjs @@ -51,7 +51,7 @@ export default Repack.defineWebpackConfig((env) => { rules: [ { test: /\.[cm]?[jt]sx?$/, - use: 'babel-loader', + use: ['thread-loader', '@callstack/repack/babel-swc-loader'], type: 'javascript/auto', }, { diff --git a/apps/tester-federation-v2/configs/rspack.host-app.mts b/apps/tester-federation-v2/configs/rspack.host-app.mts index 4dcc7c07b..87cde819f 100644 --- a/apps/tester-federation-v2/configs/rspack.host-app.mts +++ b/apps/tester-federation-v2/configs/rspack.host-app.mts @@ -8,6 +8,9 @@ export default Repack.defineRspackConfig((env) => { mode, context, entry: './src/host/index.js', + experiments: { + parallelLoader: true, + }, resolve: { ...Repack.getResolveOptions({ enablePackageExports: true }), }, @@ -17,7 +20,15 @@ export default Repack.defineRspackConfig((env) => { }, module: { rules: [ - ...Repack.getJsTransformRules(), + { + test: /\.[cm]?[jt]sx?$/, + use: { + loader: '@callstack/repack/babel-swc-loader', + parallel: true, + options: {}, + }, + type: 'javascript/auto', + }, ...Repack.getAssetTransformRules(), ], }, diff --git a/apps/tester-federation-v2/configs/rspack.mini-app.mts b/apps/tester-federation-v2/configs/rspack.mini-app.mts index a2ea6cfa7..f2aeabce8 100644 --- a/apps/tester-federation-v2/configs/rspack.mini-app.mts +++ b/apps/tester-federation-v2/configs/rspack.mini-app.mts @@ -8,6 +8,9 @@ export default Repack.defineRspackConfig((env) => { mode, context, entry: './src/mini/index.js', + experiments: { + parallelLoader: true, + }, resolve: { ...Repack.getResolveOptions({ enablePackageExports: true }), }, @@ -17,7 +20,15 @@ export default Repack.defineRspackConfig((env) => { }, module: { rules: [ - ...Repack.getJsTransformRules(), + { + test: /\.[cm]?[jt]sx?$/, + use: { + loader: '@callstack/repack/babel-swc-loader', + parallel: true, + options: {}, + }, + type: 'javascript/auto', + }, ...Repack.getAssetTransformRules({ inline: true }), ], }, diff --git a/apps/tester-federation-v2/configs/webpack.host-app.mts b/apps/tester-federation-v2/configs/webpack.host-app.mts index 2e314f944..3e634baf8 100644 --- a/apps/tester-federation-v2/configs/webpack.host-app.mts +++ b/apps/tester-federation-v2/configs/webpack.host-app.mts @@ -20,7 +20,7 @@ export default Repack.defineWebpackConfig((env) => { rules: [ { test: /\.[cm]?[jt]sx?$/, - use: 'babel-loader', + use: '@callstack/repack/babel-swc-loader', type: 'javascript/auto', }, ...Repack.getAssetTransformRules(), diff --git a/apps/tester-federation-v2/configs/webpack.mini-app.mts b/apps/tester-federation-v2/configs/webpack.mini-app.mts index 2752d2d87..a09eda442 100644 --- a/apps/tester-federation-v2/configs/webpack.mini-app.mts +++ b/apps/tester-federation-v2/configs/webpack.mini-app.mts @@ -19,7 +19,7 @@ export default Repack.defineWebpackConfig((env) => { rules: [ { test: /\.[cm]?[jt]sx?$/, - use: 'babel-loader', + use: '@callstack/repack/babel-swc-loader', type: 'javascript/auto', }, ...Repack.getAssetTransformRules({ inline: true }), diff --git a/apps/tester-federation/configs/rspack.host-app.mts b/apps/tester-federation/configs/rspack.host-app.mts index 0117fb0fc..33efbec4a 100644 --- a/apps/tester-federation/configs/rspack.host-app.mts +++ b/apps/tester-federation/configs/rspack.host-app.mts @@ -9,6 +9,9 @@ export default Repack.defineRspackConfig((env) => { mode, context, entry: './src/host/index.js', + experiments: { + parallelLoader: true, + }, resolve: { ...Repack.getResolveOptions({ enablePackageExports: true }), }, @@ -18,7 +21,15 @@ export default Repack.defineRspackConfig((env) => { }, module: { rules: [ - ...Repack.getJsTransformRules(), + { + test: /\.[cm]?[jt]sx?$/, + type: 'javascript/auto', + use: { + loader: '@callstack/repack/babel-swc-loader', + parallel: true, + options: {}, + }, + }, ...Repack.getAssetTransformRules(), ], }, diff --git a/apps/tester-federation/configs/rspack.mini-app.mts b/apps/tester-federation/configs/rspack.mini-app.mts index 42c6d9111..ca5924a2d 100644 --- a/apps/tester-federation/configs/rspack.mini-app.mts +++ b/apps/tester-federation/configs/rspack.mini-app.mts @@ -9,6 +9,9 @@ export default Repack.defineRspackConfig((env) => { mode, context, entry: './src/mini/index.js', + experiments: { + parallelLoader: true, + }, resolve: { ...Repack.getResolveOptions({ enablePackageExports: true }), }, @@ -18,7 +21,15 @@ export default Repack.defineRspackConfig((env) => { }, module: { rules: [ - ...Repack.getJsTransformRules(), + { + test: /\.[cm]?[jt]sx?$/, + use: { + loader: '@callstack/repack/babel-swc-loader', + parallel: true, + options: {}, + }, + type: 'javascript/auto', + }, ...Repack.getAssetTransformRules({ inline: true }), ], }, diff --git a/apps/tester-federation/configs/webpack.host-app.mts b/apps/tester-federation/configs/webpack.host-app.mts index da73ff3cd..8831b2c96 100644 --- a/apps/tester-federation/configs/webpack.host-app.mts +++ b/apps/tester-federation/configs/webpack.host-app.mts @@ -19,7 +19,7 @@ export default Repack.defineWebpackConfig((env) => { rules: [ { test: /\.[cm]?[jt]sx?$/, - use: 'babel-loader', + use: '@callstack/repack/babel-swc-loader', type: 'javascript/auto', }, ...Repack.getAssetTransformRules(), diff --git a/apps/tester-federation/configs/webpack.mini-app.mts b/apps/tester-federation/configs/webpack.mini-app.mts index dc60f1c9a..8ff9e4ac3 100644 --- a/apps/tester-federation/configs/webpack.mini-app.mts +++ b/apps/tester-federation/configs/webpack.mini-app.mts @@ -19,7 +19,7 @@ export default Repack.defineWebpackConfig((env) => { rules: [ { test: /\.[cm]?[jt]sx?$/, - use: 'babel-loader', + use: '@callstack/repack/babel-swc-loader', type: 'javascript/auto', }, ...Repack.getAssetTransformRules({ inline: true }), diff --git a/packages/plugin-nativewind/src/plugin.ts b/packages/plugin-nativewind/src/plugin.ts index b8463e04c..d2d4e6002 100644 --- a/packages/plugin-nativewind/src/plugin.ts +++ b/packages/plugin-nativewind/src/plugin.ts @@ -151,6 +151,8 @@ export class NativeWindPlugin { * Second, we need to configure the `builtin:swc-loader` to properly handle NativeWind's JSX transformations. * We look for any instances of the `builtin:swc-loader` in the Rspack configuration and modify their options * to include the NativeWind react import source. + * + * TODO made obsolete by the new babel-swc-loader, remove in 6.0 */ compiler.options.module.rules.forEach((rule) => { if (!rule || typeof rule !== 'object') { diff --git a/packages/plugin-reanimated/src/loader.ts b/packages/plugin-reanimated/src/loader.ts index dfc8a0f8d..cb7c2afb1 100644 --- a/packages/plugin-reanimated/src/loader.ts +++ b/packages/plugin-reanimated/src/loader.ts @@ -5,6 +5,10 @@ interface ReanimatedLoaderOptions { babelPlugins?: string[]; } +interface ReanimatedLoaderData { + skip?: boolean; +} + // Reference: https://github.com/software-mansion/react-native-reanimated/blob/3.16.3/packages/react-native-reanimated/plugin/src/autoworkletization.ts#L19-L59 const REANIMATED_AUTOWORKLETIZATION_KEYWORDS = [ 'worklet', @@ -39,7 +43,8 @@ export default function reanimatedLoader( const callback = this.async(); const options = this.getOptions(); - if (!REANIMATED_REGEX.test(source)) { + const loaderData = this.data as ReanimatedLoaderData; + if (loaderData.skip || !REANIMATED_REGEX.test(source)) { callback(null, source); return; } @@ -68,3 +73,31 @@ export default function reanimatedLoader( } ); } + +// resolve the path to the babel-swc-loader once +const babelSwcLoader = require.resolve('@callstack/repack/babel-swc-loader'); +let warningDisplayed = false; + +export function pitch( + this: LoaderContext, + _remainingRequest: string, + _previousRequest: string, + data: ReanimatedLoaderData +) { + const logger = this.getLogger('RepackReanimatedLoader'); + for (const loader of this.loaders) { + // if the babel-swc-loader is found, we skip the reanimated-loader + // since babel-swc-loader is more performant and uses the official + // babel plugin directly + if (loader.path === babelSwcLoader) { + data.skip = true; + if (!warningDisplayed) { + warningDisplayed = true; + logger.warn( + '`@callstack/repack-plugin-reanimated` should not be used with `@callstack/repack/babel-swc-loader`. ' + + 'Instead, add the `react-native-reanimated/plugin` (or `react-native-worklets/plugin`) directly to your list of babel plugins in the `babel.config.js` file in the project root.' + ); + } + } + } +} diff --git a/packages/plugin-reanimated/src/plugin.ts b/packages/plugin-reanimated/src/plugin.ts index eb087891b..015613256 100644 --- a/packages/plugin-reanimated/src/plugin.ts +++ b/packages/plugin-reanimated/src/plugin.ts @@ -19,6 +19,7 @@ export class ReanimatedPlugin { const reanimatedVersion = this.getReanimatedVersion(reanimatedPath); // add rules for transpiling wih reanimated loader + // TODO made obsolete by the new babel-swc-loader, remove in 6.0 compiler.options.module.rules.push( reanimatedVersion.major < 4 ? reanimated3ModuleRules diff --git a/packages/repack/package.json b/packages/repack/package.json index 2f6fa852b..47c8cf8aa 100644 --- a/packages/repack/package.json +++ b/packages/repack/package.json @@ -10,6 +10,8 @@ "./client": "./client/index.js", "./commands/*": "./commands/*.js", "./assets-loader": "./dist/loaders/assetsLoader/index.js", + "./babel-loader": "./dist/loaders/babelLoader/index.js", + "./babel-swc-loader": "./dist/loaders/babelSwcLoader/index.js", "./flow-loader": "./dist/loaders/flowLoader/index.js", "./react-refresh-loader": "./dist/loaders/reactRefreshLoader/index.js", "./mf/*": "./mf/*.js", @@ -109,6 +111,7 @@ "@module-federation/sdk": "0.6.10", "@rspack/core": "catalog:", "@swc/helpers": "catalog:", + "@types/babel__core": "^7.20.5", "@types/dedent": "^0.7.0", "@types/gradient-string": "^1.1.6", "@types/jest": "^29.5.12", diff --git a/packages/repack/src/loaders/babelLoader/__tests__/__snapshots__/babelLoader.test.ts.snap b/packages/repack/src/loaders/babelLoader/__tests__/__snapshots__/babelLoader.test.ts.snap new file mode 100644 index 000000000..bc9d7b6cd --- /dev/null +++ b/packages/repack/src/loaders/babelLoader/__tests__/__snapshots__/babelLoader.test.ts.snap @@ -0,0 +1,32 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`babelLoader excludePlugins by default transforms ESM modules to CJS (baseline) 1`] = ` +""use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _bar = _interopRequireDefault(require("bar")); +function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } +var _default = exports.default = _bar.default;" +`; + +exports[`babelLoader excludePlugins excludes transform-modules-commonjs so ESM stays intact 1`] = ` +"import foo from "bar"; +export default foo;" +`; + +exports[`babelLoader includePlugins includes @babel/plugin-transform-react-jsx and transforms JSX 1`] = ` +""use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Component = void 0; +var _jsxRuntime = require("react/jsx-runtime"); +const Component = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(View, { + test: 1 +}); +exports.Component = Component;" +`; diff --git a/packages/repack/src/loaders/babelLoader/__tests__/babelLoader.test.ts b/packages/repack/src/loaders/babelLoader/__tests__/babelLoader.test.ts new file mode 100644 index 000000000..5bc77a195 --- /dev/null +++ b/packages/repack/src/loaders/babelLoader/__tests__/babelLoader.test.ts @@ -0,0 +1,82 @@ +import { transform } from '../babelLoader.js'; + +jest.mock('../utils.js', () => { + const actual = jest.requireActual('../utils.js'); + const { parseSync } = require('@babel/core'); + return { + ...actual, + loadHermesParser: jest.fn(async () => ({ + parse: ( + src: string, + opts: { sourceType?: 'script' | 'module' | 'unambiguous' } + ) => + parseSync(src, { + sourceType: opts?.sourceType ?? 'unambiguous', + }), + })), + }; +}); + +describe('babelLoader', () => { + describe('includePlugins', () => { + it('includes @babel/plugin-transform-react-jsx and transforms JSX', async () => { + const src = 'export const Component = () => ;'; + + const result = await transform( + src, + { + caller: { name: 'jest-babel-loader-test' }, + filename: '/virtual/Component.tsx', + sourceMaps: false, + sourceFileName: '/virtual/Component.tsx', + sourceRoot: '/virtual', + envName: 'production', + }, + { + includePlugins: [ + [ + '@babel/plugin-transform-react-jsx', + { runtime: 'automatic', importSource: 'react' }, + ], + ], + } + ); + + expect(result.code).toMatchSnapshot(); + }); + }); + + describe('excludePlugins', () => { + const esmSrc = 'import foo from "bar"; export default foo;'; + + it('by default transforms ESM modules to CJS (baseline)', async () => { + const result = await transform(esmSrc, { + caller: { name: 'jest-babel-loader-test' }, + filename: '/virtual/esm.ts', + sourceMaps: false, + sourceFileName: '/virtual/esm.ts', + sourceRoot: '/virtual', + envName: 'production', + }); + + expect(result.code).toMatchSnapshot(); + }); + + it('excludes transform-modules-commonjs so ESM stays intact', async () => { + const result = await transform( + esmSrc, + { + caller: { name: 'jest-babel-loader-test' }, + filename: '/virtual/esm.ts', + sourceMaps: false, + sourceFileName: '/virtual/esm.ts', + sourceRoot: '/virtual', + envName: 'production', + }, + { excludePlugins: ['transform-modules-commonjs'] } + ); + + expect(result.code).toMatchSnapshot(); + }); + }); +}); diff --git a/packages/repack/src/loaders/babelLoader/babelLoader.ts b/packages/repack/src/loaders/babelLoader/babelLoader.ts new file mode 100644 index 000000000..d031342d3 --- /dev/null +++ b/packages/repack/src/loaders/babelLoader/babelLoader.ts @@ -0,0 +1,144 @@ +import { + type TransformOptions, + loadOptions, + parseSync, + transformFromAstSync, +} from '@babel/core'; +import type { LoaderContext } from '@rspack/core'; +import type { + BabelLoaderOptions, + BabelPluginOverrides, + CustomTransformOptions, +} from './options.js'; +import { + isIgnoredRepackDeepImport, + isTSXSource, + isTypeScriptSource, + loadHermesParser, +} from './utils.js'; + +export const raw = false; + +function buildBabelConfig( + babelOptions: TransformOptions, + { includePlugins, excludePlugins }: BabelPluginOverrides +): TransformOptions { + const config: TransformOptions = { + babelrc: true, + highlightCode: true, + comments: true, + plugins: [], + sourceType: 'unambiguous', + ...babelOptions, + // output settings + ast: false, + code: true, + cloneInputAst: false, + // disable optimization through babel + compact: false, + minified: false, + }; + + if (includePlugins) { + config.plugins!.push(...includePlugins); + } + + const babelConfig = loadOptions(config); + if (!babelConfig) { + throw new Error('Failed to load babel config'); + } + + if (excludePlugins && babelConfig.plugins) { + const excludedPlugins = new Set(excludePlugins); + babelConfig.plugins = babelConfig.plugins.filter( + (plugin: { key: string }) => + !( + excludedPlugins.has(plugin.key) || + (plugin.key === 'warn-on-deep-imports' && + isIgnoredRepackDeepImport(babelOptions.filename!)) + ) + ); + } + + return babelConfig; +} + +export const transform = async ( + src: string, + transformOptions: TransformOptions, + customOptions?: CustomTransformOptions +) => { + const babelConfig = buildBabelConfig(transformOptions, { + includePlugins: customOptions?.includePlugins, + excludePlugins: customOptions?.excludePlugins, + }); + const projectRoot = babelConfig.root ?? babelConfig.cwd; + // load hermes parser dynamically to match the version from preset + const hermesParser = await loadHermesParser( + projectRoot, + customOptions?.hermesParserPath + ); + + // filename will be always defined at this point + const sourceAst = + isTypeScriptSource(babelConfig.filename!) || + isTSXSource(babelConfig.filename!) + ? parseSync(src, babelConfig) + : hermesParser.parse(src, { + babel: true, + reactRuntimeTarget: '19', + sourceType: babelConfig.sourceType, + ...customOptions?.hermesParserOverrides, + }); + + if (!sourceAst) { + throw new Error(`Failed to parse source file: ${babelConfig.filename}`); + } + + const result = transformFromAstSync(sourceAst, src, babelConfig); + if (!result) { + throw new Error(`Failed to transform source file: ${babelConfig.filename}`); + } + + return result; +}; + +export default async function babelLoader( + this: LoaderContext, + source: string, + sourceMap: string | undefined +) { + this.cacheable(); + const callback = this.async(); + const options = this.getOptions(); + + const { hermesParserPath, hermesParserOverrides, ...babelOverrides } = + options; + + const inputSourceMap = sourceMap ? JSON.parse(sourceMap) : undefined; + const withSourceMaps = this.resourcePath.match(/node_modules/) + ? false + : this.sourceMap; + + try { + const result = await transform( + source, + { + caller: { name: '@callstack/repack/babel-loader' }, + filename: this.resourcePath, + sourceMaps: withSourceMaps, + sourceFileName: this.resourcePath, + sourceRoot: this.context, + inputSourceMap: withSourceMaps ? inputSourceMap : undefined, + ...babelOverrides, + }, + { + hermesParserPath, + hermesParserOverrides, + } + ); + callback(null, result.code ?? undefined, result.map ?? undefined); + } catch (e) { + callback(e as Error); + } +} diff --git a/packages/repack/src/loaders/babelLoader/index.ts b/packages/repack/src/loaders/babelLoader/index.ts new file mode 100644 index 000000000..8fd14636d --- /dev/null +++ b/packages/repack/src/loaders/babelLoader/index.ts @@ -0,0 +1,4 @@ +import babelLoader, { raw } from './babelLoader.js'; + +export { raw }; +export default babelLoader; diff --git a/packages/repack/src/loaders/babelLoader/options.ts b/packages/repack/src/loaders/babelLoader/options.ts new file mode 100644 index 000000000..af5d24299 --- /dev/null +++ b/packages/repack/src/loaders/babelLoader/options.ts @@ -0,0 +1,22 @@ +import type { TransformOptions } from '@babel/core'; + +export interface HermesParserOverrides { + babel?: boolean; + flow?: 'all' | 'detect'; + reactRuntimeTarget?: '18' | '19'; + sourceType?: 'module' | 'script' | 'unambiguous'; +} + +export interface HermesParserOptions { + hermesParserPath?: string; + hermesParserOverrides?: HermesParserOverrides; +} + +export interface BabelPluginOverrides { + includePlugins?: Array]>; + excludePlugins?: string[]; +} + +export type BabelLoaderOptions = TransformOptions & HermesParserOptions; + +export type CustomTransformOptions = HermesParserOptions & BabelPluginOverrides; diff --git a/packages/repack/src/loaders/babelLoader/utils.ts b/packages/repack/src/loaders/babelLoader/utils.ts new file mode 100644 index 000000000..5b448d3cd --- /dev/null +++ b/packages/repack/src/loaders/babelLoader/utils.ts @@ -0,0 +1,70 @@ +import type { ParseResult } from '@babel/core'; + +interface HermesParser { + parse: ( + src: string, + opts: { + babel: boolean; + flow?: 'all' | 'detect'; + reactRuntimeTarget: string; + sourceType: 'script' | 'module' | 'unambiguous' | null | undefined; + } + ) => ParseResult; +} + +export function isTypeScriptSource(fileName: string) { + return !!fileName && fileName.endsWith('.ts'); +} + +export function isTSXSource(fileName: string) { + return !!fileName && fileName.endsWith('.tsx'); +} + +function resolveHermesParser(projectRoot: string) { + const reactNativeBabelPresetPath = require.resolve( + '@react-native/babel-preset', + { paths: [projectRoot] } + ); + + const babelPluginSyntaxHermesParserPath = require.resolve( + 'babel-plugin-syntax-hermes-parser', + { paths: [reactNativeBabelPresetPath] } + ); + + const hermesParserPath = require.resolve('hermes-parser', { + paths: [babelPluginSyntaxHermesParserPath], + }); + + return hermesParserPath; +} + +export async function loadHermesParser( + projectRoot?: string | null, + providedHermesParserPath?: string +): Promise { + try { + const hermesParserPath = + providedHermesParserPath ?? + resolveHermesParser(projectRoot ?? process.cwd()); + const hermesParser = await import(hermesParserPath); + return hermesParser; + } catch (e) { + console.error(e); + throw new Error( + `Failed to import 'hermes-parser'. Make sure you have '@react-native/babel-preset' installed in your project.` + ); + } +} + +const IGNORED_REPACK_FILENAMES = [ + 'IncludeModules.js', + 'WebpackHMRClient.js', +].map((name) => name.replace(/\./g, '\\.')); + +const IGNORED_REPACK_PATHS_REGEX = new RegExp( + `repack/dist/modules/(${IGNORED_REPACK_FILENAMES.join('|')})$` +); + +export function isIgnoredRepackDeepImport(filename: string): boolean { + return IGNORED_REPACK_PATHS_REGEX.test(filename); +} diff --git a/packages/repack/src/loaders/babelSwcLoader/__tests__/__snapshots__/babelSwcLoader.test.ts.snap b/packages/repack/src/loaders/babelSwcLoader/__tests__/__snapshots__/babelSwcLoader.test.ts.snap new file mode 100644 index 000000000..1d912f68e --- /dev/null +++ b/packages/repack/src/loaders/babelSwcLoader/__tests__/__snapshots__/babelSwcLoader.test.ts.snap @@ -0,0 +1,75 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`partitionTransforms ignores unsupported and disabled transforms (snapshot): unsupported and disabled 1`] = ` +{ + "includedSwcTransforms": [], + "supportedSwcTransforms": [], + "swcConfig": { + "jsc": { + "parser": { + "jsx": true, + "syntax": "ecmascript", + }, + "transform": { + "react": { + "useBuiltins": true, + }, + }, + }, + }, +} +`; + +exports[`partitionTransforms only custom transforms are excluded from included set but present in supported set (snapshot): custom-only supported set 1`] = ` +{ + "includedSwcTransforms": [], + "supportedSwcTransforms": [ + "transform-react-jsx", + "transform-modules-commonjs", + "proposal-export-default-from", + ], + "swcConfig": { + "jsc": { + "parser": { + "exportDefaultFrom": true, + "jsx": true, + "syntax": "ecmascript", + }, + "transform": { + "react": { + "importSource": undefined, + "runtime": undefined, + "useBuiltins": true, + }, + }, + }, + "module": { + "allowTopLevelThis": false, + "ignoreDynamic": true, + "strict": false, + "strictMode": false, + "type": "commonjs", + }, + }, +} +`; + +exports[`partitionTransforms returns empty arrays when no transforms are specified (snapshot): empty arrays 1`] = ` +{ + "includedSwcTransforms": [], + "supportedSwcTransforms": [], + "swcConfig": { + "jsc": { + "parser": { + "syntax": "typescript", + "tsx": false, + }, + "transform": { + "react": { + "useBuiltins": true, + }, + }, + }, + }, +} +`; diff --git a/packages/repack/src/loaders/babelSwcLoader/__tests__/__snapshots__/swc.test.ts.snap b/packages/repack/src/loaders/babelSwcLoader/__tests__/__snapshots__/swc.test.ts.snap new file mode 100644 index 000000000..f8a54912a --- /dev/null +++ b/packages/repack/src/loaders/babelSwcLoader/__tests__/__snapshots__/swc.test.ts.snap @@ -0,0 +1,68 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`swc transforms support detection getSupportedSwcConfigurableTransforms applies loose mode to setSpreadProperties when not defined; preserves explicit true (snapshot): object-rest-spread explicit true preserved 1`] = ` +{ + "setSpreadProperties": true, +} +`; + +exports[`swc transforms support detection getSupportedSwcConfigurableTransforms applies loose mode to setSpreadProperties when not defined; preserves explicit true (snapshot): object-rest-spread loose: setSpreadProperties 1`] = ` +{ + "setSpreadProperties": true, +} +`; + +exports[`swc transforms support detection getSupportedSwcConfigurableTransforms sets optional-chaining/nullish and for-of assumptions with loose mode and respects explicit values (snapshot): optional-chaining/nullish and for-of assumptions 1`] = ` +{ + "noDocumentAll": true, + "skipForOfIteratorClosing": true, +} +`; + +exports[`swc transforms support detection getSupportedSwcConfigurableTransforms updates both privateFieldsAsProperties and setPublicClassFields for private-property-in-object but does not override explicit true (snapshot): private-property-in-object assumptions and names 1`] = ` +{ + "assumptions": { + "privateFieldsAsProperties": true, + "setPublicClassFields": true, + }, + "transformNames": [ + "transform-private-property-in-object", + ], +} +`; + +exports[`swc transforms support detection getSupportedSwcCustomTransforms configures modules commonjs options based on provided config (snapshot): modules commonjs config 1`] = ` +{ + "allowTopLevelThis": false, + "ignoreDynamic": true, + "strict": false, + "strictMode": true, + "type": "commonjs", +} +`; + +exports[`swc transforms support detection getSupportedSwcCustomTransforms enables external helpers via transform-runtime (snapshot): runtime externalHelpers 1`] = ` +{ + "externalHelpers": true, +} +`; + +exports[`swc transforms support detection getSupportedSwcCustomTransforms overrides react runtime and importSource from transform-react-jsx config (snapshot): react runtime override 1`] = ` +{ + "importSource": "react/jsx", + "runtime": "automatic", +} +`; + +exports[`swc transforms support detection getSupportedSwcCustomTransforms sets exportDefaultFrom only for ecmascript parser; leaves typescript parser unchanged (snapshot): parser: ecmascript with exportDefaultFrom 1`] = ` +{ + "exportDefaultFrom": true, + "syntax": "ecmascript", +} +`; + +exports[`swc transforms support detection getSupportedSwcCustomTransforms sets exportDefaultFrom only for ecmascript parser; leaves typescript parser unchanged (snapshot): parser: typescript unchanged 1`] = ` +{ + "syntax": "typescript", +} +`; diff --git a/packages/repack/src/loaders/babelSwcLoader/__tests__/babelSwcLoader.test.ts b/packages/repack/src/loaders/babelSwcLoader/__tests__/babelSwcLoader.test.ts new file mode 100644 index 000000000..1ad931261 --- /dev/null +++ b/packages/repack/src/loaders/babelSwcLoader/__tests__/babelSwcLoader.test.ts @@ -0,0 +1,68 @@ +import { partitionTransforms } from '../babelSwcLoader.js'; + +type TransformEntry = [string, Record | undefined]; + +describe('partitionTransforms', () => { + it('partitions normal, configurable, and custom transforms preserving order', () => { + const transforms: TransformEntry[] = [ + ['transform-block-scoping', {}], + ['transform-react-jsx', {}], + ['transform-object-rest-spread', { loose: true }], + ['transform-class-properties', { loose: true }], // disabled configurable + ['transform-private-methods', { loose: true }], // disabled configurable + ['unknown-plugin', {}], + ['transform-modules-commonjs', {}], + ['transform-classes', {}], + ['transform-for-of', {}], + ]; + + const { includedSwcTransforms, supportedSwcTransforms } = + partitionTransforms('/virtual/file.tsx', transforms); + + expect(includedSwcTransforms).toEqual([ + 'transform-block-scoping', + 'transform-classes', + 'transform-object-rest-spread', + 'transform-for-of', + ]); + + expect(supportedSwcTransforms).toEqual([ + 'transform-block-scoping', + 'transform-classes', + 'transform-object-rest-spread', + 'transform-for-of', + 'transform-react-jsx', + 'transform-modules-commonjs', + ]); + }); + + it('ignores unsupported and disabled transforms (snapshot)', () => { + const transforms: TransformEntry[] = [ + ['transform-class-properties', { loose: true }], // disabled + ['transform-private-methods', { loose: true }], // disabled + ['unknown-plugin', {}], + ]; + + const result = partitionTransforms('/virtual/file.js', transforms); + + expect(result).toMatchSnapshot('unsupported and disabled'); + }); + + it('only custom transforms are excluded from included set but present in supported set (snapshot)', () => { + const transforms: TransformEntry[] = [ + ['transform-react-jsx', {}], + ['transform-modules-commonjs', {}], + ['proposal-export-default-from', {}], + ]; + + const result = partitionTransforms('/virtual/file.jsx', transforms); + + expect(result).toMatchSnapshot('custom-only supported set'); + }); + + it('returns empty arrays when no transforms are specified (snapshot)', () => { + const result = partitionTransforms('/virtual/empty.ts', []); + + expect(result).toMatchSnapshot('empty arrays'); + }); +}); diff --git a/packages/repack/src/loaders/babelSwcLoader/__tests__/swc.test.ts b/packages/repack/src/loaders/babelSwcLoader/__tests__/swc.test.ts new file mode 100644 index 000000000..066ff7406 --- /dev/null +++ b/packages/repack/src/loaders/babelSwcLoader/__tests__/swc.test.ts @@ -0,0 +1,224 @@ +import type { SwcLoaderOptions } from '@rspack/core'; +import { + getSupportedSwcConfigurableTransforms, + getSupportedSwcCustomTransforms, + getSupportedSwcNormalTransforms, +} from '../swc.js'; + +type TransformEntry = [string, Record | undefined]; + +describe('swc transforms support detection', () => { + describe('getSupportedSwcNormalTransforms', () => { + it('returns only supported normal transform names preserving order', () => { + const transforms: TransformEntry[] = [ + ['transform-block-scoping', undefined], + ['transform-classes', {}], + ['transform-react-jsx', undefined], // custom + ['transform-private-methods', undefined], // configurable (disabled) + ['unknown-plugin', undefined], + ['transform-object-rest-spread', undefined], // configurable + ]; + + const result = getSupportedSwcNormalTransforms(transforms); + + expect(result).toEqual(['transform-block-scoping', 'transform-classes']); + }); + }); + + describe('getSupportedSwcConfigurableTransforms', () => { + it('returns only supported configurable transform names preserving order', () => { + const baseSwcConfig = {}; + const transforms: TransformEntry[] = [ + ['transform-class-properties', { loose: true }], // disabled + ['transform-private-methods', { loose: true }], // disabled + ['transform-private-property-in-object', {}], + ['transform-object-rest-spread', {}], + ['transform-optional-chaining', {}], + ['transform-nullish-coalescing-operator', {}], + ['transform-for-of', {}], + ['transform-runtime', {}], // custom + ['transform-block-scoping', {}], // normal + ['unknown-plugin', {}], + ]; + + const { transformNames } = getSupportedSwcConfigurableTransforms( + transforms, + baseSwcConfig as SwcLoaderOptions + ); + + expect(transformNames).toEqual([ + 'transform-private-property-in-object', + 'transform-object-rest-spread', + 'transform-optional-chaining', + 'transform-nullish-coalescing-operator', + 'transform-for-of', + ]); + }); + + it('applies loose mode to setSpreadProperties when not defined; preserves explicit true (snapshot)', () => { + const baseUndefined = {} as SwcLoaderOptions; + const { swcConfig: cfg1 } = getSupportedSwcConfigurableTransforms( + [['transform-object-rest-spread', { loose: true }]], + baseUndefined + ); + + expect(cfg1.jsc?.assumptions).toMatchSnapshot( + 'object-rest-spread loose: setSpreadProperties' + ); + + const baseTrue: SwcLoaderOptions = { + jsc: { assumptions: { setSpreadProperties: true } }, + } as SwcLoaderOptions; + const { swcConfig: cfg2 } = getSupportedSwcConfigurableTransforms( + [['transform-object-rest-spread', { loose: false }]], + baseTrue + ); + + expect(cfg2.jsc?.assumptions).toMatchSnapshot( + 'object-rest-spread explicit true preserved' + ); + }); + + it('sets optional-chaining/nullish and for-of assumptions with loose mode and respects explicit values (snapshot)', () => { + const base: SwcLoaderOptions = { + jsc: { assumptions: { noDocumentAll: true } }, + } as SwcLoaderOptions; + + const { swcConfig } = getSupportedSwcConfigurableTransforms( + [ + ['transform-optional-chaining', { loose: false }], + ['transform-nullish-coalescing-operator', { loose: true }], + ['transform-for-of', { loose: true }], + ], + base + ); + + expect(swcConfig.jsc?.assumptions).toMatchSnapshot( + 'optional-chaining/nullish and for-of assumptions' + ); + }); + + it('updates both privateFieldsAsProperties and setPublicClassFields for private-property-in-object but does not override explicit true (snapshot)', () => { + const base: SwcLoaderOptions = { + jsc: { + assumptions: { + privateFieldsAsProperties: true, + setPublicClassFields: true, + }, + }, + } as SwcLoaderOptions; + + const { swcConfig, transformNames } = + getSupportedSwcConfigurableTransforms( + [['transform-private-property-in-object', { loose: false }]], + base + ); + + expect({ + transformNames, + assumptions: swcConfig.jsc?.assumptions, + }).toMatchSnapshot('private-property-in-object assumptions and names'); + }); + }); + + describe('getSupportedSwcCustomTransforms', () => { + it('returns only supported custom transform names preserving order', () => { + const baseSwcConfig = {}; + const transforms: TransformEntry[] = [ + ['transform-runtime', {}], + [ + 'transform-react-jsx', + { runtime: 'automatic', importSource: 'react' }, + ], + ['transform-react-jsx-self', {}], + ['transform-react-jsx-source', {}], + ['transform-modules-commonjs', {}], + ['proposal-export-default-from', {}], + ['transform-block-scoping', {}], // normal + ['transform-private-methods', {}], // configurable (disabled) + ['unknown-plugin', {}], + ]; + + const { transformNames } = getSupportedSwcCustomTransforms( + transforms, + baseSwcConfig as SwcLoaderOptions + ); + + expect(transformNames).toEqual([ + 'transform-runtime', + 'transform-react-jsx', + 'transform-react-jsx-self', + 'transform-react-jsx-source', + 'transform-modules-commonjs', + 'proposal-export-default-from', + ]); + }); + + it('overrides react runtime and importSource from transform-react-jsx config (snapshot)', () => { + const inputConfig: SwcLoaderOptions = { + jsc: { + transform: { react: { runtime: 'classic', importSource: 'preact' } }, + }, + }; + const { swcConfig } = getSupportedSwcCustomTransforms( + [ + [ + 'transform-react-jsx', + { runtime: 'automatic', importSource: 'react/jsx' }, + ], + ], + inputConfig + ); + + expect(swcConfig.jsc?.transform?.react).toMatchSnapshot( + 'react runtime override' + ); + }); + + it('configures modules commonjs options based on provided config (snapshot)', () => { + const inputConfig: SwcLoaderOptions = {}; + const { swcConfig } = getSupportedSwcCustomTransforms( + [ + [ + 'transform-modules-commonjs', + { strict: false, strictMode: true, allowTopLevelThis: false }, + ], + ], + inputConfig + ); + expect(swcConfig.module).toMatchSnapshot('modules commonjs config'); + }); + + it('enables external helpers via transform-runtime (snapshot)', () => { + const inputConfig: SwcLoaderOptions = {}; + const { swcConfig } = getSupportedSwcCustomTransforms( + [['transform-runtime', {}]], + inputConfig + ); + expect(swcConfig.jsc).toMatchSnapshot('runtime externalHelpers'); + }); + + it('sets exportDefaultFrom only for ecmascript parser; leaves typescript parser unchanged (snapshot)', () => { + const inputConfigTs: SwcLoaderOptions = { + jsc: { parser: { syntax: 'typescript' } }, + } as SwcLoaderOptions; + + const { swcConfig: tsCfg } = getSupportedSwcCustomTransforms( + [['proposal-export-default-from', {}]], + inputConfigTs + ); + expect(tsCfg.jsc?.parser).toMatchSnapshot('parser: typescript unchanged'); + + const inputConfigEcma: SwcLoaderOptions = { + jsc: { parser: { syntax: 'ecmascript' } }, + } as SwcLoaderOptions; + const { swcConfig: ecmaCfg } = getSupportedSwcCustomTransforms( + [['proposal-export-default-from', {}]], + inputConfigEcma + ); + expect(ecmaCfg.jsc?.parser).toMatchSnapshot( + 'parser: ecmascript with exportDefaultFrom' + ); + }); + }); +}); diff --git a/packages/repack/src/loaders/babelSwcLoader/babelSwcLoader.ts b/packages/repack/src/loaders/babelSwcLoader/babelSwcLoader.ts new file mode 100644 index 000000000..1d4680c10 --- /dev/null +++ b/packages/repack/src/loaders/babelSwcLoader/babelSwcLoader.ts @@ -0,0 +1,160 @@ +import type { TransformOptions } from '@babel/core'; +import type { LoaderContext, SwcLoaderOptions } from '@rspack/core'; +import { transform } from '../babelLoader/babelLoader.js'; +import type { BabelSwcLoaderOptions } from './options.js'; +import { + getSupportedSwcConfigurableTransforms, + getSupportedSwcCustomTransforms, + getSupportedSwcNormalTransforms, +} from './swc.js'; +import { + checkParallelModeAvailable, + getExtraBabelPlugins, + getProjectBabelConfig, + getProjectRootPath, + getSwcParserConfig, + lazyGetSwc, +} from './utils.js'; + +type BabelTransform = [string, Record | undefined]; +type InputSourceMap = TransformOptions['inputSourceMap']; + +export const raw = false; + +export function partitionTransforms( + filename: string, + babelTransforms: BabelTransform[] +) { + let normalTransforms: string[] = []; + let configurableTransforms: string[] = []; + let customTransforms: string[] = []; + + let swcConfig: SwcLoaderOptions = { + jsc: { + parser: getSwcParserConfig(filename), + transform: { react: { useBuiltins: true } }, + }, + }; + + normalTransforms = getSupportedSwcNormalTransforms(babelTransforms); + ({ swcConfig, transformNames: configurableTransforms } = + getSupportedSwcConfigurableTransforms(babelTransforms, swcConfig)); + ({ swcConfig, transformNames: customTransforms } = + getSupportedSwcCustomTransforms(babelTransforms, swcConfig)); + + const includedSwcTransforms: string[] = [ + ...normalTransforms, + ...configurableTransforms, + ]; + + const supportedSwcTransforms: string[] = [ + ...includedSwcTransforms, + ...customTransforms, + ]; + + return { includedSwcTransforms, supportedSwcTransforms, swcConfig }; +} + +export default async function babelSwcLoader( + this: LoaderContext, + source: string, + sourceMap: string | undefined +) { + this.cacheable(); + const callback = this.async(); + const loaderName = '@callstack/repack/babel-swc-loader'; + const logger = this.getLogger('BabelSwcLoader'); + const options = this.getOptions(); + + if (!options.hideParallelModeWarning) { + checkParallelModeAvailable(this, logger); + } + + const inputSourceMap: InputSourceMap = sourceMap + ? JSON.parse(sourceMap) + : undefined; + const lazyImports = options.lazyImports ?? true; + const projectRoot = getProjectRootPath(this); + + const withSourceMaps = this.resourcePath.match(/node_modules/) + ? false + : this.sourceMap; + + const baseBabelConfig: TransformOptions = { + caller: { name: loaderName }, + root: projectRoot, + filename: this.resourcePath, + sourceMaps: withSourceMaps, + sourceFileName: this.resourcePath, + sourceRoot: this.context, + inputSourceMap: withSourceMaps ? inputSourceMap : undefined, + ...options.babelOverrides, + }; + + try { + const swc = await lazyGetSwc(this); + // if swc is not available, use babel to transform everything + if (!swc) { + const { code, map } = await transform(source, baseBabelConfig, { + hermesParserPath: options.hermesParserPath, + hermesParserOverrides: options.hermesParserOverrides, + }); + callback(null, code ?? undefined, map ?? undefined); + return; + } + + const babelConfig = getProjectBabelConfig(this.resourcePath, projectRoot); + const detectedBabelTransforms = + babelConfig.plugins?.map((p) => [p.key, p.options] as BabelTransform) ?? + []; + + const includeBabelPlugins = getExtraBabelPlugins(this.resourcePath); + const { includedSwcTransforms, supportedSwcTransforms, swcConfig } = + partitionTransforms(this.resourcePath, detectedBabelTransforms); + + const babelResult = await transform(source, baseBabelConfig, { + excludePlugins: supportedSwcTransforms, + includePlugins: includeBabelPlugins, + hermesParserPath: options.hermesParserPath, + hermesParserOverrides: options.hermesParserOverrides, + }); + + const finalSwcConfig: SwcLoaderOptions = { + ...swcConfig, + // set env based on babel transforms + env: { + // node supports everything and does not include + // any transforms by default, so it can as a template + targets: { node: 24 }, + include: includedSwcTransforms, + }, + // set lazy imports based on loader options + module: { + ...swcConfig.module, + lazy: lazyImports, + type: swcConfig.module!.type, + }, + }; + + const swcResult = swc.transformSync(babelResult?.code!, { + ...finalSwcConfig, + caller: { name: loaderName }, + filename: this.resourcePath, + configFile: false, + swcrc: false, + root: projectRoot ?? babelConfig.root ?? undefined, + minify: false, + sourceMaps: withSourceMaps, + inputSourceMap: withSourceMaps + ? JSON.stringify(babelResult?.map) + : undefined, + sourceFileName: this.resourcePath, + sourceRoot: this.context!, + ...options.swcOverrides, + }); + + callback(null, swcResult?.code, swcResult?.map); + } catch (error) { + callback(error as Error); + } +} diff --git a/packages/repack/src/loaders/babelSwcLoader/index.ts b/packages/repack/src/loaders/babelSwcLoader/index.ts new file mode 100644 index 000000000..229c76518 --- /dev/null +++ b/packages/repack/src/loaders/babelSwcLoader/index.ts @@ -0,0 +1,4 @@ +import babelSwcLoader, { raw } from './babelSwcLoader.js'; + +export { raw }; +export default babelSwcLoader; diff --git a/packages/repack/src/loaders/babelSwcLoader/options.ts b/packages/repack/src/loaders/babelSwcLoader/options.ts new file mode 100644 index 000000000..674cf51a8 --- /dev/null +++ b/packages/repack/src/loaders/babelSwcLoader/options.ts @@ -0,0 +1,13 @@ +import type { TransformOptions } from '@babel/core'; +import type { SwcLoaderOptions } from '@rspack/core'; +import type { HermesParserOptions } from '../babelLoader/options.js'; + +type BabelOverrides = TransformOptions; +type SwcOverrides = Omit; + +export type BabelSwcLoaderOptions = { + hideParallelModeWarning?: boolean; + lazyImports?: boolean | string[]; + babelOverrides?: BabelOverrides; + swcOverrides?: SwcOverrides; +} & HermesParserOptions; diff --git a/packages/repack/src/loaders/babelSwcLoader/swc.ts b/packages/repack/src/loaders/babelSwcLoader/swc.ts new file mode 100644 index 000000000..353449d83 --- /dev/null +++ b/packages/repack/src/loaders/babelSwcLoader/swc.ts @@ -0,0 +1,293 @@ +import type { SwcLoaderOptions } from '@rspack/core'; + +const SWC_SUPPORTED_NORMAL_RULES = new Set([ + 'transform-block-scoping', + 'transform-classes', + 'transform-class-static-block', + 'transform-destructuring', + 'transform-async-to-generator', + 'transform-async-generator-functions', + 'transform-unicode-regex', + 'transform-named-capturing-groups-regex', + 'transform-spread', + 'transform-parameters', + 'transform-function-name', + 'transform-logical-assignment-operators', + 'transform-sticky-regex', + 'transform-literals', + 'transform-optional-catch-binding', + 'transform-arrow-functions', + 'transform-numeric-separator', + 'transform-shorthand-properties', + 'transform-computed-properties', +]); + +// NOTE: 'transform-class-properties' and 'transform-private-methods' are disabled here +// because, when combined with loose mode, these cause an internal swc error. Needs fixing upstream +const SWC_SUPPORTED_CONFIGURABLE_RULES = new Set([ + // 'transform-class-properties', + // 'transform-private-methods', + 'transform-private-property-in-object', + 'transform-object-rest-spread', + 'transform-optional-chaining', + 'transform-nullish-coalescing-operator', + 'transform-for-of', +]); + +const SWC_SUPPORTED_CUSTOM_RULES = new Set([ + 'transform-runtime', + 'transform-react-jsx-self', + 'transform-react-jsx-source', + 'transform-react-jsx', + 'transform-modules-commonjs', + 'proposal-export-default-from', +]); + +function getTransformRuntimeConfig( + swcConfig: SwcLoaderOptions +): SwcLoaderOptions { + return { + ...swcConfig, + jsc: { + ...swcConfig.jsc, + externalHelpers: true, + }, + }; +} + +function getTransformReactDevelopmentConfig( + swcConfig: SwcLoaderOptions +): SwcLoaderOptions { + return { + ...swcConfig, + jsc: { + ...swcConfig.jsc, + transform: { + ...swcConfig.jsc?.transform, + react: { + ...swcConfig.jsc?.transform?.react, + development: true, + }, + }, + }, + }; +} + +function getTransformReactRuntimeConfig( + swcConfig: SwcLoaderOptions, + reactRuntimeConfig: Record = { + runtime: 'automatic', + } +): SwcLoaderOptions { + return { + ...swcConfig, + jsc: { + ...swcConfig.jsc, + transform: { + ...swcConfig.jsc?.transform, + react: { + ...swcConfig.jsc?.transform?.react, + runtime: reactRuntimeConfig.runtime, + importSource: reactRuntimeConfig.importSource, + }, + }, + }, + }; +} + +function getTransformModulesCommonjsConfig( + swcConfig: SwcLoaderOptions, + moduleConfig: Record = { + strict: true, + strictMode: true, + allowTopLevelThis: true, + } +): SwcLoaderOptions { + return { + ...swcConfig, + module: { + ...swcConfig.module, + type: 'commonjs', + strict: Boolean(moduleConfig.strict), + strictMode: Boolean(moduleConfig.strictMode), + allowTopLevelThis: Boolean(moduleConfig.allowTopLevelThis), + ignoreDynamic: true, + }, + }; +} + +function getTransformExportDefaultFromConfig( + swcConfig: SwcLoaderOptions +): SwcLoaderOptions { + if (swcConfig.jsc?.parser?.syntax === 'typescript') { + return swcConfig; + } + return { + ...swcConfig, + jsc: { + ...swcConfig.jsc, + parser: { + ...swcConfig.jsc?.parser, + syntax: 'ecmascript', + exportDefaultFrom: true, + }, + }, + }; +} + +function getTransformClassPropertiesConfig( + swcConfig: SwcLoaderOptions, + ruleConfig: Record = { loose: false } +): SwcLoaderOptions { + return { + ...swcConfig, + jsc: { + ...swcConfig.jsc, + assumptions: { + ...swcConfig.jsc?.assumptions, + setPublicClassFields: + swcConfig.jsc?.assumptions?.setPublicClassFields || ruleConfig.loose, + }, + }, + }; +} + +function getTransformPrivateMethodsPropertyConfig( + swcConfig: SwcLoaderOptions, + ruleConfig: Record = { loose: false } +): SwcLoaderOptions { + return { + ...swcConfig, + jsc: { + ...swcConfig.jsc, + assumptions: { + ...swcConfig.jsc?.assumptions, + privateFieldsAsProperties: + swcConfig.jsc?.assumptions?.privateFieldsAsProperties || + ruleConfig.loose, + setPublicClassFields: + swcConfig.jsc?.assumptions?.setPublicClassFields || ruleConfig.loose, + }, + }, + }; +} + +function getTransformObjectRestSpreadConfig( + swcConfig: SwcLoaderOptions, + ruleConfig: Record = { loose: false } +): SwcLoaderOptions { + return { + ...swcConfig, + jsc: { + ...swcConfig.jsc, + assumptions: { + ...swcConfig.jsc?.assumptions, + setSpreadProperties: + swcConfig.jsc?.assumptions?.setSpreadProperties || ruleConfig.loose, + }, + }, + }; +} + +function getTransformOptionalChainingNullishCoalescingConfig( + swcConfig: SwcLoaderOptions, + ruleConfig: Record = { loose: false } +): SwcLoaderOptions { + return { + ...swcConfig, + jsc: { + ...swcConfig.jsc, + assumptions: { + ...swcConfig.jsc?.assumptions, + noDocumentAll: + swcConfig.jsc?.assumptions?.noDocumentAll || ruleConfig.loose, + }, + }, + }; +} + +function getTransformForOfConfig( + swcConfig: SwcLoaderOptions, + ruleConfig: Record = { loose: false } +): SwcLoaderOptions { + return { + ...swcConfig, + jsc: { + ...swcConfig.jsc, + assumptions: { + ...swcConfig.jsc?.assumptions, + skipForOfIteratorClosing: + swcConfig.jsc?.assumptions?.skipForOfIteratorClosing || + ruleConfig.loose, + }, + }, + }; +} + +const SWC_SUPPORTED_CONFIGURABLE_RULES_MAP = { + 'transform-class-properties': getTransformClassPropertiesConfig, + 'transform-private-methods': getTransformPrivateMethodsPropertyConfig, + 'transform-private-property-in-object': + getTransformPrivateMethodsPropertyConfig, + 'transform-object-rest-spread': getTransformObjectRestSpreadConfig, + 'transform-optional-chaining': + getTransformOptionalChainingNullishCoalescingConfig, + 'transform-nullish-coalescing-operator': + getTransformOptionalChainingNullishCoalescingConfig, + 'transform-for-of': getTransformForOfConfig, +}; + +const SWC_SUPPORTED_CUSTOM_RULES_MAP = { + 'transform-runtime': getTransformRuntimeConfig, + 'transform-react-jsx': getTransformReactRuntimeConfig, + 'transform-react-jsx-self': getTransformReactDevelopmentConfig, + 'transform-react-jsx-source': getTransformReactDevelopmentConfig, + 'transform-modules-commonjs': getTransformModulesCommonjsConfig, + 'proposal-export-default-from': getTransformExportDefaultFromConfig, +}; + +export function getSupportedSwcNormalTransforms( + transforms: [string, Record | undefined][] +) { + return transforms + .filter(([transform]) => SWC_SUPPORTED_NORMAL_RULES.has(transform)) + .map(([transform]) => transform); +} + +export function getSupportedSwcConfigurableTransforms( + transforms: [string, Record | undefined][], + swcConfig: SwcLoaderOptions +) { + const transformNames = transforms + .filter(([transform]) => SWC_SUPPORTED_CONFIGURABLE_RULES.has(transform)) + .map(([transform]) => transform); + const finalSwcConfig = transforms + .filter(([transform]) => SWC_SUPPORTED_CONFIGURABLE_RULES.has(transform)) + .reduce((config, [transform, transformConfig]) => { + const handler = + SWC_SUPPORTED_CONFIGURABLE_RULES_MAP[ + transform as keyof typeof SWC_SUPPORTED_CONFIGURABLE_RULES_MAP + ]; + return handler(config, transformConfig); + }, swcConfig); + return { swcConfig: finalSwcConfig, transformNames }; +} + +export function getSupportedSwcCustomTransforms( + transforms: [string, Record | undefined][], + swcConfig: SwcLoaderOptions +) { + const transformNames = transforms + .filter(([transform]) => SWC_SUPPORTED_CUSTOM_RULES.has(transform)) + .map(([transform]) => transform); + const finalSwcConfig = transforms + .filter(([transform]) => SWC_SUPPORTED_CUSTOM_RULES.has(transform)) + .reduce((config, [transform, transformConfig]) => { + const handler = + SWC_SUPPORTED_CUSTOM_RULES_MAP[ + transform as keyof typeof SWC_SUPPORTED_CUSTOM_RULES_MAP + ]; + return handler(config, transformConfig); + }, swcConfig); + return { swcConfig: finalSwcConfig, transformNames }; +} diff --git a/packages/repack/src/loaders/babelSwcLoader/utils.ts b/packages/repack/src/loaders/babelSwcLoader/utils.ts new file mode 100644 index 000000000..1ca3fadaf --- /dev/null +++ b/packages/repack/src/loaders/babelSwcLoader/utils.ts @@ -0,0 +1,174 @@ +import { loadOptions } from '@babel/core'; +import type { + LoaderContext, + SwcLoaderParserConfig, + experiments, +} from '@rspack/core'; + +type Swc = (typeof experiments)['swc']; +type Logger = ReturnType; + +export function isTypeScriptSource(fileName: string) { + return !!fileName && fileName.endsWith('.ts'); +} + +export function isTSXSource(fileName: string) { + return !!fileName && fileName.endsWith('.tsx'); +} + +export function getProjectBabelConfig(filename: string, projectRoot?: string) { + const babelConfig = loadOptions({ filename, root: projectRoot }); + return babelConfig ?? {}; +} + +export function getExtraBabelPlugins(filename: string) { + const extraBabelPlugins: Array]> = []; + // add TS syntax plugins since RN preset + // only uses transform-typescript plugin + // which includes the syntax-typescript plugin + if (isTypeScriptSource(filename)) { + extraBabelPlugins.push([ + '@babel/plugin-syntax-typescript', + { isTSX: false, allowNamespaces: true }, + ]); + } else if (isTSXSource(filename)) { + extraBabelPlugins.push([ + '@babel/plugin-syntax-typescript', + { isTSX: true, allowNamespaces: true }, + ]); + } + return extraBabelPlugins; +} + +export function getSwcParserConfig(filename: string): SwcLoaderParserConfig { + if (isTypeScriptSource(filename)) { + return { syntax: 'typescript', tsx: false }; + } + if (isTSXSource(filename)) { + return { syntax: 'typescript', tsx: true }; + } + // include JSX in .js files + return { syntax: 'ecmascript', jsx: true }; +} + +function isWebpackBackend(loaderContext: LoaderContext) { + // parallel loader in Rspack has mocked compiler object without most props + // but in non-parallel mode, full compiler object is available so we can do the proper check + // we distinguish between parallel and non-parallel mode by checking if the compiler has a version property + // and then proceed to check if it's a Rspack compiler the official way + if ( + 'webpack' in loaderContext._compiler && + 'version' in loaderContext._compiler.webpack && + loaderContext._compiler.webpack.version + ) { + return !('rspackVersion' in loaderContext._compiler.webpack); + } + // in threaded-loader mode, _compiler.webpack is undefined + // loaderContext.webpack exists in webpack but not in Rspack + // in case it's added in the future, it should be followed by similar rspack prop + if ('webpack' in loaderContext && loaderContext.webpack) { + return !('rspack' in loaderContext && loaderContext.rspack); + } + // if both checks fail, we assume it's a Rspack compiler + return false; +} + +const disabledParalleModeWarning = [ + 'You have enabled `experiments.parallelLoader` but forgot to enable it for this loader.', + 'To enable parallel mode for this loader you need to add `parallel: true` to the loader rule.', + 'See how to do it in the official Rspack docs:', + 'https://rspack.rs/config/experiments#experimentsparallelloader.', + 'If this is intentional, you can disable this warning', + 'by setting `hideParallelModeWarning` in the loader options.', +].join(' '); + +let parallelModeWarningDisplayed = false; + +export function checkParallelModeAvailable( + loaderContext: LoaderContext, + logger: Logger +) { + // only Rspack supports parallel mode + if (parallelModeWarningDisplayed || isWebpackBackend(loaderContext)) { + return; + } + // in parallel mode compiler.options.experiments are not available + // but since we're already running in parallel mode, we can ignore this check + if (loaderContext._compiler.options?.experiments?.parallelLoader) { + parallelModeWarningDisplayed = true; + logger.warn(disabledParalleModeWarning); + } +} + +export function getProjectRootPath( + loaderContext: LoaderContext +): string | undefined { + // parallel loaders in Rspack had a bug where rootContext + // was the same as context, so we check if they are different + if (loaderContext.rootContext !== loaderContext.context) { + return loaderContext.rootContext; + } + return undefined; +} + +function safelyResolve(path: string, from: string): string | null { + try { + return require.resolve(path, { paths: [from] }); + } catch { + return null; + } +} + +async function getSwcModule(loaderContext: LoaderContext): Promise { + const projectRoot = getProjectRootPath(loaderContext) ?? process.cwd(); + const isWebpack = isWebpackBackend(loaderContext); + if (!isWebpack) { + // happy path - rspack & exposed swc + // use optional chaining to avoid type errors when using parallel loader + if (loaderContext._compiler.rspack?.experiments?.swc) { + return loaderContext._compiler.rspack.experiments.swc; + } + // fallback to checking for `@rspack/core` installed in the project + // use optional chaining to avoid type errors when there is no experiments.swc + const rspackCorePath = safelyResolve('@rspack/core', projectRoot); + if (rspackCorePath && !isWebpack) { + const rspack = await import(rspackCorePath); + if ('default' in rspack) { + return rspack.default?.experiments?.swc ?? null; + } + if (rspack) { + return rspack?.experiments?.swc ?? null; + } + } + } + // fallback to checking for `@swc/core` installed in the project + // this can be in both webpack & rspack projects + const swcCorePath = safelyResolve('@swc/core', projectRoot); + if (swcCorePath) { + const swc = await import(swcCorePath); + if ('default' in swc) { + return swc.default as Swc; + } + if (swc) { + return swc as Swc; + } + } + // at this point, we've tried all possible ways to get swc and failed + return null; +} + +function createLazyGetSwc(): ( + loaderContext: LoaderContext +) => Promise { + let swc: Swc | Promise | null | undefined; + + const getSwc = async (loaderContext: LoaderContext) => { + if (swc === undefined) { + swc = getSwcModule(loaderContext); + } + return await swc; + }; + return getSwc; +} + +export const lazyGetSwc = createLazyGetSwc(); diff --git a/packages/repack/src/types/babel-core.d.ts b/packages/repack/src/types/babel-core.d.ts new file mode 100644 index 000000000..7d1b902f6 --- /dev/null +++ b/packages/repack/src/types/babel-core.d.ts @@ -0,0 +1,21 @@ +import type { TransformOptions } from '@babel/core'; + +declare module '@babel/core' { + interface BabelProjectConfig extends TransformOptions { + plugins?: { + key: string; + manipulateOptions: (() => void) | undefined; + post: (() => void) | undefined; + pre: (() => void) | undefined; + visitor: unknown; + parserOverride: unknown; + generatorOverride: undefined; + options?: Record; + externalDependencies: unknown[]; + }[]; + } + + export function loadOptions( + options: TransformOptions + ): BabelProjectConfig | null; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 81793486c..2cbaf851b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,8 +10,8 @@ catalogs: specifier: ^0.6.3 version: 0.6.3 '@rspack/core': - specifier: ^1.4.2 - version: 1.4.6 + specifier: ^1.4.11 + version: 1.4.11 '@swc/helpers': specifier: ~0.5.17 version: 0.5.17 @@ -101,7 +101,7 @@ importers: version: 1.0.0 nx: specifier: 19.7.3 - version: 19.7.3 + version: 19.7.3(@swc/core@1.13.3) typescript: specifier: 'catalog:' version: 5.8.3 @@ -180,13 +180,16 @@ importers: version: 0.80.0 '@rsdoctor/rspack-plugin': specifier: ^0.4.11 - version: 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) + version: 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) '@rspack/core': specifier: 'catalog:' - version: 1.4.6(@swc/helpers@0.5.17) + version: 1.4.11(@swc/helpers@0.5.17) '@svgr/webpack': specifier: ^8.1.0 version: 8.1.0(typescript@5.8.3) + '@swc/core': + specifier: ^1.13.3 + version: 1.13.3(@swc/helpers@0.5.17) '@swc/helpers': specifier: 'catalog:' version: 0.5.17 @@ -213,7 +216,7 @@ importers: version: 8.5.1 postcss-loader: specifier: ^8.1.1 - version: 8.1.1(@rspack/core@1.4.6(@swc/helpers@0.5.17))(postcss@8.5.1)(typescript@5.8.3)(webpack@5.100.2) + version: 8.1.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(postcss@8.5.1)(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) react-native-test-app: specifier: catalog:testers version: 4.4.5(react-native@0.80.0(@babel/core@7.25.2)(@react-native-community/cli@19.0.0(typescript@5.8.3))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) @@ -222,7 +225,10 @@ importers: version: 3.4.17 terser-webpack-plugin: specifier: 'catalog:' - version: 5.3.14(webpack@5.100.2) + version: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + thread-loader: + specifier: ^4.0.4 + version: 4.0.4(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) typescript: specifier: 'catalog:' version: 5.8.3 @@ -231,7 +237,7 @@ importers: version: 2.0.5(@types/node@20.14.11)(lightningcss@1.28.2)(terser@5.31.3) webpack: specifier: 'catalog:' - version: 5.100.2 + version: 5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)) apps/tester-federation: dependencies: @@ -280,10 +286,10 @@ importers: version: 0.80.0 '@rsdoctor/rspack-plugin': specifier: ^0.4.5 - version: 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) + version: 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) '@rspack/core': specifier: 'catalog:' - version: 1.4.6(@swc/helpers@0.5.17) + version: 1.4.11(@swc/helpers@0.5.17) '@swc/helpers': specifier: 'catalog:' version: 0.5.17 @@ -298,13 +304,13 @@ importers: version: 4.4.5(react-native@0.80.0(@babel/core@7.25.2)(@react-native-community/cli@19.0.0(typescript@5.8.3))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) terser-webpack-plugin: specifier: 'catalog:' - version: 5.3.14(webpack@5.100.2) + version: 5.3.14(@swc/core@1.13.3)(webpack@5.100.2(@swc/core@1.13.3)) typescript: specifier: 'catalog:' version: 5.8.3 webpack: specifier: 'catalog:' - version: 5.100.2 + version: 5.100.2(@swc/core@1.13.3) apps/tester-federation-v2: dependencies: @@ -313,7 +319,7 @@ importers: version: link:../../packages/repack '@module-federation/enhanced': specifier: 0.12.0 - version: 0.12.0(@rspack/core@1.4.6(@swc/helpers@0.5.17))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack@5.100.2) + version: 0.12.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.3)) '@module-federation/runtime': specifier: 0.12.0 version: 0.12.0 @@ -359,10 +365,10 @@ importers: version: 0.80.0 '@rsdoctor/rspack-plugin': specifier: ^0.4.5 - version: 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) + version: 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) '@rspack/core': specifier: 'catalog:' - version: 1.4.6(@swc/helpers@0.5.17) + version: 1.4.11(@swc/helpers@0.5.17) '@swc/helpers': specifier: 'catalog:' version: 0.5.17 @@ -377,13 +383,13 @@ importers: version: 4.4.5(react-native@0.80.0(@babel/core@7.25.2)(@react-native-community/cli@19.0.0(typescript@5.8.3))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0) terser-webpack-plugin: specifier: 'catalog:' - version: 5.3.14(webpack@5.100.2) + version: 5.3.14(@swc/core@1.13.3)(webpack@5.100.2(@swc/core@1.13.3)) typescript: specifier: 'catalog:' version: 5.8.3 webpack: specifier: 'catalog:' - version: 5.100.2 + version: 5.100.2(@swc/core@1.13.3) packages/dev-server: dependencies: @@ -502,13 +508,13 @@ importers: version: link:../repack '@rspack/core': specifier: 'catalog:' - version: 1.4.6(@swc/helpers@0.5.17) + version: 1.4.11(@swc/helpers@0.5.17) '@types/node': specifier: 'catalog:' version: 20.14.11 webpack: specifier: 'catalog:' - version: 5.100.2 + version: 5.100.2(@swc/core@1.13.3) packages/plugin-nativewind: dependencies: @@ -521,7 +527,7 @@ importers: version: link:../repack '@rspack/core': specifier: 'catalog:' - version: 1.4.6(@swc/helpers@0.5.17) + version: 1.4.11(@swc/helpers@0.5.17) '@types/dedent': specifier: 0.7.2 version: 0.7.2 @@ -536,7 +542,7 @@ importers: version: 0.1.22(react-native-reanimated@4.0.0(@babel/core@7.25.2)(react-native-worklets@0.4.0(@babel/core@7.25.2)(react-native@0.80.0(@babel/core@7.25.2)(@react-native-community/cli@19.0.0(typescript@5.8.3))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0))(react-native@0.80.0(@babel/core@7.25.2)(@react-native-community/cli@19.0.0(typescript@5.8.3))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0))(react-native-safe-area-context@5.5.0(react-native@0.80.0(@babel/core@7.25.2)(@react-native-community/cli@19.0.0(typescript@5.8.3))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0))(react-native-svg@15.12.0(react-native@0.80.0(@babel/core@7.25.2)(@react-native-community/cli@19.0.0(typescript@5.8.3))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0))(react-native@0.80.0(@babel/core@7.25.2)(@react-native-community/cli@19.0.0(typescript@5.8.3))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.17) webpack: specifier: 'catalog:' - version: 5.100.2 + version: 5.100.2(@swc/core@1.13.3) packages/plugin-reanimated: dependencies: @@ -549,7 +555,7 @@ importers: version: link:../repack '@rspack/core': specifier: 'catalog:' - version: 1.4.6(@swc/helpers@0.5.17) + version: 1.4.11(@swc/helpers@0.5.17) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -561,7 +567,7 @@ importers: version: 7.7.0 webpack: specifier: 'catalog:' - version: 5.100.2 + version: 5.100.2(@swc/core@1.13.3) packages/repack: dependencies: @@ -576,7 +582,7 @@ importers: version: 1.0.0(react-refresh@0.14.2) babel-loader: specifier: ^9.2.1 - version: 9.2.1(@babel/core@7.25.2)(webpack@5.100.2) + version: 9.2.1(@babel/core@7.25.2)(webpack@5.100.2(@swc/core@1.13.3)) colorette: specifier: ^2.0.20 version: 2.0.20 @@ -630,7 +636,7 @@ importers: version: 2.2.1 terser-webpack-plugin: specifier: ^5.3.14 - version: 5.3.14(webpack@5.100.2) + version: 5.3.14(@swc/core@1.13.3)(webpack@5.100.2(@swc/core@1.13.3)) throttleit: specifier: ^2.1.0 version: 2.1.0 @@ -652,16 +658,19 @@ importers: version: 7.24.8(@babel/core@7.25.2) '@module-federation/enhanced': specifier: 0.8.9 - version: 0.8.9(@rspack/core@1.4.6(@swc/helpers@0.5.17))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack@5.100.2) + version: 0.8.9(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.3)) '@module-federation/sdk': specifier: 0.6.10 version: 0.6.10 '@rspack/core': specifier: 'catalog:' - version: 1.4.6(@swc/helpers@0.5.17) + version: 1.4.11(@swc/helpers@0.5.17) '@swc/helpers': specifier: 'catalog:' version: 0.5.17 + '@types/babel__core': + specifier: ^7.20.5 + version: 7.20.5 '@types/dedent': specifier: ^0.7.0 version: 0.7.2 @@ -709,7 +718,7 @@ importers: version: 5.8.3 webpack: specifier: 'catalog:' - version: 5.100.2 + version: 5.100.2(@swc/core@1.13.3) tests/metro-compat: devDependencies: @@ -769,22 +778,22 @@ importers: dependencies: '@callstack/rspress-theme': specifier: ^0.3.1 - version: 0.3.1(react@19.1.0)(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2)) + version: 0.3.1(react@19.1.0)(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3))) '@rspress/plugin-llms': specifier: 2.0.0-beta.21 - version: 2.0.0-beta.21(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2)) + version: 2.0.0-beta.21(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3))) rsbuild-plugin-open-graph: specifier: ^1.0.2 version: 1.0.2(@rsbuild/core@1.4.6) rspress: specifier: 2.0.0-beta.21 - version: 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2) + version: 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3)) rspress-plugin-sitemap: specifier: ^1.1.1 version: 1.1.1 rspress-plugin-vercel-analytics: specifier: ^0.3.0 - version: 0.3.0(react@19.1.0)(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2)) + version: 0.3.0(react@19.1.0)(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3))) devDependencies: '@types/node': specifier: 'catalog:' @@ -1693,12 +1702,21 @@ packages: '@emnapi/core@1.4.3': resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} + '@emnapi/core@1.4.5': + resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} + '@emnapi/runtime@1.4.3': resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + '@emnapi/runtime@1.4.5': + resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} + '@emnapi/wasi-threads@1.0.2': resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} + '@emnapi/wasi-threads@1.0.4': + resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -2251,6 +2269,9 @@ packages: '@module-federation/error-codes@0.15.0': resolution: {integrity: sha512-CFJSF+XKwTcy0PFZ2l/fSUpR4z247+Uwzp1sXVkdIfJ/ATsnqf0Q01f51qqSEA6MYdQi6FKos9FIcu3dCpQNdg==} + '@module-federation/error-codes@0.17.1': + resolution: {integrity: sha512-n6Elm4qKSjwAPxLUGtwnl7qt4y1dxB8OpSgVvXBIzqI9p27a3ZXshLPLnumlpPg1Qudaj8sLnSnFtt9yGpt5yQ==} + '@module-federation/error-codes@0.8.4': resolution: {integrity: sha512-55LYmrDdKb4jt+qr8qE8U3al62ZANp3FhfVaNPOaAmdTh0jHdD8M3yf5HKFlr5xVkVO4eV/F/J2NCfpbh+pEXQ==} @@ -2312,6 +2333,9 @@ packages: '@module-federation/runtime-core@0.15.0': resolution: {integrity: sha512-RYzI61fRDrhyhaEOXH3AgIGlHiot0wPFXu7F43cr+ZnTi+VlSYWLdlZ4NBuT9uV6JSmH54/c+tEZm5SXgKR2sQ==} + '@module-federation/runtime-core@0.17.1': + resolution: {integrity: sha512-LCtIFuKgWPQ3E+13OyrVpuTPOWBMI/Ggwsq1Q874YeT8Px28b8tJRCj09DjyRFyhpSPyV/uG80T6iXPAUoLIfQ==} + '@module-federation/runtime-core@0.6.17': resolution: {integrity: sha512-PXFN/TT9f64Un6NQYqH1Z0QLhpytW15jkZvTEOV8W7Ed319BECFI0Rv4xAsAGa8zJGFoaM/c7QOQfdFXtKj5Og==} @@ -2324,6 +2348,9 @@ packages: '@module-federation/runtime-tools@0.15.0': resolution: {integrity: sha512-kzFn3ObUeBp5vaEtN1WMxhTYBuYEErxugu1RzFUERD21X3BZ+b4cWwdFJuBDlsmVjctIg/QSOoZoPXRKAO0foA==} + '@module-federation/runtime-tools@0.17.1': + resolution: {integrity: sha512-4kr6zTFFwGywJx6whBtxsc84V+COAuuBpEdEbPZN//YLXhNB0iz2IGsy9r9wDl+06h84bD+3dQ05l9euRLgXzQ==} + '@module-federation/runtime-tools@0.8.4': resolution: {integrity: sha512-fjVOsItJ1u5YY6E9FnS56UDwZgqEQUrWFnouRiPtK123LUuqUI9FH4redZoKWlE1PB0ir1Z3tnqy8eFYzPO38Q==} @@ -2339,6 +2366,9 @@ packages: '@module-federation/runtime@0.15.0': resolution: {integrity: sha512-dTPsCNum9Bhu3yPOcrPYq0YnM9eCMMMNB1wuiqf1+sFbQlNApF0vfZxooqz3ln0/MpgE0jerVvFsLVGfqvC9Ug==} + '@module-federation/runtime@0.17.1': + resolution: {integrity: sha512-vKEN32MvUbpeuB/s6UXfkHDZ9N5jFyDDJnj83UTJ8n4N1jHIJu9VZ6Yi4/Ac8cfdvU8UIK9bIbfVXWbUYZUDsw==} + '@module-federation/runtime@0.8.4': resolution: {integrity: sha512-yZeZ7z2Rx4gv/0E97oLTF3V6N25vglmwXGgoeju/W2YjsFvWzVtCDI7zRRb0mJhU6+jmSM8jP1DeQGbea/AiZQ==} @@ -2354,6 +2384,9 @@ packages: '@module-federation/sdk@0.15.0': resolution: {integrity: sha512-PWiYbGcJrKUD6JZiEPihrXhV3bgXdll4bV7rU+opV7tHaun+Z0CdcawjZ82Xnpb8MCPGmqHwa1MPFeUs66zksw==} + '@module-federation/sdk@0.17.1': + resolution: {integrity: sha512-nlUcN6UTEi+3HWF+k8wPy7gH0yUOmCT+xNatihkIVR9REAnr7BUvHFGlPJmx7WEbLPL46+zJUbtQHvLzXwFhng==} + '@module-federation/sdk@0.6.10': resolution: {integrity: sha512-i6ofHnImB4zCn/bt7Ft0zh9o/PxvsJj8Wc88EAeJg4IrY6+bzwwo1G2h44w1Yt3go4skZZFQCK0UxoaV6l/t/A==} @@ -2378,6 +2411,9 @@ packages: '@module-federation/webpack-bundler-runtime@0.15.0': resolution: {integrity: sha512-i+3wu2Ljh2TmuUpsnjwZVupOVqV50jP0ndA8PSP4gwMKlgdGeaZ4VH5KkHAXGr2eiYUxYLMrJXz1+eILJqeGDg==} + '@module-federation/webpack-bundler-runtime@0.17.1': + resolution: {integrity: sha512-Swspdgf4PzcbvS9SNKFlBzfq8h/Qxwqjq/xRSqw1pqAZWondZQzwTTqPXhgrg0bFlz7qWjBS/6a8KuH/gRvGaQ==} + '@module-federation/webpack-bundler-runtime@0.8.4': resolution: {integrity: sha512-HggROJhvHPUX7uqBD/XlajGygMNM1DG0+4OAkk8MBQe4a18QzrRNzZt6XQbRTSG4OaEoyRWhQHvYD3Yps405tQ==} @@ -2390,6 +2426,9 @@ packages: '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + '@napi-rs/wasm-runtime@1.0.1': + resolution: {integrity: sha512-KVlQ/jgywZpixGCKMNwxStmmbYEMyokZpCf2YuIChhfJA2uqfAKNEM8INz7zzTo55iEXfBhIIs3VqYyqzDLj8g==} + '@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3': resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} @@ -2806,6 +2845,11 @@ packages: cpu: [arm64] os: [darwin] + '@rspack/binding-darwin-arm64@1.4.11': + resolution: {integrity: sha512-PrmBVhR8MC269jo6uQ+BMy1uwIDx0HAJYLQRQur8gXiehWabUBCRg/d4U9KR7rLzdaSScRyc5JWXR52T7/4MfA==} + cpu: [arm64] + os: [darwin] + '@rspack/binding-darwin-arm64@1.4.6': resolution: {integrity: sha512-K37H8e58eY7zBHGeMVtT7m0Z5XvlNQX7YDuaxlbiA4hZxqeRoS5BMX/YOcDiGdNbSuqv+iG5GSckJ99YUI67Cw==} cpu: [arm64] @@ -2821,6 +2865,11 @@ packages: cpu: [x64] os: [darwin] + '@rspack/binding-darwin-x64@1.4.11': + resolution: {integrity: sha512-YIV8Wzy+JY0SoSsVtN4wxFXOjzxxVPnVXNswrrfqVUTPr9jqGOFYUWCGpbt8lcCgfuBFm6zN8HpOsKm1xUNsVA==} + cpu: [x64] + os: [darwin] + '@rspack/binding-darwin-x64@1.4.6': resolution: {integrity: sha512-3p5u9q/Q9MMVe+5XFJ/WiFrzNrrxUjJFR19kB1k/KMcf8ox982xWjnfJuBkET/k7Hn0EZL7L06ym447uIfAVAg==} cpu: [x64] @@ -2836,6 +2885,11 @@ packages: cpu: [arm64] os: [linux] + '@rspack/binding-linux-arm64-gnu@1.4.11': + resolution: {integrity: sha512-ms6uwECUIcu+6e82C5HJhRMHnfsI+l33v7XQezntzRPN0+sG3EpikEoT7SGbgt4vDwaWLR7wS20suN4qd5r3GA==} + cpu: [arm64] + os: [linux] + '@rspack/binding-linux-arm64-gnu@1.4.6': resolution: {integrity: sha512-ZrrCn5b037ImZfZ3MShJrRw4d5M3Tq2rFJupr+SGMg7GTl2T6xEmo3ER/evHlT6e0ETi6tRWPxC9A1125jbSQA==} cpu: [arm64] @@ -2851,6 +2905,11 @@ packages: cpu: [arm64] os: [linux] + '@rspack/binding-linux-arm64-musl@1.4.11': + resolution: {integrity: sha512-9evq0DOdxMN/H8VM8ZmyY9NSuBgILNVV6ydBfVPMHPx4r1E7JZGpWeKDegZcS5Erw3sS9kVSIxyX78L5PDzzKw==} + cpu: [arm64] + os: [linux] + '@rspack/binding-linux-arm64-musl@1.4.6': resolution: {integrity: sha512-0a30oR6ZmZrqmsOHQYrbZPCxAgnqAiqlbFozdhHs+Yu2bS7SDiLpdjMg0PHwLZT2+siiMWsLodFZlXRJE54oAQ==} cpu: [arm64] @@ -2866,6 +2925,11 @@ packages: cpu: [x64] os: [linux] + '@rspack/binding-linux-x64-gnu@1.4.11': + resolution: {integrity: sha512-bHYFLxPPYBOSaHdQbEoCYGMQ1gOrEWj7Mro/DLfSHZi1a0okcQ2Q1y0i1DczReim3ZhLGNrK7k1IpFXCRbAobQ==} + cpu: [x64] + os: [linux] + '@rspack/binding-linux-x64-gnu@1.4.6': resolution: {integrity: sha512-u6pq1aq7bX+NABVDDTOzH64KMj1KJn8fUWO+FaX7Kr7PBjhmxNRs4OaWZjbXEY6COhMYEJZ04h4DhY+lRzcKjA==} cpu: [x64] @@ -2881,11 +2945,20 @@ packages: cpu: [x64] os: [linux] + '@rspack/binding-linux-x64-musl@1.4.11': + resolution: {integrity: sha512-wrm4E7q2k4+cwT6Uhp6hIQ3eUe/YoaUttj6j5TqHYZX6YeLrNPtD9+ne6lQQ17BV8wmm6NZsmoFIJ5xIptpRhQ==} + cpu: [x64] + os: [linux] + '@rspack/binding-linux-x64-musl@1.4.6': resolution: {integrity: sha512-rjP/1dWKB828kzd4/QpDYNVasUAKDj0OeRJGh5L/RluSH3pEqhxm5FwvndpmFDv6m3iPekZ4IO26UrpGJmE9fw==} cpu: [x64] os: [linux] + '@rspack/binding-wasm32-wasi@1.4.11': + resolution: {integrity: sha512-hiYxHZjaZ17wQtXyLCK0IdtOvMWreGVTiGsaHCxyeT+SldDG+r16bXNjmlqfZsjlfl1mkAqKz1dg+mMX28OTqw==} + cpu: [wasm32] + '@rspack/binding-wasm32-wasi@1.4.6': resolution: {integrity: sha512-5M0g7TaWgCFQJr4NKYW2bTLbQJuAQIgZL7WmiDwotgscBJDQWJVBayFEsnM6PYX1Inmu6RNhQ44BKIYwwoSyYw==} cpu: [wasm32] @@ -2900,6 +2973,11 @@ packages: cpu: [arm64] os: [win32] + '@rspack/binding-win32-arm64-msvc@1.4.11': + resolution: {integrity: sha512-+HF/mnjmTr8PC1dccRt1bkrD2tPDGeqvXC1BBLYd/Klq1VbtIcnrhfmvQM6KaXbiLcY9VWKzcZPOTmnyZ8TaHQ==} + cpu: [arm64] + os: [win32] + '@rspack/binding-win32-arm64-msvc@1.4.6': resolution: {integrity: sha512-thPCdbh4O+uEAJ8AvXBWZIOW0ZopJAN3CX2zlprso8Cnhi4wDseTtrIxFQh7cTo6pR3xSZAIv/zHd+MMF8TImA==} cpu: [arm64] @@ -2915,6 +2993,11 @@ packages: cpu: [ia32] os: [win32] + '@rspack/binding-win32-ia32-msvc@1.4.11': + resolution: {integrity: sha512-EU2fQGwrRfwFd/tcOInlD0jy6gNQE4Q3Ayj0Is+cX77sbhPPyyOz0kZDEaQ4qaN2VU8w4Hu/rrD7c0GAKLFvCw==} + cpu: [ia32] + os: [win32] + '@rspack/binding-win32-ia32-msvc@1.4.6': resolution: {integrity: sha512-KQmm6c/ZfJKQ/TpzbY6J0pDvUB9kwTXzp+xl2FhGq2RXid8uyDS8ZqbeJA6LDxgttsmp4PRVJjMdLVYjZenfLw==} cpu: [ia32] @@ -2930,6 +3013,11 @@ packages: cpu: [x64] os: [win32] + '@rspack/binding-win32-x64-msvc@1.4.11': + resolution: {integrity: sha512-1Nc5ZzWqfvE+iJc47qtHFzYYnHsC3awavXrCo74GdGip1vxtksM3G30BlvAQHHVtEmULotWqPbjZpflw/Xk9Ag==} + cpu: [x64] + os: [win32] + '@rspack/binding-win32-x64-msvc@1.4.6': resolution: {integrity: sha512-WRRhCsJ+xcOmvzo/r/b2UTejPLnDEbaD/te1yQwHe97sUaFGr3u1Njk6lVYRTV6mEvUopEChb8yAq/S4dvaGLg==} cpu: [x64] @@ -2941,6 +3029,9 @@ packages: '@rspack/binding@1.3.3': resolution: {integrity: sha512-zdwJ801tyC8k+Gu5RjNoc7bEtX0MgJzzVv9qpaMwcAUfUfwZgCzXPTqcGMDoNI+Z47Fw59/2fKCmgZhZn60AgA==} + '@rspack/binding@1.4.11': + resolution: {integrity: sha512-maGl/zRwnl0QVwkBCkgjn5PH20L9HdlRIdkYhEsfTepy5x2QZ0ti/0T49djjTJQrqb+S1i6wWQymMMMMMsxx6Q==} + '@rspack/binding@1.4.6': resolution: {integrity: sha512-rRc6sbKWxhomxxJeqi4QS3S/2T6pKf4JwC/VHXs7KXw7lHXHa3yxPynmn3xHstL0H6VLaM5xQj87Wh7lQYRAPg==} @@ -2968,6 +3059,15 @@ packages: '@swc/helpers': optional: true + '@rspack/core@1.4.11': + resolution: {integrity: sha512-JtKnL6p7Kc/YgWQJF3Woo4OccbgKGyT/4187W4dyex8BMkdQcbqCNIdi6dFk02hwQzxpOOxRSBI4hlGRbz7oYQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@swc/helpers': '>=0.5.1' + peerDependenciesMeta: + '@swc/helpers': + optional: true + '@rspack/core@1.4.6': resolution: {integrity: sha512-/OpJLv7dPEE7x/qCXGecRm9suNxz5w0Dheq2sh0TjTCUHodtMET3T+FlRWznBAlZeNuHLECDp0DWhchgS8BWuA==} engines: {node: '>=16.0.0'} @@ -3210,12 +3310,87 @@ packages: resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} engines: {node: '>=14'} + '@swc/core-darwin-arm64@1.13.3': + resolution: {integrity: sha512-ux0Ws4pSpBTqbDS9GlVP354MekB1DwYlbxXU3VhnDr4GBcCOimpocx62x7cFJkSpEBF8bmX8+/TTCGKh4PbyXw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.13.3': + resolution: {integrity: sha512-p0X6yhxmNUOMZrbeZ3ZNsPige8lSlSe1llllXvpCLkKKxN/k5vZt1sULoq6Nj4eQ7KeHQVm81/+AwKZyf/e0TA==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.13.3': + resolution: {integrity: sha512-OmDoiexL2fVWvQTCtoh0xHMyEkZweQAlh4dRyvl8ugqIPEVARSYtaj55TBMUJIP44mSUOJ5tytjzhn2KFxFcBA==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.13.3': + resolution: {integrity: sha512-STfKku3QfnuUj6k3g9ld4vwhtgCGYIFQmsGPPgT9MK/dI3Lwnpe5Gs5t1inoUIoGNP8sIOLlBB4HV4MmBjQuhw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.13.3': + resolution: {integrity: sha512-bc+CXYlFc1t8pv9yZJGus372ldzOVscBl7encUBlU1m/Sig0+NDJLz6cXXRcFyl6ABNOApWeR4Yl7iUWx6C8og==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.13.3': + resolution: {integrity: sha512-dFXoa0TEhohrKcxn/54YKs1iwNeW6tUkHJgXW33H381SvjKFUV53WR231jh1sWVJETjA3vsAwxKwR23s7UCmUA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.13.3': + resolution: {integrity: sha512-ieyjisLB+ldexiE/yD8uomaZuZIbTc8tjquYln9Quh5ykOBY7LpJJYBWvWtm1g3pHv6AXlBI8Jay7Fffb6aLfA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.13.3': + resolution: {integrity: sha512-elTQpnaX5vESSbhCEgcwXjpMsnUbqqHfEpB7ewpkAsLzKEXZaK67ihSRYAuAx6ewRQTo7DS5iTT6X5aQD3MzMw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.13.3': + resolution: {integrity: sha512-nvehQVEOdI1BleJpuUgPLrclJ0TzbEMc+MarXDmmiRFwEUGqj+pnfkTSb7RZyS1puU74IXdK/YhTirHurtbI9w==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.13.3': + resolution: {integrity: sha512-A+JSKGkRbPLVV2Kwx8TaDAV0yXIXm/gc8m98hSkVDGlPBBmydgzNdWy3X7HTUBM7IDk7YlWE7w2+RUGjdgpTmg==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.13.3': + resolution: {integrity: sha512-ZaDETVWnm6FE0fc+c2UE8MHYVS3Fe91o5vkmGfgwGXFbxYvAjKSqxM/j4cRc9T7VZNSJjriXq58XkfCp3Y6f+w==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@swc/helpers@0.5.13': resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} '@swc/helpers@0.5.17': resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + '@swc/types@0.1.24': + resolution: {integrity: sha512-tjTMh3V4vAORHtdTprLlfoMptu1WfTZG9Rsca6yOKyNYsRr+MUXutKmliB17orgSZk5DpnDxs8GUdd/qwYxOng==} + '@trysound/sax@0.2.0': resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -3223,6 +3398,9 @@ packages: '@ts-morph/common@0.23.0': resolution: {integrity: sha512-m7Lllj9n/S6sOkCkRftpM7L24uvmfXQFedlW/4hENcuJH1HHm9u5EgxZb9uVjQSCGrbBWBkOGgcTxNg36r6ywA==} + '@tybys/wasm-util@0.10.0': + resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} + '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} @@ -6767,8 +6945,8 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - react-devtools-core@6.1.1: - resolution: {integrity: sha512-TFo1MEnkqE6hzAbaztnyR5uLTMoz6wnEWwWBsCUzNt+sVXJycuRJdDqvL078M4/h65BI/YO5XWTaxZDWVsW0fw==} + react-devtools-core@6.1.5: + resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==} react-dom@19.1.0: resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} @@ -7548,6 +7726,12 @@ packages: peerDependencies: tslib: ^2 + thread-loader@4.0.4: + resolution: {integrity: sha512-tXagu6Hivd03wB2tiS1bqvw345sc7mKei32EgpYpq31ZLes9FN0mEK2nKzXLRFgwt3PsBB0E/MZDp159rDoqwg==} + engines: {node: '>= 16.10.0'} + peerDependencies: + webpack: ^5.0.0 + thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} @@ -9110,10 +9294,10 @@ snapshots: '@biomejs/cli-win32-x64@1.9.4': optional: true - '@callstack/rspress-theme@0.3.1(react@19.1.0)(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2))': + '@callstack/rspress-theme@0.3.1(react@19.1.0)(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3)))': dependencies: react: 19.1.0 - rspress: 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2) + rspress: 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3)) '@changesets/apply-release-plan@7.0.12': dependencies: @@ -9292,14 +9476,30 @@ snapshots: '@emnapi/wasi-threads': 1.0.2 tslib: 2.8.1 + '@emnapi/core@1.4.5': + dependencies: + '@emnapi/wasi-threads': 1.0.4 + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.4.3': dependencies: tslib: 2.8.1 + '@emnapi/runtime@1.4.5': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.0.2': dependencies: tslib: 2.8.1 + '@emnapi/wasi-threads@1.0.4': + dependencies: + tslib: 2.8.1 + optional: true + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -9739,12 +9939,12 @@ snapshots: jju: 1.4.0 js-yaml: 4.1.0 - '@mdx-js/loader@3.1.0(acorn@8.15.0)(webpack@5.100.2)': + '@mdx-js/loader@3.1.0(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3))': dependencies: '@mdx-js/mdx': 3.1.0(acorn@8.15.0) source-map: 0.7.4 optionalDependencies: - webpack: 5.100.2 + webpack: 5.100.2(@swc/core@1.13.3) transitivePeerDependencies: - acorn - supports-color @@ -9897,7 +10097,7 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/enhanced@0.12.0(@rspack/core@1.4.6(@swc/helpers@0.5.17))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack@5.100.2)': + '@module-federation/enhanced@0.12.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.3))': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.12.0 '@module-federation/cli': 0.12.0(typescript@5.8.3) @@ -9907,7 +10107,7 @@ snapshots: '@module-federation/inject-external-runtime-core-plugin': 0.12.0(@module-federation/runtime-tools@0.12.0) '@module-federation/managers': 0.12.0 '@module-federation/manifest': 0.12.0(typescript@5.8.3) - '@module-federation/rspack': 0.12.0(@rspack/core@1.4.6(@swc/helpers@0.5.17))(typescript@5.8.3) + '@module-federation/rspack': 0.12.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(typescript@5.8.3) '@module-federation/runtime-tools': 0.12.0 '@module-federation/sdk': 0.12.0 btoa: 1.2.1 @@ -9915,7 +10115,7 @@ snapshots: upath: 2.0.1 optionalDependencies: typescript: 5.8.3 - webpack: 5.100.2 + webpack: 5.100.2(@swc/core@1.13.3) transitivePeerDependencies: - '@rspack/core' - bufferutil @@ -9925,7 +10125,7 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/enhanced@0.8.9(@rspack/core@1.4.6(@swc/helpers@0.5.17))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack@5.100.2)': + '@module-federation/enhanced@0.8.9(@rspack/core@1.4.11(@swc/helpers@0.5.17))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.3))': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.8.9 '@module-federation/data-prefetch': 0.8.9(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -9934,14 +10134,14 @@ snapshots: '@module-federation/inject-external-runtime-core-plugin': 0.8.9(@module-federation/runtime-tools@0.8.9) '@module-federation/managers': 0.8.9 '@module-federation/manifest': 0.8.9(typescript@5.8.3) - '@module-federation/rspack': 0.8.9(@rspack/core@1.4.6(@swc/helpers@0.5.17))(typescript@5.8.3) + '@module-federation/rspack': 0.8.9(@rspack/core@1.4.11(@swc/helpers@0.5.17))(typescript@5.8.3) '@module-federation/runtime-tools': 0.8.9 '@module-federation/sdk': 0.8.9 btoa: 1.2.1 upath: 2.0.1 optionalDependencies: typescript: 5.8.3 - webpack: 5.100.2 + webpack: 5.100.2(@swc/core@1.13.3) transitivePeerDependencies: - '@rspack/core' - bufferutil @@ -9957,6 +10157,8 @@ snapshots: '@module-federation/error-codes@0.15.0': {} + '@module-federation/error-codes@0.17.1': {} + '@module-federation/error-codes@0.8.4': {} '@module-federation/error-codes@0.8.9': {} @@ -10011,7 +10213,7 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/rspack@0.12.0(@rspack/core@1.4.6(@swc/helpers@0.5.17))(typescript@5.8.3)': + '@module-federation/rspack@0.12.0(@rspack/core@1.4.11(@swc/helpers@0.5.17))(typescript@5.8.3)': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.12.0 '@module-federation/dts-plugin': 0.12.0(typescript@5.8.3) @@ -10020,7 +10222,7 @@ snapshots: '@module-federation/manifest': 0.12.0(typescript@5.8.3) '@module-federation/runtime-tools': 0.12.0 '@module-federation/sdk': 0.12.0 - '@rspack/core': 1.4.6(@swc/helpers@0.5.17) + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) btoa: 1.2.1 optionalDependencies: typescript: 5.8.3 @@ -10030,7 +10232,7 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/rspack@0.8.9(@rspack/core@1.4.6(@swc/helpers@0.5.17))(typescript@5.8.3)': + '@module-federation/rspack@0.8.9(@rspack/core@1.4.11(@swc/helpers@0.5.17))(typescript@5.8.3)': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.8.9 '@module-federation/dts-plugin': 0.8.9(typescript@5.8.3) @@ -10039,7 +10241,7 @@ snapshots: '@module-federation/manifest': 0.8.9(typescript@5.8.3) '@module-federation/runtime-tools': 0.8.9 '@module-federation/sdk': 0.8.9 - '@rspack/core': 1.4.6(@swc/helpers@0.5.17) + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -10063,6 +10265,11 @@ snapshots: '@module-federation/error-codes': 0.15.0 '@module-federation/sdk': 0.15.0 + '@module-federation/runtime-core@0.17.1': + dependencies: + '@module-federation/error-codes': 0.17.1 + '@module-federation/sdk': 0.17.1 + '@module-federation/runtime-core@0.6.17': dependencies: '@module-federation/error-codes': 0.8.9 @@ -10083,6 +10290,11 @@ snapshots: '@module-federation/runtime': 0.15.0 '@module-federation/webpack-bundler-runtime': 0.15.0 + '@module-federation/runtime-tools@0.17.1': + dependencies: + '@module-federation/runtime': 0.17.1 + '@module-federation/webpack-bundler-runtime': 0.17.1 + '@module-federation/runtime-tools@0.8.4': dependencies: '@module-federation/runtime': 0.8.4 @@ -10111,6 +10323,12 @@ snapshots: '@module-federation/runtime-core': 0.15.0 '@module-federation/sdk': 0.15.0 + '@module-federation/runtime@0.17.1': + dependencies: + '@module-federation/error-codes': 0.17.1 + '@module-federation/runtime-core': 0.17.1 + '@module-federation/sdk': 0.17.1 + '@module-federation/runtime@0.8.4': dependencies: '@module-federation/error-codes': 0.8.4 @@ -10128,6 +10346,8 @@ snapshots: '@module-federation/sdk@0.15.0': {} + '@module-federation/sdk@0.17.1': {} + '@module-federation/sdk@0.6.10': {} '@module-federation/sdk@0.8.4': @@ -10165,6 +10385,11 @@ snapshots: '@module-federation/runtime': 0.15.0 '@module-federation/sdk': 0.15.0 + '@module-federation/webpack-bundler-runtime@0.17.1': + dependencies: + '@module-federation/runtime': 0.17.1 + '@module-federation/sdk': 0.17.1 + '@module-federation/webpack-bundler-runtime@0.8.4': dependencies: '@module-federation/runtime': 0.8.4 @@ -10188,6 +10413,13 @@ snapshots: '@emnapi/runtime': 1.4.3 '@tybys/wasm-util': 0.9.0 + '@napi-rs/wasm-runtime@1.0.1': + dependencies: + '@emnapi/core': 1.4.5 + '@emnapi/runtime': 1.4.5 + '@tybys/wasm-util': 0.10.0 + optional: true + '@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3': optional: true @@ -10203,9 +10435,9 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - '@nrwl/tao@19.7.3': + '@nrwl/tao@19.7.3(@swc/core@1.13.3)': dependencies: - nx: 19.7.3 + nx: 19.7.3(@swc/core@1.13.3) tslib: 2.8.1 transitivePeerDependencies: - '@swc-node/register' @@ -10374,7 +10606,7 @@ snapshots: fs-extra: 8.1.0 graceful-fs: 4.2.11 prompts: 2.4.2 - semver: 7.6.3 + semver: 7.7.2 transitivePeerDependencies: - bufferutil - supports-color @@ -10653,12 +10885,12 @@ snapshots: '@rsdoctor/client@0.4.11': {} - '@rsdoctor/core@0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2)': + '@rsdoctor/core@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)))': dependencies: - '@rsdoctor/graph': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rsdoctor/sdk': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rsdoctor/types': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) + '@rsdoctor/graph': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rsdoctor/sdk': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rsdoctor/types': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) axios: 1.8.4 enhanced-resolve: 5.12.0 filesize: 10.1.6 @@ -10676,10 +10908,33 @@ snapshots: - utf-8-validate - webpack - '@rsdoctor/graph@0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2)': + '@rsdoctor/core@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3))': dependencies: - '@rsdoctor/types': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) + '@rsdoctor/graph': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rsdoctor/sdk': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rsdoctor/types': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + axios: 1.8.4 + enhanced-resolve: 5.12.0 + filesize: 10.1.6 + fs-extra: 11.3.0 + lodash: 4.17.21 + path-browserify: 1.0.1 + semver: 7.7.2 + source-map: 0.7.4 + webpack-bundle-analyzer: 4.10.2 + transitivePeerDependencies: + - '@rspack/core' + - bufferutil + - debug + - supports-color + - utf-8-validate + - webpack + + '@rsdoctor/graph@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)))': + dependencies: + '@rsdoctor/types': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) lodash: 4.17.21 socket.io: 4.7.2 source-map: 0.7.4 @@ -10690,14 +10945,44 @@ snapshots: - utf-8-validate - webpack - '@rsdoctor/rspack-plugin@0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2)': + '@rsdoctor/graph@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3))': dependencies: - '@rsdoctor/core': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rsdoctor/graph': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rsdoctor/sdk': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rsdoctor/types': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rspack/core': 1.4.6(@swc/helpers@0.5.17) + '@rsdoctor/types': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + lodash: 4.17.21 + socket.io: 4.7.2 + source-map: 0.7.4 + transitivePeerDependencies: + - '@rspack/core' + - bufferutil + - supports-color + - utf-8-validate + - webpack + + '@rsdoctor/rspack-plugin@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)))': + dependencies: + '@rsdoctor/core': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rsdoctor/graph': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rsdoctor/sdk': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rsdoctor/types': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) + lodash: 4.17.21 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + - webpack + + '@rsdoctor/rspack-plugin@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3))': + dependencies: + '@rsdoctor/core': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rsdoctor/graph': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rsdoctor/sdk': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rsdoctor/types': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) lodash: 4.17.21 transitivePeerDependencies: - bufferutil @@ -10706,12 +10991,37 @@ snapshots: - utf-8-validate - webpack - '@rsdoctor/sdk@0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2)': + '@rsdoctor/sdk@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)))': + dependencies: + '@rsdoctor/client': 0.4.11 + '@rsdoctor/graph': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rsdoctor/types': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@types/fs-extra': 11.0.4 + body-parser: 1.20.3 + cors: 2.8.5 + dayjs: 1.11.13 + fs-extra: 11.3.0 + json-cycle: 1.5.0 + lodash: 4.17.21 + open: 8.4.2 + serve-static: 1.16.2 + socket.io: 4.7.2 + source-map: 0.7.4 + tapable: 2.2.1 + transitivePeerDependencies: + - '@rspack/core' + - bufferutil + - supports-color + - utf-8-validate + - webpack + + '@rsdoctor/sdk@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3))': dependencies: '@rsdoctor/client': 0.4.11 - '@rsdoctor/graph': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rsdoctor/types': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) - '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) + '@rsdoctor/graph': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rsdoctor/types': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) + '@rsdoctor/utils': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) '@types/fs-extra': 11.0.4 body-parser: 1.20.3 cors: 2.8.5 @@ -10731,20 +11041,55 @@ snapshots: - utf-8-validate - webpack - '@rsdoctor/types@0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2)': + '@rsdoctor/types@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)))': dependencies: '@types/connect': 3.4.38 '@types/estree': 1.0.5 '@types/tapable': 2.2.7 source-map: 0.7.4 - webpack: 5.100.2 + webpack: 5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)) optionalDependencies: - '@rspack/core': 1.4.6(@swc/helpers@0.5.17) + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) - '@rsdoctor/utils@0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2)': + '@rsdoctor/types@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3))': + dependencies: + '@types/connect': 3.4.38 + '@types/estree': 1.0.5 + '@types/tapable': 2.2.7 + source-map: 0.7.4 + webpack: 5.100.2(@swc/core@1.13.3) + optionalDependencies: + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) + + '@rsdoctor/utils@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)))': dependencies: '@babel/code-frame': 7.25.7 - '@rsdoctor/types': 0.4.11(@rspack/core@1.4.6(@swc/helpers@0.5.17))(webpack@5.100.2) + '@rsdoctor/types': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + '@types/estree': 1.0.5 + acorn: 8.15.0 + acorn-import-assertions: 1.9.0(acorn@8.15.0) + acorn-walk: 8.3.4 + chalk: 4.1.2 + connect: 3.7.0 + deep-eql: 4.1.4 + envinfo: 7.14.0 + filesize: 10.1.6 + fs-extra: 11.3.0 + get-port: 5.1.1 + json-stream-stringify: 3.0.1 + lines-and-columns: 2.0.4 + lodash: 4.17.21 + rslog: 1.2.3 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - '@rspack/core' + - supports-color + - webpack + + '@rsdoctor/utils@0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3))': + dependencies: + '@babel/code-frame': 7.25.7 + '@rsdoctor/types': 0.4.11(@rspack/core@1.4.11(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3)) '@types/estree': 1.0.5 acorn: 8.15.0 acorn-import-assertions: 1.9.0(acorn@8.15.0) @@ -10782,6 +11127,9 @@ snapshots: '@rspack/binding-darwin-arm64@1.3.3': optional: true + '@rspack/binding-darwin-arm64@1.4.11': + optional: true + '@rspack/binding-darwin-arm64@1.4.6': optional: true @@ -10791,6 +11139,9 @@ snapshots: '@rspack/binding-darwin-x64@1.3.3': optional: true + '@rspack/binding-darwin-x64@1.4.11': + optional: true + '@rspack/binding-darwin-x64@1.4.6': optional: true @@ -10800,6 +11151,9 @@ snapshots: '@rspack/binding-linux-arm64-gnu@1.3.3': optional: true + '@rspack/binding-linux-arm64-gnu@1.4.11': + optional: true + '@rspack/binding-linux-arm64-gnu@1.4.6': optional: true @@ -10809,6 +11163,9 @@ snapshots: '@rspack/binding-linux-arm64-musl@1.3.3': optional: true + '@rspack/binding-linux-arm64-musl@1.4.11': + optional: true + '@rspack/binding-linux-arm64-musl@1.4.6': optional: true @@ -10818,6 +11175,9 @@ snapshots: '@rspack/binding-linux-x64-gnu@1.3.3': optional: true + '@rspack/binding-linux-x64-gnu@1.4.11': + optional: true + '@rspack/binding-linux-x64-gnu@1.4.6': optional: true @@ -10827,9 +11187,17 @@ snapshots: '@rspack/binding-linux-x64-musl@1.3.3': optional: true + '@rspack/binding-linux-x64-musl@1.4.11': + optional: true + '@rspack/binding-linux-x64-musl@1.4.6': optional: true + '@rspack/binding-wasm32-wasi@1.4.11': + dependencies: + '@napi-rs/wasm-runtime': 1.0.1 + optional: true + '@rspack/binding-wasm32-wasi@1.4.6': dependencies: '@napi-rs/wasm-runtime': 0.2.11 @@ -10841,6 +11209,9 @@ snapshots: '@rspack/binding-win32-arm64-msvc@1.3.3': optional: true + '@rspack/binding-win32-arm64-msvc@1.4.11': + optional: true + '@rspack/binding-win32-arm64-msvc@1.4.6': optional: true @@ -10850,6 +11221,9 @@ snapshots: '@rspack/binding-win32-ia32-msvc@1.3.3': optional: true + '@rspack/binding-win32-ia32-msvc@1.4.11': + optional: true + '@rspack/binding-win32-ia32-msvc@1.4.6': optional: true @@ -10859,6 +11233,9 @@ snapshots: '@rspack/binding-win32-x64-msvc@1.3.3': optional: true + '@rspack/binding-win32-x64-msvc@1.4.11': + optional: true + '@rspack/binding-win32-x64-msvc@1.4.6': optional: true @@ -10886,6 +11263,19 @@ snapshots: '@rspack/binding-win32-ia32-msvc': 1.3.3 '@rspack/binding-win32-x64-msvc': 1.3.3 + '@rspack/binding@1.4.11': + optionalDependencies: + '@rspack/binding-darwin-arm64': 1.4.11 + '@rspack/binding-darwin-x64': 1.4.11 + '@rspack/binding-linux-arm64-gnu': 1.4.11 + '@rspack/binding-linux-arm64-musl': 1.4.11 + '@rspack/binding-linux-x64-gnu': 1.4.11 + '@rspack/binding-linux-x64-musl': 1.4.11 + '@rspack/binding-wasm32-wasi': 1.4.11 + '@rspack/binding-win32-arm64-msvc': 1.4.11 + '@rspack/binding-win32-ia32-msvc': 1.4.11 + '@rspack/binding-win32-x64-msvc': 1.4.11 + '@rspack/binding@1.4.6': optionalDependencies: '@rspack/binding-darwin-arm64': 1.4.6 @@ -10917,6 +11307,14 @@ snapshots: optionalDependencies: '@swc/helpers': 0.5.17 + '@rspack/core@1.4.11(@swc/helpers@0.5.17)': + dependencies: + '@module-federation/runtime-tools': 0.17.1 + '@rspack/binding': 1.4.11 + '@rspack/lite-tapable': 1.0.1 + optionalDependencies: + '@swc/helpers': 0.5.17 + '@rspack/core@1.4.6(@swc/helpers@0.5.17)': dependencies: '@module-federation/runtime-tools': 0.15.0 @@ -10940,9 +11338,9 @@ snapshots: html-entities: 2.6.0 react-refresh: 0.17.0 - '@rspress/core@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2)': + '@rspress/core@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3))': dependencies: - '@mdx-js/loader': 3.1.0(acorn@8.15.0)(webpack@5.100.2) + '@mdx-js/loader': 3.1.0(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3)) '@mdx-js/mdx': 3.1.0(acorn@8.15.0) '@mdx-js/react': 3.1.0(@types/react@18.3.3)(react@19.1.0) '@rsbuild/core': 1.4.6 @@ -11019,12 +11417,12 @@ snapshots: '@rspress/mdx-rs-win32-arm64-msvc': 0.6.6 '@rspress/mdx-rs-win32-x64-msvc': 0.6.6 - '@rspress/plugin-llms@2.0.0-beta.21(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2))': + '@rspress/plugin-llms@2.0.0-beta.21(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3)))': dependencies: remark-mdx: 3.1.0 remark-parse: 11.0.0 remark-stringify: 11.0.0 - rspress: 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2) + rspress: 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3)) unified: 11.0.5 unist-util-visit: 5.0.0 unist-util-visit-children: 3.0.0 @@ -11241,6 +11639,55 @@ snapshots: - supports-color - typescript + '@swc/core-darwin-arm64@1.13.3': + optional: true + + '@swc/core-darwin-x64@1.13.3': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.13.3': + optional: true + + '@swc/core-linux-arm64-gnu@1.13.3': + optional: true + + '@swc/core-linux-arm64-musl@1.13.3': + optional: true + + '@swc/core-linux-x64-gnu@1.13.3': + optional: true + + '@swc/core-linux-x64-musl@1.13.3': + optional: true + + '@swc/core-win32-arm64-msvc@1.13.3': + optional: true + + '@swc/core-win32-ia32-msvc@1.13.3': + optional: true + + '@swc/core-win32-x64-msvc@1.13.3': + optional: true + + '@swc/core@1.13.3(@swc/helpers@0.5.17)': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.24 + optionalDependencies: + '@swc/core-darwin-arm64': 1.13.3 + '@swc/core-darwin-x64': 1.13.3 + '@swc/core-linux-arm-gnueabihf': 1.13.3 + '@swc/core-linux-arm64-gnu': 1.13.3 + '@swc/core-linux-arm64-musl': 1.13.3 + '@swc/core-linux-x64-gnu': 1.13.3 + '@swc/core-linux-x64-musl': 1.13.3 + '@swc/core-win32-arm64-msvc': 1.13.3 + '@swc/core-win32-ia32-msvc': 1.13.3 + '@swc/core-win32-x64-msvc': 1.13.3 + '@swc/helpers': 0.5.17 + + '@swc/counter@0.1.3': {} + '@swc/helpers@0.5.13': dependencies: tslib: 2.8.1 @@ -11249,6 +11696,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@swc/types@0.1.24': + dependencies: + '@swc/counter': 0.1.3 + '@trysound/sax@0.2.0': {} '@ts-morph/common@0.23.0': @@ -11258,6 +11709,11 @@ snapshots: mkdirp: 3.0.1 path-browserify: 1.0.1 + '@tybys/wasm-util@0.10.0': + dependencies: + tslib: 2.8.1 + optional: true + '@tybys/wasm-util@0.9.0': dependencies: tslib: 2.8.1 @@ -11755,12 +12211,12 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@9.2.1(@babel/core@7.25.2)(webpack@5.100.2): + babel-loader@9.2.1(@babel/core@7.25.2)(webpack@5.100.2(@swc/core@1.13.3)): dependencies: '@babel/core': 7.25.2 find-cache-dir: 4.0.0 schema-utils: 4.3.0 - webpack: 5.100.2 + webpack: 5.100.2(@swc/core@1.13.3) babel-plugin-istanbul@6.1.1: dependencies: @@ -15202,10 +15658,10 @@ snapshots: nullthrows@1.1.1: {} - nx@19.7.3: + nx@19.7.3(@swc/core@1.13.3): dependencies: '@napi-rs/wasm-runtime': 0.2.4 - '@nrwl/tao': 19.7.3 + '@nrwl/tao': 19.7.3(@swc/core@1.13.3) '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.7 @@ -15250,6 +15706,7 @@ snapshots: '@nx/nx-linux-x64-musl': 19.7.3 '@nx/nx-win32-arm64-msvc': 19.7.3 '@nx/nx-win32-x64-msvc': 19.7.3 + '@swc/core': 1.13.3(@swc/helpers@0.5.17) transitivePeerDependencies: - debug @@ -15545,15 +16002,15 @@ snapshots: optionalDependencies: postcss: 8.5.1 - postcss-loader@8.1.1(@rspack/core@1.4.6(@swc/helpers@0.5.17))(postcss@8.5.1)(typescript@5.8.3)(webpack@5.100.2): + postcss-loader@8.1.1(@rspack/core@1.4.11(@swc/helpers@0.5.17))(postcss@8.5.1)(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: cosmiconfig: 9.0.0(typescript@5.8.3) jiti: 1.21.7 postcss: 8.5.1 semver: 7.6.3 optionalDependencies: - '@rspack/core': 1.4.6(@swc/helpers@0.5.17) - webpack: 5.100.2 + '@rspack/core': 1.4.11(@swc/helpers@0.5.17) + webpack: 5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)) transitivePeerDependencies: - typescript @@ -15669,7 +16126,7 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - react-devtools-core@6.1.1: + react-devtools-core@6.1.5: dependencies: shell-quote: 1.8.1 ws: 7.5.10 @@ -15807,11 +16264,11 @@ snapshots: pretty-format: 29.7.0 promise: 8.3.0 react: 19.1.0 - react-devtools-core: 6.1.1 + react-devtools-core: 6.1.5 react-refresh: 0.14.2 regenerator-runtime: 0.13.11 scheduler: 0.26.0 - semver: 7.6.3 + semver: 7.7.2 stacktrace-parser: 0.1.10 whatwg-fetch: 3.6.20 ws: 6.2.3 @@ -16134,7 +16591,7 @@ snapshots: dependencies: fs-extra: 11.3.0 - rspress-plugin-devkit@0.3.0(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2)): + rspress-plugin-devkit@0.3.0(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3))): dependencies: '@rspress/shared': 1.42.0 '@types/estree-jsx': 1.0.5 @@ -16149,7 +16606,7 @@ snapshots: mdast-util-to-markdown: 1.5.0 mdast-util-to-string: 4.0.0 remark-mdc: 1.2.0 - rspress: 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2) + rspress: 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3)) ts-morph: 22.0.0 unified: 10.1.2 unist-util-visit: 5.0.0 @@ -16163,22 +16620,22 @@ snapshots: rspress-plugin-sitemap@1.1.1: {} - rspress-plugin-vercel-analytics@0.3.0(react@19.1.0)(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2)): + rspress-plugin-vercel-analytics@0.3.0(react@19.1.0)(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3))): dependencies: '@rspress/shared': 1.42.0 '@vercel/analytics': 1.3.1(react@19.1.0) - rspress: 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2) - rspress-plugin-devkit: 0.3.0(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2)) + rspress: 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3)) + rspress-plugin-devkit: 0.3.0(rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3))) transitivePeerDependencies: - '@rspack/tracing' - next - react - supports-color - rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2): + rspress@2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3)): dependencies: '@rsbuild/core': 1.4.6 - '@rspress/core': 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2) + '@rspress/core': 2.0.0-beta.21(@types/react@18.3.3)(acorn@8.15.0)(webpack@5.100.2(@swc/core@1.13.3)) '@rspress/shared': 2.0.0-beta.21 cac: 6.7.14 chokidar: 3.6.0 @@ -16614,14 +17071,27 @@ snapshots: term-size@2.2.1: {} - terser-webpack-plugin@5.3.14(webpack@5.100.2): + terser-webpack-plugin@5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.2 serialize-javascript: 6.0.2 terser: 5.31.3 - webpack: 5.100.2 + webpack: 5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)) + optionalDependencies: + '@swc/core': 1.13.3(@swc/helpers@0.5.17) + + terser-webpack-plugin@5.3.14(@swc/core@1.13.3)(webpack@5.100.2(@swc/core@1.13.3)): + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 4.3.2 + serialize-javascript: 6.0.2 + terser: 5.31.3 + webpack: 5.100.2(@swc/core@1.13.3) + optionalDependencies: + '@swc/core': 1.13.3(@swc/helpers@0.5.17) terser@5.31.3: dependencies: @@ -16648,6 +17118,14 @@ snapshots: dependencies: tslib: 2.8.1 + thread-loader@4.0.4(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))): + dependencies: + json-parse-better-errors: 1.0.2 + loader-runner: 4.3.0 + neo-async: 2.6.2 + schema-utils: 4.3.2 + webpack: 5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)) + thread-stream@3.1.0: dependencies: real-require: 0.2.0 @@ -17045,7 +17523,39 @@ snapshots: webpack-sources@3.3.3: {} - webpack@5.100.2: + webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.24.4 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.2 + es-module-lexer: 1.5.4 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.2 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + watchpack: 2.4.1 + webpack-sources: 3.3.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + webpack@5.100.2(@swc/core@1.13.3): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -17069,7 +17579,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.2 tapable: 2.2.1 - terser-webpack-plugin: 5.3.14(webpack@5.100.2) + terser-webpack-plugin: 5.3.14(@swc/core@1.13.3)(webpack@5.100.2(@swc/core@1.13.3)) watchpack: 2.4.1 webpack-sources: 3.3.3 transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 406913c15..592821082 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -5,7 +5,7 @@ packages: - "website" catalog: - "@rspack/core": ^1.4.2 + "@rspack/core": ^1.4.11 "@rslib/core": ^0.6.3 "@swc/helpers": ~0.5.17 "@types/node": ^20 diff --git a/website/src/latest/api/loaders/_meta.json b/website/src/latest/api/loaders/_meta.json index 40517c8a1..f7e9929b4 100644 --- a/website/src/latest/api/loaders/_meta.json +++ b/website/src/latest/api/loaders/_meta.json @@ -1 +1,7 @@ -["assets-loader", "flow-loader", "react-refresh-loader"] +[ + "assets-loader", + "babel-loader", + "babel-swc-loader", + "flow-loader", + "react-refresh-loader" +] diff --git a/website/src/latest/api/loaders/babel-loader.md b/website/src/latest/api/loaders/babel-loader.md new file mode 100644 index 000000000..0894dd41c --- /dev/null +++ b/website/src/latest/api/loaders/babel-loader.md @@ -0,0 +1,78 @@ +# BabelLoader + +The `BabelLoader` runs Babel transformations for JavaScript and TypeScript sources in React Native projects. It chooses the parser based on source type: `hermes-parser` for JavaScript and Flow-typed files, and Babel's standard parser for TypeScript files. + +:::info How this loader differs from babel-loader + +There are two similarly named loaders: `@callstack/repack/babel-loader` (this loader) and `babel-loader` from npm. This loader is tailored for Re.Pack and aims for Metro parity, so the same Babel config used in Metro works as-is in Re.Pack. It automatically selects the parser by source type (Hermes parser for JS/JSX and Flow, Babel parser for TypeScript). + +It is also optimized for parallel transforms. In Rspack, enable [`experiments.parallelLoader`](https://rspack.rs/config/experiments#experimentsparallelloader) to fan out transforms; in webpack, pair it with [`thread-loader`](https://www.npmjs.com/package/thread-loader) to run a worker pool. On projects with heavier Babel pipelines, this often translates into noticeably faster builds. + +::: + +## Options + +```ts +// All Babel options from `@babel/core` are supported +type BabelTransformOptions = import('@babel/core').TransformOptions + +type BabelLoaderOptions = BabelTransformOptions & { + babel?: boolean; + flow?: "all" | "detect"; + reactRuntimeTarget?: "18" | "19"; + sourceType?: "module" | "script" | "unambiguous"; +}; +``` + +All options from the [Babel options documentation](https://babeljs.io/docs/options) are supported. See [Babel TransformOptions](#babel-transformoptions) below for more details. + + +### hermesParserPath + +- Type: `string` + +Optional path to use for importing `hermes-parser`. By default, the path is obtained automatically. + +### hermesParserOverrides + +- Type: `HermesParserOverrides` +- Default: `{ babel: true, reactRuntimeTarget: '19' }` + +Overrides passed to `hermes-parser` when parsing non-TypeScript files. + +```ts +type HermesParserOverrides = { + babel?: boolean; + flow?: "all" | "detect"; + reactRuntimeTarget?: "18" | "19"; + sourceType?: "module" | "script" | "unambiguous"; +}; +``` + +## Babel TransformOptions + +You can pass any standard Babel options (e.g. `presets`, `plugins`, `overrides`, etc.). Source maps are enabled automatically for application code and disabled for `node_modules` by default. + +## Example + +```js title=rspack.config.mjs +export default { + module: { + rules: [ + { + test: /\.[cm]?[jt]sx?$/, + type: "javascript/auto", + use: { + loader: "@callstack/repack/babel-loader", + options: { + presets: ["module:@react-native/babel-preset"], + plugins: ["react-native-reanimated/plugin"], + comments: true + }, + }, + }, + ], + }, +}; +``` + diff --git a/website/src/latest/api/loaders/babel-swc-loader.md b/website/src/latest/api/loaders/babel-swc-loader.md new file mode 100644 index 000000000..8392e7fb4 --- /dev/null +++ b/website/src/latest/api/loaders/babel-swc-loader.md @@ -0,0 +1,125 @@ +# BabelSwcLoader + +The `BabelSwcLoader` pairs Babel with SWC to deliver faster builds without sacrificing compatibility with complex Babel setups. It first runs Babel to respect your project’s configuration, then hands off the supported transforms to SWC. + +This loader can be used universally—even if your project does not have SWC. When SWC isn’t available, it cleanly falls back to pure Babel transforms, so you can adopt it incrementally without extra setup. +SWC can be provided either by Rspack (via its built-in integration) or by installing `@swc/core` in your project. + +:::danger Heads up! +Do not use `@callstack/repack/babel-swc-loader` together with `getJSTransformRules`. They overlap in functionality and will duplicate transforms when combined in one configuration. It might often result in code that's malformed and won't execute properly in the target mobile environment. +::: + +:::tip Maximizing performance +For optimal performance, enable Rspack’s parallel transforms with [`experiments.parallelLoader`](https://rspack.rs/config/experiments#experimentsparallelloader). This allows for transformations to run in parallel through worker threads managed by Rspack. +::: + +:::details How does this loader work? +The loader reads your Babel config and checks each plugin against a capability map to see if SWC can produce the same semantics. From that, it builds two ordered sets: transforms that stay in Babel and transforms handed off to SWC. This preserves your original plugin order and avoids behavior changes. + +Babel runs first and executes only the Babel‑only pieces while adding the minimal syntax support your sources need (for example, TS/TSX and Hermes‑compatible parsing where applicable). SWC then runs on the result with a generated configuration (including targets and optional lazy imports) and applies its share of the work. Each transform is applied once—never duplicated—and the output matches what you’d get from Babel alone. + +If SWC isn’t available, the SWC step is skipped and Babel handles everything. +::: + +## Options + +```ts +import type { TransformOptions } from "@babel/core"; +import type { Options } from "@swc/core"; + +type BabelOverrides = TransformOptions; +type SwcOverrides = Options; + +type BabelSwcLoaderOptions = { + hideParallelModeWarning?: boolean; + lazyImports?: boolean | string[]; + babelOverrides?: BabelOverrides; + swcOverrides?: SwcOverrides; + hermesParserPath?: string; + hermesParserOverrides?: { + babel?: boolean; + flow?: "all" | "detect"; + reactRuntimeTarget?: "18" | "19"; + sourceType?: "module" | "script" | "unambiguous"; + }; +}; +``` + +### lazyImports + +- Type: `boolean | string[]` +- Default: `true` + +Enables SWC's lazy import functionality, which is roughly equivalent to Metro's `inlineRequires`. You can also provide an allowlist of module names. See [SWC documentation](https://swc.rs/docs/configuration/modules#lazy) for details on how to configure it. + +### babelOverrides + +- Type: `BabelOverrides` + +```ts +type BabelOverrides = import('@babel/core').TransformOptions +``` + +Additional Babel loader options applied on top of the loader's computed Babel configuration. For available fields, see [Babel Documentation](https://babeljs.io/docs/options). + +### swcOverrides + +- Type: `SwcOverrides` + +```ts +type SwcOverrides = import('@swc/core').Options +``` + +Additional SWC loader options applied on top of the loader's computed SWC configuration. For available fields, see [SWC Documentation](https://swc.rs/docs/configuration/swcrc). + +### hermesParserPath + +- Type: `string` + +Optional path to use for importing `hermes-parser`. By default, the path is obtained automatically. + +### hermesParserOverrides + +- Type: `HermesParserOverrides` +- Default: `{ babel: true, reactRuntimeTarget: '19' }` + +Overrides passed to `hermes-parser` when parsing non-TypeScript files. + +```ts +type HermesParserOverrides = { + babel?: boolean; + flow?: "all" | "detect"; + reactRuntimeTarget?: "18" | "19"; + sourceType?: "module" | "script" | "unambiguous"; +}; +``` + +### hideParallelModeWarning + +- Type: `boolean` +- Default: `false` + +Hide the warning about Rspack `experiments.parallelLoader` when the rule isn't marked `parallel: true`. + +## Example + +```js title=rspack.config.mjs +export default { + module: { + rules: [ + { + test: /\.[cm]?[jt]sx?$/, + type: "javascript/auto", + use: { + loader: "@callstack/repack/babel-swc-loader", + parallel: true, + options: { + lazyImports: true, + }, + }, + }, + ], + }, +}; +``` +