From 4d5ba89d0cbbdd32dffdb5410b4e8d23192fdf9f Mon Sep 17 00:00:00 2001 From: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Date: Sat, 27 Jun 2026 00:30:07 +0000 Subject: [PATCH 1/4] fix asset query parity --- src/index.ts | 3 ++- tests/features.test.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 20a51df..b84d7d1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -128,7 +128,8 @@ const ensureFederationAsyncStartup = ( const cssUrlAssetExtensions = /\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)$/; -const urlAssetResourceQuery = /(?:\?|&)url(?:&|$)/; +const urlAssetResourceQuery = + /^(?=.*(?:\?|&)url(?:&|$))(?!.*(?:\?|&)(?:raw|inline)(?:&|$))/; export const pluginReactRouter = ( options: PluginOptions = {} diff --git a/tests/features.test.ts b/tests/features.test.ts index cd0744a..dbb0193 100644 --- a/tests/features.test.ts +++ b/tests/features.test.ts @@ -240,6 +240,14 @@ describe('pluginReactRouter', () => { const hasUrlAssetRule = (rule: any) => rule.resourceQuery?.toString().includes('url') && rule.exclude?.test('app/styles.css') && + rule.resourceQuery?.test('?url') && + rule.resourceQuery?.test('?foo=bar&url') && + !rule.resourceQuery?.test('?raw') && + !rule.resourceQuery?.test('?inline') && + !rule.resourceQuery?.test('?url&raw') && + !rule.resourceQuery?.test('?raw&url') && + !rule.resourceQuery?.test('?url&inline') && + !rule.resourceQuery?.test('?inline&url') && rule.type === 'asset/resource'; expect(getRules('web').some(hasUrlAssetRule)).toBe(true); From 645f03ae04104467fc8a0c77cafef297d516720b Mon Sep 17 00:00:00 2001 From: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Date: Sun, 28 Jun 2026 19:57:29 +0000 Subject: [PATCH 2/4] chore: simplify asset query parity test --- tests/features.test.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/features.test.ts b/tests/features.test.ts index dbb0193..85f7d48 100644 --- a/tests/features.test.ts +++ b/tests/features.test.ts @@ -237,17 +237,20 @@ describe('pluginReactRouter', () => { const config = await rsbuild.unwrapConfig(); const getRules = (name: 'web' | 'node') => config.environments?.[name]?.tools?.rspack?.module?.rules ?? []; + const includedQueries = ['?url', '?foo=bar&url']; + const excludedQueries = [ + '?raw', + '?inline', + '?url&raw', + '?raw&url', + '?url&inline', + '?inline&url', + ]; const hasUrlAssetRule = (rule: any) => rule.resourceQuery?.toString().includes('url') && rule.exclude?.test('app/styles.css') && - rule.resourceQuery?.test('?url') && - rule.resourceQuery?.test('?foo=bar&url') && - !rule.resourceQuery?.test('?raw') && - !rule.resourceQuery?.test('?inline') && - !rule.resourceQuery?.test('?url&raw') && - !rule.resourceQuery?.test('?raw&url') && - !rule.resourceQuery?.test('?url&inline') && - !rule.resourceQuery?.test('?inline&url') && + includedQueries.every(query => rule.resourceQuery?.test(query)) && + excludedQueries.every(query => !rule.resourceQuery?.test(query)) && rule.type === 'asset/resource'; expect(getRules('web').some(hasUrlAssetRule)).toBe(true); From d20c605571a36f06428b00848f0020b12945bdfe Mon Sep 17 00:00:00 2001 From: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Date: Mon, 29 Jun 2026 06:59:52 +0000 Subject: [PATCH 3/4] chore: add mixed asset query changeset --- .changeset/mixed-url-assets.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/mixed-url-assets.md diff --git a/.changeset/mixed-url-assets.md b/.changeset/mixed-url-assets.md new file mode 100644 index 0000000..91fffb5 --- /dev/null +++ b/.changeset/mixed-url-assets.md @@ -0,0 +1,5 @@ +--- +'rsbuild-plugin-react-router': patch +--- + +Preserve mixed asset query semantics for `?url&raw` and `?url&inline` requests. From 7e52300fc8a0e837f0d7f4badac3f2872f58e6de Mon Sep 17 00:00:00 2001 From: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Date: Mon, 29 Jun 2026 07:44:02 +0000 Subject: [PATCH 4/4] test: tighten asset query parity coverage --- tests/features.test.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/tests/features.test.ts b/tests/features.test.ts index 85f7d48..b7e2580 100644 --- a/tests/features.test.ts +++ b/tests/features.test.ts @@ -237,7 +237,7 @@ describe('pluginReactRouter', () => { const config = await rsbuild.unwrapConfig(); const getRules = (name: 'web' | 'node') => config.environments?.[name]?.tools?.rspack?.module?.rules ?? []; - const includedQueries = ['?url', '?foo=bar&url']; + const includedQueries = ['?url', '?url&foo=bar', '?foo=bar&url']; const excludedQueries = [ '?raw', '?inline', @@ -246,12 +246,22 @@ describe('pluginReactRouter', () => { '?url&inline', '?inline&url', ]; - const hasUrlAssetRule = (rule: any) => - rule.resourceQuery?.toString().includes('url') && - rule.exclude?.test('app/styles.css') && - includedQueries.every(query => rule.resourceQuery?.test(query)) && - excludedQueries.every(query => !rule.resourceQuery?.test(query)) && - rule.type === 'asset/resource'; + const hasUrlAssetRule = (rule: { + resourceQuery?: RegExp; + exclude?: RegExp; + type?: string; + }) => { + const { resourceQuery, exclude, type } = rule; + return ( + resourceQuery instanceof RegExp && + exclude instanceof RegExp && + resourceQuery.toString().includes('url') && + exclude.test('app/styles.css') && + includedQueries.every(query => resourceQuery.test(query)) && + excludedQueries.every(query => !resourceQuery.test(query)) && + type === 'asset/resource' + ); + }; expect(getRules('web').some(hasUrlAssetRule)).toBe(true); expect(getRules('node').some(hasUrlAssetRule)).toBe(true);