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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,21 @@ new ReactRefreshPlugin({
});
```

### reactRefreshLoader

- Type: `string`
- Default: `builtin:react-refresh-loader`

Be default, the plugin uses `builtin:react-refresh-loader` loader implementation [from Rspack](https://github.com/web-infra-dev/rspack/tree/main/crates/rspack_loader_react_refresh) in order ot inject
the React Refresh utilities into each module. `reactRefreshLoader` option allows to specify the loader, that implements
custom React Refresh instrumentation if needed.

```js
new ReactRefreshPlugin({
reactRefreshLoader: 'my-advanced-react-refresh-loader',
});
```

## Credits

Thanks to the [react-refresh-webpack-plugin](https://github.com/pmmmwh/react-refresh-webpack-plugin) created by [@pmmmwh](https://github.com/pmmmwh), which inspires implement this plugin.
Expand Down
4 changes: 1 addition & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ class ReactRefreshRspackPlugin {
return getRefreshRuntimePaths();
}

static loader = 'builtin:react-refresh-loader';

constructor(options: PluginOptions = {}) {
this.options = normalizeOptions(options);
}
Expand Down Expand Up @@ -104,7 +102,7 @@ class ReactRefreshRspackPlugin {
// React Refresh should not be injected for asset modules as they are static resources
not: ['url'],
},
use: ReactRefreshRspackPlugin.loader,
use: this.options.reactRefreshLoader,
});
}

Expand Down
6 changes: 6 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ export type PluginOptions = {
* @default false
*/
reloadOnRuntimeErrors?: boolean;
/**
* Allows to specify custom react-refresh loader
* @default "builtin:react-refresh-loader"
*/
reactRefreshLoader?: string;
};

export interface NormalizedPluginOptions extends Required<PluginOptions> {
Expand Down Expand Up @@ -135,6 +140,7 @@ export function normalizeOptions(
d(options, 'injectLoader', true);
d(options, 'injectEntry', true);
d(options, 'reloadOnRuntimeErrors', false);
d(options, 'reactRefreshLoader', 'builtin:react-refresh-loader');
options.overlay = normalizeOverlay(options.overlay);
return options as NormalizedPluginOptions;
}
11 changes: 10 additions & 1 deletion test/exports.spec.mts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import DefaultExport, { ReactRefreshRspackPlugin } from '../exports/index.mjs';

test('should allow to import from the package', () => {
expect(DefaultExport.loader).toBeTruthy();
const instance = new ReactRefreshRspackPlugin();
expect(instance.options.reactRefreshLoader).toBeTruthy();
});

test('should allow the default import from the package', () => {
const instance = new DefaultExport();
expect(instance.options.reactRefreshLoader).toBeTruthy();
});

test('default import picks the same plugin class', () => {
expect(DefaultExport).toEqual(ReactRefreshRspackPlugin);
});
3 changes: 2 additions & 1 deletion test/exports.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const DefaultExport = require('../exports/index.cjs');

test('should allow to require from the package', () => {
expect(DefaultExport.loader).toBeTruthy();
const instance = new DefaultExport();
expect(instance.options.reactRefreshLoader).toBeTruthy();
});
1 change: 1 addition & 0 deletions test/fixtures/loader/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('foo');
8 changes: 8 additions & 0 deletions test/fixtures/loader/loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = function customLoader(source, sourceMap) {
const callback = this.async();

const injected = `/** TEST_LOADER */`;
const result = `${source}\n${injected}`;

callback(null, result, sourceMap);
};
Loading