Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
bc0522f
feat: prototype of custom babel loader
jbroma May 14, 2025
03aba23
Merge remote-tracking branch 'origin/main' into feat/custom-babel-loader
jbroma May 14, 2025
3b892ba
chore: bump rspack to 1.3.10
jbroma May 14, 2025
0c4ed40
feat: preset
jbroma May 14, 2025
cd174f1
Merge remote-tracking branch 'origin/main' into feat/custom-babel-loader
jbroma Jul 2, 2025
53130db
chore: bump rspack
jbroma Jul 2, 2025
f7e8685
chore: ignore profiling mismatch
jbroma Jul 2, 2025
68617b2
chore: fix types
jbroma Jul 2, 2025
6dbba24
chore: improve types
jbroma Jul 2, 2025
75bfe4c
Merge remote-tracking branch 'origin/main' into feat/custom-babel-loader
jbroma Jul 24, 2025
3ddc702
Merge remote-tracking branch 'origin/main' into feat/custom-babel-loader
jbroma Jul 29, 2025
f959ea2
chore: update podfile locks
jbroma Jul 29, 2025
112c4be
chore: use babel loader in federation v2 tester
jbroma Jul 29, 2025
d69e19c
Merge remote-tracking branch 'origin/main' into feat/custom-babel-loader
jbroma Jul 30, 2025
028d987
feat: add module rules normalization
jbroma Jul 30, 2025
19b07fe
wip
jbroma Jul 30, 2025
ef8bc68
feat: working initial prototype
jbroma Jul 31, 2025
800e994
fix: disable broken rules
jbroma Jul 31, 2025
75ba138
chore: cleanup
jbroma Jul 31, 2025
f599486
feat: hybrid js loader
jbroma Aug 1, 2025
2514a34
feat: working rspack
jbroma Aug 1, 2025
cf91841
chore: update mini app config
jbroma Aug 1, 2025
3775286
chore: undo changes to getSwcLoaderOptions
jbroma Aug 4, 2025
2d058fd
chore: update comments
jbroma Aug 4, 2025
af59814
chore: revert changes in commands
jbroma Aug 4, 2025
9b0a65e
refactor: make parts more reusable
jbroma Aug 4, 2025
9f58fda
chore: add TODOs for 6.0
jbroma Aug 4, 2025
e218ed4
refactor: babel loader accepts babel transform options
jbroma Aug 4, 2025
9809ce0
refactor: align hybrid loader
jbroma Aug 4, 2025
99f06d1
feat: skip reaniamted loader when hybrid loader is found
jbroma Aug 4, 2025
9d27516
refactor: reuse isRspackCompiler
jbroma Aug 4, 2025
ae4d931
refactor: rename to swcConfigHelpers
jbroma Aug 4, 2025
b799315
refactor: add non-swc mode
jbroma Aug 4, 2025
9b9337d
refactor: rename to babel-swc-loader
jbroma Aug 4, 2025
0510872
chore: comment
jbroma Aug 4, 2025
d7e2fd1
feat: add disabled parallel mode warning
jbroma Aug 4, 2025
035e4c6
feat: add option to disable the warning
jbroma Aug 4, 2025
d7c80f6
fix: use babel resolved root as fallback
jbroma Aug 4, 2025
37b02d9
chore: align loaders in testers
jbroma Aug 4, 2025
8e4dc89
fix: tests
jbroma Aug 4, 2025
c111697
fix: sourcemaps settings
jbroma Aug 5, 2025
8cd37d5
feat: support multiple ways to obtain swc
jbroma Aug 6, 2025
95b534d
chore: use threaded-loader in tester-app
jbroma Aug 6, 2025
942ae61
chore: bump rspack/core & update lockfile
jbroma Aug 6, 2025
1fefd3a
chore: revert changes to isRspackCompiler
jbroma Aug 6, 2025
453d12d
chore: remove hermes-parser dependency
jbroma Aug 6, 2025
75a6ec4
refactor: safer checks & cleanup in loader
jbroma Aug 6, 2025
bcc1d7b
Merge remote-tracking branch 'origin/main' into feat/custom-babel-loader
jbroma Aug 7, 2025
a573063
chore: remove console logs
jbroma Aug 7, 2025
be35275
feat: proper error handling in both loaders
jbroma Aug 7, 2025
57cde01
feat: ignore repack deep imports
jbroma Aug 7, 2025
08c756d
feat: more customizable API
jbroma Aug 7, 2025
7c8233c
refactor: move swc helpers to babelSwcLoader
jbroma Aug 7, 2025
6c14046
feat: log warning in reanimated plugin and instruct users what to do
jbroma Aug 7, 2025
48059cf
chore: remove unused
jbroma Aug 7, 2025
5b30687
fix: display reanimated warning only once
jbroma Aug 7, 2025
071121f
wip: max workers
jbroma Aug 7, 2025
7cab5b9
Merge remote-tracking branch 'origin/main' into feat/custom-babel-loader
jbroma Aug 11, 2025
88068c6
test: add tests for exclude & include plugins functionality
jbroma Aug 11, 2025
95d8566
refactor: move to utils
jbroma Aug 11, 2025
62b545a
chore: comment
jbroma Aug 11, 2025
fe84d9e
tests: swc
jbroma Aug 11, 2025
56b67b7
tests: swc updated
jbroma Aug 11, 2025
523bfff
tests: babelSwcLoader
jbroma Aug 11, 2025
5af1a95
Merge remote-tracking branch 'origin/main' into feat/custom-babel-loader
jbroma Aug 18, 2025
80d2f4b
docs: docs for babel loader and babel swc loader
jbroma Aug 18, 2025
27fbe5f
docs: improve babel-swc-loader docs
jbroma Aug 18, 2025
0d41639
chore: cleanup
jbroma Aug 18, 2025
3514d37
chore: add changesets
jbroma Aug 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/clever-trams-grab.md
Original file line number Diff line number Diff line change
@@ -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.
6 changes: 6 additions & 0 deletions .changeset/dirty-cups-pick.md
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions .changeset/mighty-plums-shout.md
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion apps/tester-app/__tests__/configs/webpack.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default async (env) => {
path: process.env.TEST_WEBPACK_OUTPUT_DIR,
},
experiments: {
...config.output.experiments,
...config.experiments,
lazyCompilation: false,
},
};
Expand Down
8 changes: 2 additions & 6 deletions apps/tester-app/babel.config.js
Original file line number Diff line number Diff line change
@@ -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',
],
Expand Down
2 changes: 2 additions & 0 deletions apps/tester-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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:"
Expand Down
15 changes: 12 additions & 3 deletions apps/tester-app/rspack.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export default Repack.defineRspackConfig((env) => {
mode,
context,
entry: './index.js',
experiments: {
parallelLoader: true,
},
resolve: {
...Repack.getResolveOptions({ enablePackageExports: true }),
},
Expand All @@ -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')
Expand Down
2 changes: 1 addition & 1 deletion apps/tester-app/webpack.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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',
},
{
Expand Down
13 changes: 12 additions & 1 deletion apps/tester-federation-v2/configs/rspack.host-app.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export default Repack.defineRspackConfig((env) => {
mode,
context,
entry: './src/host/index.js',
experiments: {
parallelLoader: true,
},
resolve: {
...Repack.getResolveOptions({ enablePackageExports: true }),
},
Expand All @@ -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(),
],
},
Expand Down
13 changes: 12 additions & 1 deletion apps/tester-federation-v2/configs/rspack.mini-app.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export default Repack.defineRspackConfig((env) => {
mode,
context,
entry: './src/mini/index.js',
experiments: {
parallelLoader: true,
},
resolve: {
...Repack.getResolveOptions({ enablePackageExports: true }),
},
Expand All @@ -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 }),
],
},
Expand Down
2 changes: 1 addition & 1 deletion apps/tester-federation-v2/configs/webpack.host-app.mts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
2 changes: 1 addition & 1 deletion apps/tester-federation-v2/configs/webpack.mini-app.mts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }),
Expand Down
13 changes: 12 additions & 1 deletion apps/tester-federation/configs/rspack.host-app.mts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export default Repack.defineRspackConfig((env) => {
mode,
context,
entry: './src/host/index.js',
experiments: {
parallelLoader: true,
},
resolve: {
...Repack.getResolveOptions({ enablePackageExports: true }),
},
Expand All @@ -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(),
],
},
Expand Down
13 changes: 12 additions & 1 deletion apps/tester-federation/configs/rspack.mini-app.mts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export default Repack.defineRspackConfig((env) => {
mode,
context,
entry: './src/mini/index.js',
experiments: {
parallelLoader: true,
},
resolve: {
...Repack.getResolveOptions({ enablePackageExports: true }),
},
Expand All @@ -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 }),
],
},
Expand Down
2 changes: 1 addition & 1 deletion apps/tester-federation/configs/webpack.host-app.mts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
2 changes: 1 addition & 1 deletion apps/tester-federation/configs/webpack.mini-app.mts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }),
Expand Down
2 changes: 2 additions & 0 deletions packages/plugin-nativewind/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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') {
Expand Down
35 changes: 34 additions & 1 deletion packages/plugin-reanimated/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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<ReanimatedLoaderOptions>,
_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.'
);
}
}
}
}
1 change: 1 addition & 0 deletions packages/plugin-reanimated/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions packages/repack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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;"
`;
Loading