diff --git a/e2e/cases/assets/import-json-raw-query/index.test.ts b/e2e/cases/assets/import-json-raw-query/index.test.ts new file mode 100644 index 0000000000..f246ba369a --- /dev/null +++ b/e2e/cases/assets/import-json-raw-query/index.test.ts @@ -0,0 +1,17 @@ +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; +import { expect, rspackTest } from '@e2e/helper'; + +rspackTest( + 'should import raw JSON with raw query', + async ({ page, buildPreview }) => { + await buildPreview(); + + expect(await page.evaluate('window.a')).toBe( + readFileSync(join(__dirname, './src/a.json'), 'utf-8'), + ); + expect(await page.evaluate('window.b')).toBe( + readFileSync(join(__dirname, './src/b.json'), 'utf-8'), + ); + }, +); diff --git a/e2e/cases/assets/import-json-raw-query/src/a.json b/e2e/cases/assets/import-json-raw-query/src/a.json new file mode 100644 index 0000000000..eeff5c2770 --- /dev/null +++ b/e2e/cases/assets/import-json-raw-query/src/a.json @@ -0,0 +1,4 @@ +{ + "foo": "bar", + "age": 1 +} diff --git a/e2e/cases/assets/import-json-raw-query/src/b.json b/e2e/cases/assets/import-json-raw-query/src/b.json new file mode 100644 index 0000000000..a82da11a91 --- /dev/null +++ b/e2e/cases/assets/import-json-raw-query/src/b.json @@ -0,0 +1,3 @@ +{ + "list": [1, 2] +} diff --git a/e2e/cases/assets/import-json-raw-query/src/index.js b/e2e/cases/assets/import-json-raw-query/src/index.js new file mode 100644 index 0000000000..f13aac462b --- /dev/null +++ b/e2e/cases/assets/import-json-raw-query/src/index.js @@ -0,0 +1,5 @@ +import a from './a.json?raw'; +import b from './b.json?raw'; + +window.a = a; +window.b = b; diff --git a/packages/compat/webpack/tests/__snapshots__/default.test.ts.snap b/packages/compat/webpack/tests/__snapshots__/default.test.ts.snap index b1d3a6245c..f3a8e81561 100644 --- a/packages/compat/webpack/tests/__snapshots__/default.test.ts.snap +++ b/packages/compat/webpack/tests/__snapshots__/default.test.ts.snap @@ -252,6 +252,15 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = ` ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": { @@ -631,6 +640,15 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when produ ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": { @@ -1009,6 +1027,15 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": { @@ -1375,6 +1402,15 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": { diff --git a/packages/core/src/configChain.ts b/packages/core/src/configChain.ts index 112baf8cac..729876c61c 100644 --- a/packages/core/src/configChain.ts +++ b/packages/core/src/configChain.ts @@ -34,6 +34,8 @@ export const CHAIN_ID = { MJS: 'mjs', /** Rule for fonts */ FONT: 'font', + /** Rule for JSON */ + JSON: 'json', /** Rule for images */ IMAGE: 'image', /** Rule for media */ diff --git a/packages/core/src/plugins/asset.ts b/packages/core/src/plugins/asset.ts index 402fab2f12..58c4e1c97a 100644 --- a/packages/core/src/plugins/asset.ts +++ b/packages/core/src/plugins/asset.ts @@ -57,11 +57,11 @@ const chainStaticAssetRule = ({ .type('asset/source') .resourceQuery(RAW_QUERY_REGEX); - // the asset will be inlined if fileSize < dataUrlCondition.maxSize rule .oneOf(`${assetType}-asset`) .type('asset') .parser({ + // asset will be inlined if file size < maxSize dataUrlCondition: { maxSize, }, @@ -144,6 +144,15 @@ export const pluginAsset = (): RsbuildPlugin => ({ // font createAssetRule(CHAIN_ID.RULE.FONT, FONT_EXTENSIONS, emitAssets); + // JSON + // Rspack has built-in rule for JSON, so we only need to handle imports with query + // get raw content: "foo.json?raw" + const rule = chain.module.rule(CHAIN_ID.RULE.JSON).test(/\.json$/i); + rule + .oneOf('json-asset-raw') + .type('asset/source') + .resourceQuery(RAW_QUERY_REGEX); + // assets const assetsFilename = getMergedFilename('assets'); chain.output.assetModuleFilename(assetsFilename); diff --git a/packages/core/tests/__snapshots__/asset.test.ts.snap b/packages/core/tests/__snapshots__/asset.test.ts.snap index 96a47f7c19..f558e6e132 100644 --- a/packages/core/tests/__snapshots__/asset.test.ts.snap +++ b/packages/core/tests/__snapshots__/asset.test.ts.snap @@ -128,6 +128,15 @@ exports[`plugin-asset > should add image rules correctly 1`] = ` ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, ], }, "output": { @@ -269,6 +278,15 @@ exports[`plugin-asset > should add image rules correctly 2`] = ` ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, ], }, "output": { @@ -410,6 +428,15 @@ exports[`plugin-asset > should allow to use distPath.image to modify dist path 1 ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, ], }, "output": { @@ -551,6 +578,15 @@ exports[`plugin-asset > should allow to use filename.image to modify filename 1` ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, ], }, "output": { diff --git a/packages/core/tests/__snapshots__/builder.test.ts.snap b/packages/core/tests/__snapshots__/builder.test.ts.snap index 3b9884aaeb..e76e4d14be 100644 --- a/packages/core/tests/__snapshots__/builder.test.ts.snap +++ b/packages/core/tests/__snapshots__/builder.test.ts.snap @@ -369,6 +369,15 @@ exports[`should use Rspack as the default bundler > apply Rspack correctly 1`] = ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": { diff --git a/packages/core/tests/__snapshots__/default.test.ts.snap b/packages/core/tests/__snapshots__/default.test.ts.snap index 6f952e4b95..b169e6ef9f 100644 --- a/packages/core/tests/__snapshots__/default.test.ts.snap +++ b/packages/core/tests/__snapshots__/default.test.ts.snap @@ -369,6 +369,15 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = ` ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": { @@ -884,6 +893,15 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when prod ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": { @@ -1386,6 +1404,15 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": { @@ -1859,6 +1886,15 @@ exports[`tools.rspack > should match snapshot 1`] = ` ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": { diff --git a/packages/core/tests/__snapshots__/environments.test.ts.snap b/packages/core/tests/__snapshots__/environments.test.ts.snap index 349dd306df..1a8f8ce7ef 100644 --- a/packages/core/tests/__snapshots__/environments.test.ts.snap +++ b/packages/core/tests/__snapshots__/environments.test.ts.snap @@ -1800,6 +1800,15 @@ exports[`environment config > tools.rspack / bundlerChain can be configured in e ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": { @@ -2219,6 +2228,15 @@ exports[`environment config > tools.rspack / bundlerChain can be configured in e ], "test": /\\\\\\.\\(\\?:woff\\|woff2\\|eot\\|ttf\\|otf\\|ttc\\)\\$/i, }, + { + "oneOf": [ + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + ], + "test": /\\\\\\.json\\$/i, + }, { "dependency": "url", "generator": {