Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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/babel-loader-resolve-loader-fallback-array.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@callstack/repack": patch
---

Fix `BabelPlugin` to set the `babel-loader` entry of `resolveLoader.fallback` as an array containing the resolved path, instead of a plain string. Rspack's resolver and downstream tools that consume the resolved loader config (e.g. `RSDoctor`) expect the value to be an array; a bare string triggered `Given napi value is not an array on NapiResolveOptions.fallback`. This still matches Rspack's `ResolveAlias` (`{ [x: string]: string | false | (string | false)[] }`) and Webpack's resolver loader fallback shape.
3 changes: 2 additions & 1 deletion packages/repack/src/plugins/BabelPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Compiler as RspackCompiler } from '@rspack/core';
import type { Compiler as WebpackCompiler } from 'webpack';

/**
* Plugin that adds babel-loader fallback to resolveLoader configuration.
* This ensures babel-loader can be resolved regardless of the package manager used,
Expand All @@ -18,7 +19,7 @@ export class BabelPlugin {
...compiler.options.resolveLoader,
fallback: {
...compiler.options.resolveLoader?.fallback,
'babel-loader': require.resolve('babel-loader'),
'babel-loader': [require.resolve('babel-loader')],
},
};
}
Expand Down
30 changes: 30 additions & 0 deletions packages/repack/src/plugins/__tests__/BabelPlugin.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Compiler } from '@rspack/core';
import { BabelPlugin } from '../BabelPlugin.js';

const compilerMock: { options: Compiler['options'] } = {
options: {} as Compiler['options'],
};

describe('BabelPlugin', () => {
it('sets resolveLoader.fallback[babel-loader] as an array entry', () => {
const pluginInstance = new BabelPlugin();
pluginInstance.apply(compilerMock as unknown as Compiler);

expect(compilerMock.options.resolveLoader?.fallback).toEqual({
'babel-loader': [expect.any(String)],
});
});

it('preserves existing record fallback entries', () => {
compilerMock.options.resolveLoader = {
fallback: { 'foo-loader': '/path/to/foo-loader' },
};
const pluginInstance = new BabelPlugin();
pluginInstance.apply(compilerMock as unknown as Compiler);

expect(compilerMock.options.resolveLoader.fallback).toEqual({
'foo-loader': '/path/to/foo-loader',
'babel-loader': [expect.any(String)],
});
});
});
Loading