diff --git a/README.md b/README.md index 5e166d9..6900f35 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ Compared to the previous approach, this method decouples the React Fast Refresh ### test - Type: [Rspack.RuleSetCondition](https://rspack.rs/config/module-rules#condition) -- Default: `undefined` +- Default: `/\.(?:js|jsx|mjs|cjs|ts|tsx|mts|cts)$/` Specifies which files should be processed by the React Refresh loader. This option is passed to the `builtin:react-refresh-loader` as the `rule.test` condition. @@ -104,7 +104,7 @@ new ReactRefreshPlugin({ ### include - Type: [Rspack.RuleSetCondition](https://rspack.rs/config/module-rules#condition) -- Default: `/\.(?:js|jsx|mjs|cjs|ts|tsx|mts|cts)$/` +- Default: `undefined` Explicitly includes files to be processed by the React Refresh loader. This option is passed to the `builtin:react-refresh-loader` as the `rule.include` condition. diff --git a/src/options.ts b/src/options.ts index 770c59b..6203c5f 100644 --- a/src/options.ts +++ b/src/options.ts @@ -5,6 +5,7 @@ export type PluginOptions = { * Specifies which files should be processed by the React Refresh loader. * This option is passed to the `builtin:react-refresh-loader` as the `rule.test` condition. * Works identically to Rspack's `rule.test` option. + * @default /\.(?:js|jsx|mjs|cjs|ts|tsx|mts|cts)$/ * @see https://rspack.rs/config/module-rules#rulestest */ test?: RuleSetCondition; @@ -13,7 +14,7 @@ export type PluginOptions = { * This option is passed to the `builtin:react-refresh-loader` as the `rule.include` condition. * Use this to limit processing to specific directories or file patterns. * Works identically to Rspack's `rule.include` option. - * @default /\.(?:js|jsx|mjs|cjs|ts|tsx|mts|cts)$/ + * @default undefined * @see https://rspack.rs/config/module-rules#rulesinclude */ include?: RuleSetCondition | null; @@ -93,8 +94,8 @@ const d = ( export function normalizeOptions( options: PluginOptions, ): NormalizedPluginOptions { + d(options, 'test', /\.(?:js|jsx|mjs|cjs|ts|tsx|mts|cts)$/); d(options, 'exclude', /node_modules/i); - d(options, 'include', /\.(?:js|jsx|mjs|cjs|ts|tsx|mts|cts)$/); d(options, 'library'); d(options, 'forceEnable', false); d(options, 'injectLoader', true); diff --git a/test/fixtures/include/index.js b/test/fixtures/include/index.js new file mode 100644 index 0000000..325598e --- /dev/null +++ b/test/fixtures/include/index.js @@ -0,0 +1,3 @@ +import './style.css'; + +export default 'include'; diff --git a/test/fixtures/include/style.css b/test/fixtures/include/style.css new file mode 100644 index 0000000..8579bef --- /dev/null +++ b/test/fixtures/include/style.css @@ -0,0 +1,3 @@ +.include { + color: red; +} diff --git a/test/test.spec.ts b/test/test.spec.ts index 8518255..8c66906 100644 --- a/test/test.spec.ts +++ b/test/test.spec.ts @@ -12,6 +12,7 @@ type Outputs = { fixture: string; runtime: string; vendor: string; + css?: string; }; type CompilationResult = { @@ -22,6 +23,10 @@ type CompilationResult = { }; const uniqueName = 'ReactRefreshLibrary'; +const readOutput = (fixturePath: string, file: string) => + fs.existsSync(path.join(fixturePath, 'dist', file)) + ? fs.readFileSync(path.join(fixturePath, 'dist', file), 'utf-8') + : ''; const compileWithReactRefresh = ( fixturePath: string, @@ -32,7 +37,9 @@ const compileWithReactRefresh = ( const cjsEntry = path.join(fixturePath, 'index.js'); const ctsEntry = path.join(fixturePath, 'index.cjs'); const mjsEntry = path.join(fixturePath, 'index.mjs'); - const customLoader = path.join(fixturePath, 'loader.cjs'); + const customLoader = fs.existsSync(path.join(fixturePath, 'loader.cjs')) + ? path.join(fixturePath, 'loader.cjs') + : path.join(import.meta.dirname, 'fixtures/loader/loader.cjs'); const entry = fs.existsSync(cjsEntry) ? cjsEntry : fs.existsSync(ctsEntry) @@ -52,6 +59,14 @@ const compileWithReactRefresh = ( uniqueName, assetModuleFilename: '[name][ext]', }, + module: { + rules: [ + { + test: /\.css$/, + type: 'css/auto', + }, + ], + }, resolveLoader: { alias: { 'custom-react-refresh-loader': customLoader, @@ -112,22 +127,11 @@ const compileWithReactRefresh = ( error, stats, outputs: { - reactRefresh: fs.readFileSync( - path.join(fixturePath, 'dist', 'react-refresh.js'), - 'utf-8', - ), - fixture: fs.readFileSync( - path.join(fixturePath, 'dist', 'fixture.js'), - 'utf-8', - ), - runtime: fs.readFileSync( - path.join(fixturePath, 'dist', 'runtime.js'), - 'utf-8', - ), - vendor: fs.readFileSync( - path.join(fixturePath, 'dist', 'vendor.js'), - 'utf-8', - ), + reactRefresh: readOutput(fixturePath, 'react-refresh.js'), + fixture: readOutput(fixturePath, 'fixture.js'), + runtime: readOutput(fixturePath, 'runtime.js'), + vendor: readOutput(fixturePath, 'vendor.js'), + css: readOutput(fixturePath, 'fixture.css') || undefined, }, plugin, }); @@ -301,4 +305,19 @@ describe('react-refresh-rspack-plugin', () => { expect(fixture).toContain('TEST_LOADER'); expect(fixture).not.toContain('function $RefreshReg$'); }); + + it('should keep the default extension filter when include targets a directory', async () => { + const { + outputs: { fixture, css }, + } = await compileWithReactRefresh( + path.join(import.meta.dirname, 'fixtures/include'), + { + include: path.join(import.meta.dirname, 'fixtures/include'), + reactRefreshLoader: 'custom-react-refresh-loader', + }, + ); + expect(fixture).toContain('TEST_LOADER'); + expect(css).toBeDefined(); + expect(css).not.toContain('TEST_LOADER'); + }); });