From 70f638014a11260d79d8ebbf61507c455db2ab02 Mon Sep 17 00:00:00 2001 From: neverland Date: Sun, 25 Jan 2026 18:00:53 +0800 Subject: [PATCH] =?UTF-8?q?feat!:=20convert=20the=20built=E2=80=91in=20CSS?= =?UTF-8?q?=20rule=20to=20oneOf=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/configChain.ts | 40 +- packages/core/src/plugins/css.ts | 54 +- .../tests/__snapshots__/builder.test.ts.snap | 136 ++- .../core/tests/__snapshots__/css.test.ts.snap | 706 +++++++------ .../tests/__snapshots__/default.test.ts.snap | 518 +++++----- .../__snapshots__/environments.test.ts.snap | 250 +++-- packages/plugin-less/src/index.ts | 63 +- .../tests/__snapshots__/index.test.ts.snap | 962 +++++++++--------- packages/plugin-less/tests/index.test.ts | 6 +- packages/plugin-sass/src/index.ts | 69 +- .../tests/__snapshots__/index.test.ts.snap | 904 ++++++++-------- packages/plugin-sass/tests/index.test.ts | 6 +- packages/plugin-stylus/src/index.ts | 67 +- .../tests/__snapshots__/index.test.ts.snap | 324 +++--- packages/plugin-stylus/tests/index.test.ts | 2 +- 15 files changed, 2062 insertions(+), 2045 deletions(-) diff --git a/packages/core/src/configChain.ts b/packages/core/src/configChain.ts index c96c404a1f..3ff5ef08cd 100644 --- a/packages/core/src/configChain.ts +++ b/packages/core/src/configChain.ts @@ -42,38 +42,18 @@ export const CHAIN_ID = { MEDIA: 'media', /** Rule for additional assets */ ADDITIONAL_ASSETS: 'additional-assets', - /** Rule for js */ + /** Rule for JS */ JS: 'js', - /** Rule for raw js */ - JS_RAW: 'js-raw', /** Rule for data uri encoded javascript */ JS_DATA_URI: 'js-data-uri', - /** Rule for ts */ - TS: 'ts', /** Rule for CSS */ CSS: 'css', - /** Rule for raw CSS */ - CSS_RAW: 'css-raw', - /** Rule for inline CSS */ - CSS_INLINE: 'css-inline', /** Rule for Less */ LESS: 'less', - /** Rule for raw Less */ - LESS_RAW: 'less-raw', - /** Rule for inline Less */ - LESS_INLINE: 'less-inline', /** Rule for Sass */ SASS: 'sass', - /** Rule for raw Sass */ - SASS_RAW: 'sass-raw', - /** Rule for inline Sass */ - SASS_INLINE: 'sass-inline', /** Rule for stylus */ STYLUS: 'stylus', - /** Rule for raw stylus */ - STYLUS_RAW: 'stylus-raw', - /** Rule for inline stylus */ - STYLUS_INLINE: 'stylus-inline', /** Rule for svg */ SVG: 'svg', /** Rule for Vue */ @@ -85,8 +65,26 @@ export const CHAIN_ID = { }, /** Predefined rule groups */ ONE_OF: { + /** JS oneOf rules */ JS_MAIN: 'js-main', JS_RAW: 'js-raw', + /** CSS oneOf rules */ + CSS_MAIN: 'css-main', + CSS_RAW: 'css-raw', + CSS_INLINE: 'css-inline', + /** Less oneOf rules */ + LESS_MAIN: 'less-main', + LESS_RAW: 'less-raw', + LESS_INLINE: 'less-inline', + /** Sass oneOf rules */ + SASS_MAIN: 'sass-main', + SASS_RAW: 'sass-raw', + SASS_INLINE: 'sass-inline', + /** Stylus oneOf rules */ + STYLUS_MAIN: 'stylus-main', + STYLUS_RAW: 'stylus-raw', + STYLUS_INLINE: 'stylus-inline', + /** SVG oneOf rules */ SVG: 'svg', SVG_RAW: 'svg-asset-raw', SVG_URL: 'svg-asset-url', diff --git a/packages/core/src/plugins/css.ts b/packages/core/src/plugins/css.ts index 8f3fb1c588..2ada310cce 100644 --- a/packages/core/src/plugins/css.ts +++ b/packages/core/src/plugins/css.ts @@ -278,33 +278,33 @@ export const pluginCss = (): RsbuildPlugin => ({ chain, { target, isProd, CHAIN_ID, environment, environments }, ) => { - const rule = chain.module.rule(CHAIN_ID.RULE.CSS); - const inlineRule = chain.module.rule(CHAIN_ID.RULE.CSS_INLINE); + const cssRule = chain.module.rule(CHAIN_ID.RULE.CSS); const { config } = environment; - rule + cssRule .test(CSS_REGEX) - // specify type to allow enabling Rspack `experiments.css` - .type('javascript/auto') // When using `new URL('./path/to/foo.css', import.meta.url)`, // the module should be treated as an asset module rather than a JS module. - .dependency({ not: 'url' }) - // exclude `import './foo.css?raw'` and `import './foo.css?inline'` - .resourceQuery({ not: [RAW_QUERY_REGEX, INLINE_QUERY_REGEX] }); + .dependency({ not: 'url' }); // Support for `import inlineCss from "a.css?inline"` - inlineRule - .test(CSS_REGEX) + const inlineRule = cssRule + .oneOf(CHAIN_ID.ONE_OF.CSS_INLINE) .type('javascript/auto') .resourceQuery(INLINE_QUERY_REGEX); // Support for `import rawCss from "a.css?raw"` - chain.module - .rule(CHAIN_ID.RULE.CSS_RAW) - .test(CSS_REGEX) + cssRule + .oneOf(CHAIN_ID.ONE_OF.CSS_RAW) .type('asset/source') .resourceQuery(RAW_QUERY_REGEX); + // Default CSS handling + const mainRule = cssRule + .oneOf(CHAIN_ID.ONE_OF.CSS_MAIN) + // specify type for `CssExtractRspackPlugin` to work properly + .type('javascript/auto'); + const emitCss = config.output.emitCss ?? target === 'web'; // Create Rspack rule @@ -316,20 +316,20 @@ export const pluginCss = (): RsbuildPlugin => ({ initial: {}, config: config.tools.styleLoader, }); - rule + mainRule .use(CHAIN_ID.USE.STYLE) .loader(getCompiledPath('style-loader')) .options(styleLoaderOptions); } // use CssExtractRspackPlugin loader else { - rule + mainRule .use(CHAIN_ID.USE.MINI_CSS_EXTRACT) .loader(getCssExtractPlugin().loader) .options(config.tools.cssExtract.loaderOptions); } } else { - rule + mainRule .use(CHAIN_ID.USE.IGNORE_CSS) .loader(path.join(LOADER_PATH, 'ignoreCssLoader.mjs')); } @@ -342,11 +342,14 @@ export const pluginCss = (): RsbuildPlugin => ({ // Update the normal CSS rule and the inline CSS rule const updateRules = ( - callback: (rule: RspackChain.Rule, type: 'normal' | 'inline') => void, - options: { skipNormal?: boolean } = {}, + callback: ( + rule: RspackChain.Rule, + type: 'main' | 'inline', + ) => void, + options: { skipMain?: boolean } = {}, ) => { - if (!options.skipNormal) { - callback(rule, 'normal'); + if (!options.skipMain) { + callback(mainRule, 'main'); } callback(inlineRule, 'inline'); }; @@ -397,7 +400,7 @@ export const pluginCss = (): RsbuildPlugin => ({ .options(lightningcssOptions); }, // If emit CSS is disabled, skip lightningcss-loader to reduce performance overhead - { skipNormal: !emitCss }, + { skipMain: !emitCss }, ); } @@ -427,7 +430,7 @@ export const pluginCss = (): RsbuildPlugin => ({ .options(postcssLoaderOptions); }, // If emit CSS is disabled, skip postcss-loader to reduce performance overhead - { skipNormal: !emitCss }, + { skipMain: !emitCss }, ); } @@ -465,8 +468,11 @@ export const pluginCss = (): RsbuildPlugin => ({ }); const isStringExport = cssLoaderOptions.exportType === 'string'; - if (isStringExport && rule.uses.has(CHAIN_ID.USE.MINI_CSS_EXTRACT)) { - rule.uses.delete(CHAIN_ID.USE.MINI_CSS_EXTRACT); + if ( + isStringExport && + mainRule.uses.has(CHAIN_ID.USE.MINI_CSS_EXTRACT) + ) { + mainRule.uses.delete(CHAIN_ID.USE.MINI_CSS_EXTRACT); } // Apply CSS extract plugin if not using style-loader and emitCss is true diff --git a/packages/core/tests/__snapshots__/builder.test.ts.snap b/packages/core/tests/__snapshots__/builder.test.ts.snap index 62214fc88d..7c6894cb9c 100644 --- a/packages/core/tests/__snapshots__/builder.test.ts.snap +++ b/packages/core/tests/__snapshots__/builder.test.ts.snap @@ -38,86 +38,82 @@ exports[`should use Rspack as the default bundler > apply Rspack correctly 1`] = "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, + "oneOf": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 1, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, + "resolve": { + "preferRelative": true, }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 1, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - ], - }, - { - "resolve": { - "preferRelative": true, - }, - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 1, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 1, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, "test": /\\\\\\.css\\$/, - "type": "asset/source", }, { "dependency": { diff --git a/packages/core/tests/__snapshots__/css.test.ts.snap b/packages/core/tests/__snapshots__/css.test.ts.snap index 6246411333..a63bcf8535 100644 --- a/packages/core/tests/__snapshots__/css.test.ts.snap +++ b/packages/core/tests/__snapshots__/css.test.ts.snap @@ -8,86 +8,82 @@ exports[`plugin-css > should use custom cssModules rule when using output.cssMod "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 1, - "modules": { - "auto": [Function], - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, + "oneOf": [ { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 1, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, - ], - }, - { - "resolve": { - "preferRelative": true, - }, - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 1, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 1, + "modules": { + "auto": [Function], + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, "test": /\\\\\\.css\\$/, - "type": "asset/source", }, ], }, @@ -114,53 +110,194 @@ exports[`plugin-css injectStyles > should apply ignoreCssLoader when injectStyle "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ + "oneOf": [ { - "loader": "/packages/core/src/ignoreCssLoader.mjs", + "resolve": { + "preferRelative": true, + }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 1, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "node >= 20", + ], + }, + }, + ], }, { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 0, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "exportOnlyLocals": true, - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + { + "resolve": { + "preferRelative": true, + }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/src/ignoreCssLoader.mjs", }, - "sourceMap": false, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 0, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "exportOnlyLocals": true, + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + ], + }, + ], + "test": /\\\\\\.css\\$/, + }, + ], + }, + "plugins": [ + { + "name": "RsbuildCorePlugin", + }, + ], +} +`; + +exports[`plugin-css injectStyles > should use css-loader + style-loader when injectStyles is true 1`] = ` +{ + "module": { + "rules": [ + { + "dependency": { + "not": "url", + }, + "oneOf": [ + { + "resolve": { + "preferRelative": true, }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 1, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], + }, + { + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", + }, + { + "resolve": { + "preferRelative": true, + }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/style-loader/index.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 1, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, ], + "test": /\\\\\\.css\\$/, }, + ], + }, + "plugins": [ + { + "name": "RsbuildCorePlugin", + }, + ], +} +`; + +exports[`should ensure isolation of PostCSS config objects between different builds 1`] = ` +[ + { + "dependency": { + "not": "url", + }, + "oneOf": [ { "resolve": { "preferRelative": true, }, "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, "sideEffects": true, - "test": /\\\\\\.css\\$/, "type": "javascript/auto", "use": [ { "loader": "/packages/core/compiled/css-loader/index.js", "options": { "exportType": "string", - "importLoaders": 1, + "importLoaders": 2, "modules": false, "sourceMap": false, }, @@ -170,55 +307,48 @@ exports[`plugin-css injectStyles > should apply ignoreCssLoader when injectStyle "options": { "errorRecovery": true, "targets": [ - "node >= 20", + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", ], }, }, + { + "loader": "/packages/core/compiled/postcss-loader/index.js", + "options": { + "implementation": "/packages/core/compiled/postcss/index.js", + "postcssOptions": { + "config": false, + "plugins": [ + { + "postcssPlugin": "foo", + }, + ], + }, + "sourceMap": false, + }, + }, ], }, { "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - "test": /\\\\\\.css\\$/, "type": "asset/source", }, - ], - }, - "plugins": [ - { - "name": "RsbuildCorePlugin", - }, - ], -} -`; - -exports[`plugin-css injectStyles > should use css-loader + style-loader when injectStyles is true 1`] = ` -{ - "module": { - "rules": [ { - "dependency": { - "not": "url", - }, "resolve": { "preferRelative": true, }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, "sideEffects": true, - "test": /\\\\\\.css\\$/, "type": "javascript/auto", "use": [ { - "loader": "/packages/core/compiled/style-loader/index.js", + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", }, { "loader": "/packages/core/compiled/css-loader/index.js", "options": { - "importLoaders": 1, + "importLoaders": 2, "modules": { "auto": true, "exportGlobals": false, @@ -241,22 +371,49 @@ exports[`plugin-css injectStyles > should use css-loader + style-loader when inj ], }, }, + { + "loader": "/packages/core/compiled/postcss-loader/index.js", + "options": { + "implementation": "/packages/core/compiled/postcss/index.js", + "postcssOptions": { + "config": false, + "plugins": [ + { + "postcssPlugin": "foo", + }, + ], + }, + "sourceMap": false, + }, + }, ], }, + ], + "test": /\\\\\\.css\\$/, + }, +] +`; + +exports[`should ensure isolation of PostCSS config objects between different builds 2`] = ` +[ + { + "dependency": { + "not": "url", + }, + "oneOf": [ { "resolve": { "preferRelative": true, }, "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, "sideEffects": true, - "test": /\\\\\\.css\\$/, "type": "javascript/auto", "use": [ { "loader": "/packages/core/compiled/css-loader/index.js", "options": { "exportType": "string", - "importLoaders": 1, + "importLoaders": 2, "modules": false, "sourceMap": false, }, @@ -273,259 +430,82 @@ exports[`plugin-css injectStyles > should use css-loader + style-loader when inj ], }, }, + { + "loader": "/packages/core/compiled/postcss-loader/index.js", + "options": { + "implementation": "/packages/core/compiled/postcss/index.js", + "postcssOptions": { + "config": false, + "plugins": [ + { + "postcssPlugin": "bar", + }, + ], + }, + "sourceMap": false, + }, + }, ], }, { "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - "test": /\\\\\\.css\\$/, "type": "asset/source", }, - ], - }, - "plugins": [ - { - "name": "RsbuildCorePlugin", - }, - ], -} -`; - -exports[`should ensure isolation of PostCSS config objects between different builds 1`] = ` -[ - { - "dependency": { - "not": "url", - }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 2, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, - }, - { - "loader": "/packages/core/compiled/postcss-loader/index.js", - "options": { - "implementation": "/packages/core/compiled/postcss/index.js", - "postcssOptions": { - "config": false, - "plugins": [ - { - "postcssPlugin": "foo", - }, - ], + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", }, - "sourceMap": false, - }, - }, - ], - }, - { - "resolve": { - "preferRelative": true, - }, - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 2, - "modules": false, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/core/compiled/postcss-loader/index.js", - "options": { - "implementation": "/packages/core/compiled/postcss/index.js", - "postcssOptions": { - "config": false, - "plugins": [ - { - "postcssPlugin": "foo", + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 2, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, }, - ], - }, - "sourceMap": false, - }, - }, - ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - "test": /\\\\\\.css\\$/, - "type": "asset/source", - }, -] -`; - -exports[`should ensure isolation of PostCSS config objects between different builds 2`] = ` -[ - { - "dependency": { - "not": "url", - }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 2, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, + "sourceMap": false, + }, }, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/core/compiled/postcss-loader/index.js", - "options": { - "implementation": "/packages/core/compiled/postcss/index.js", - "postcssOptions": { - "config": false, - "plugins": [ - { - "postcssPlugin": "bar", - }, - ], + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, }, - "sourceMap": false, - }, - }, - ], - }, - { - "resolve": { - "preferRelative": true, - }, - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 2, - "modules": false, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/core/compiled/postcss-loader/index.js", - "options": { - "implementation": "/packages/core/compiled/postcss/index.js", - "postcssOptions": { - "config": false, - "plugins": [ - { - "postcssPlugin": "bar", + { + "loader": "/packages/core/compiled/postcss-loader/index.js", + "options": { + "implementation": "/packages/core/compiled/postcss/index.js", + "postcssOptions": { + "config": false, + "plugins": [ + { + "postcssPlugin": "bar", + }, + ], }, - ], + "sourceMap": false, + }, }, - "sourceMap": false, - }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, "test": /\\\\\\.css\\$/, - "type": "asset/source", }, ] `; diff --git a/packages/core/tests/__snapshots__/default.test.ts.snap b/packages/core/tests/__snapshots__/default.test.ts.snap index f311d28d4e..1f8eb32259 100644 --- a/packages/core/tests/__snapshots__/default.test.ts.snap +++ b/packages/core/tests/__snapshots__/default.test.ts.snap @@ -38,86 +38,82 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = ` "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, + "oneOf": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 1, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 1, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, - ], - }, - { - "resolve": { - "preferRelative": true, - }, - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 1, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 1, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, "test": /\\\\\\.css\\$/, - "type": "asset/source", }, { "dependency": { @@ -549,87 +545,83 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when prod "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 1, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, + "oneOf": [ { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 1, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "minify": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, - ], - }, - { - "resolve": { - "preferRelative": true, - }, - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 1, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "minify": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 1, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, "test": /\\\\\\.css\\$/, - "type": "asset/source", }, { "dependency": { @@ -1081,72 +1073,68 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/packages/core/dist/ignoreCssLoader.mjs", - }, + "oneOf": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 0, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "exportOnlyLocals": true, - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, + "resolve": { + "preferRelative": true, }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 1, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "node >= 20", + ], + }, + }, + ], }, - ], - }, - { - "resolve": { - "preferRelative": true, - }, - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 1, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "node >= 20", - ], + "resolve": { + "preferRelative": true, }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/dist/ignoreCssLoader.mjs", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 0, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "exportOnlyLocals": true, + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, "test": /\\\\\\.css\\$/, - "type": "asset/source", }, { "dependency": { @@ -1536,86 +1524,82 @@ exports[`tools.rspack > should match snapshot 1`] = ` "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 1, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, + "oneOf": [ { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 1, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, - ], - }, - { - "resolve": { - "preferRelative": true, - }, - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 1, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 1, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, "test": /\\\\\\.css\\$/, - "type": "asset/source", }, { "dependency": { diff --git a/packages/core/tests/__snapshots__/environments.test.ts.snap b/packages/core/tests/__snapshots__/environments.test.ts.snap index f642a5db03..28a30bb4f5 100644 --- a/packages/core/tests/__snapshots__/environments.test.ts.snap +++ b/packages/core/tests/__snapshots__/environments.test.ts.snap @@ -1487,86 +1487,82 @@ exports[`environment config > tools.rspack / bundlerChain can be configured in e "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 1, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, + "oneOf": [ { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 1, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, - ], - }, - { - "resolve": { - "preferRelative": true, - }, - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 1, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 1, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, "test": /\\\\\\.css\\$/, - "type": "asset/source", }, { "dependency": { @@ -1934,75 +1930,71 @@ exports[`environment config > tools.rspack / bundlerChain can be configured in e "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ - { - "loader": "/packages/core/src/ignoreCssLoader.mjs", - }, + "oneOf": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 0, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "exportOnlyLocals": true, - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, + "resolve": { + "preferRelative": true, }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 1, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + ], }, - ], - }, - { - "resolve": { - "preferRelative": true, - }, - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.css\\$/, - "type": "javascript/auto", - "use": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 1, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "resolve": { + "preferRelative": true, }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/src/ignoreCssLoader.mjs", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 0, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "exportOnlyLocals": true, + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, "test": /\\\\\\.css\\$/, - "type": "asset/source", }, { "dependency": { diff --git a/packages/plugin-less/src/index.ts b/packages/plugin-less/src/index.ts index a58a11ad0c..a4301cabde 100644 --- a/packages/plugin-less/src/index.ts +++ b/packages/plugin-less/src/index.ts @@ -183,28 +183,32 @@ export const pluginLess = ( api.modifyBundlerChain((chain, { CHAIN_ID, environment }) => { const { config } = environment; + const cssRule = chain.module.rules.get(CHAIN_ID.RULE.CSS); const lessRule = chain.module .rule(findRuleId(chain, CHAIN_ID.RULE.LESS)) .test(include) + .dependency(cssRule.get('dependency')) .resolve.preferRelative(true) .end(); + const cssInlineRule = cssRule.oneOfs.get(CHAIN_ID.ONE_OF.CSS_INLINE); + const cssRawRule = cssRule.oneOfs.get(CHAIN_ID.ONE_OF.CSS_RAW); - // Rsbuild < 1.3.0 does not have the raw and inline rules - const inlineRule = CHAIN_ID.RULE.CSS_INLINE - ? chain.module - .rule(findRuleId(chain, CHAIN_ID.RULE.LESS_INLINE)) - .test(include) - : null; + // Inline Less for `?inline` imports + const lessInlineRule = lessRule + .oneOf(CHAIN_ID.ONE_OF.LESS_INLINE) + .type('javascript/auto') + .resourceQuery(cssInlineRule.get('resourceQuery')); - // Support for importing raw Less files - if (CHAIN_ID.RULE.CSS_RAW) { - const cssRawRule = chain.module.rules.get(CHAIN_ID.RULE.CSS_RAW); - chain.module - .rule(CHAIN_ID.RULE.LESS_RAW) - .test(include) - .type('asset/source') - .resourceQuery(cssRawRule.get('resourceQuery')); - } + // Raw Less for `?raw` imports + lessRule + .oneOf(CHAIN_ID.ONE_OF.LESS_RAW) + .type('asset/source') + .resourceQuery(cssRawRule.get('resourceQuery')); + + // Main Less transform + const lessMainRule = lessRule + .oneOf(CHAIN_ID.ONE_OF.LESS_MAIN) + .type('javascript/auto'); const { sourceMap } = config.output; const { excludes, options } = getLessLoaderOptions( @@ -213,15 +217,15 @@ export const pluginLess = ( api.context.rootPath, ); - // Update the normal rule and the inline rule + // Update the main rule and the inline rule const updateRules = ( - callback: (rule: RspackChain.Rule, type: 'normal' | 'inline') => void, + callback: ( + rule: RspackChain.Rule, + type: 'main' | 'inline', + ) => void, ) => { - callback(lessRule, 'normal'); - - if (inlineRule) { - callback(inlineRule, 'inline'); - } + callback(lessMainRule, 'main'); + callback(lessInlineRule, 'inline'); }; const lessLoaderPath = path.join( @@ -238,15 +242,16 @@ export const pluginLess = ( } // Copy the builtin CSS rules - const cssRule = chain.module.rules.get( - type === 'normal' ? CHAIN_ID.RULE.CSS : CHAIN_ID.RULE.CSS_INLINE, - ); + const cssBranchRule = + type === 'main' + ? cssRule.oneOfs.get(CHAIN_ID.ONE_OF.CSS_MAIN) + : cssInlineRule; rule.dependency(cssRule.get('dependency')); - rule.sideEffects(cssRule.get('sideEffects')); - rule.resourceQuery(cssRule.get('resourceQuery')); + rule.sideEffects(cssBranchRule.get('sideEffects')); + rule.resourceQuery(cssBranchRule.get('resourceQuery')); - for (const id of Object.keys(cssRule.uses.entries())) { - const loader = cssRule.uses.get(id); + for (const id of Object.keys(cssBranchRule.uses.entries())) { + const loader = cssBranchRule.uses.get(id); const options = loader.get('options') ?? {}; const clonedOptions = deepmerge>({}, options); diff --git a/packages/plugin-less/tests/__snapshots__/index.test.ts.snap b/packages/plugin-less/tests/__snapshots__/index.test.ts.snap index f1ef6041fc..cd4b7c562d 100644 --- a/packages/plugin-less/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-less/tests/__snapshots__/index.test.ts.snap @@ -6,107 +6,111 @@ exports[`plugin-less > should add less-loader 1`] = ` "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.less\\$/, - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 2, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, + "oneOf": [ { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/plugin-less/compiled/less-loader/index.js", - "options": { - "implementation": "/packages/plugin-less/compiled/less/index.js", - "lessOptions": { - "javascriptEnabled": true, - "paths": [ - "/node_modules", - ], - }, - "sourceMap": false, - }, - }, - ], - }, - { - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.less\\$/, - "use": [ - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 2, - "modules": false, - "sourceMap": false, + "dependency": { + "not": "url", }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 2, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-less/compiled/less-loader/index.js", + "options": { + "implementation": "/packages/plugin-less/compiled/less/index.js", + "lessOptions": { + "javascriptEnabled": true, + "paths": [ + "/node_modules", + ], + }, + "sourceMap": false, + }, + }, + ], }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "/packages/plugin-less/compiled/less-loader/index.js", - "options": { - "implementation": "/packages/plugin-less/compiled/less/index.js", - "lessOptions": { - "javascriptEnabled": true, - "paths": [ - "/node_modules", - ], - }, - "sourceMap": false, + "dependency": { + "not": "url", }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 2, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-less/compiled/less-loader/index.js", + "options": { + "implementation": "/packages/plugin-less/compiled/less/index.js", + "lessOptions": { + "javascriptEnabled": true, + "paths": [ + "/node_modules", + ], + }, + "sourceMap": false, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.less\\$/, - "type": "asset/source", }, ] `; @@ -117,107 +121,111 @@ exports[`plugin-less > should add less-loader and css-loader when injectStyles 1 "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.less\\$/, - "use": [ - { - "loader": "/packages/core/compiled/style-loader/index.js", - }, + "oneOf": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 2, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/plugin-less/compiled/less-loader/index.js", - "options": { - "implementation": "/packages/plugin-less/compiled/less/index.js", - "lessOptions": { - "javascriptEnabled": true, - "paths": [ - "/node_modules", - ], - }, - "sourceMap": false, - }, - }, - ], - }, - { - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.less\\$/, - "use": [ - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 2, - "modules": false, - "sourceMap": false, + "dependency": { + "not": "url", }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 2, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-less/compiled/less-loader/index.js", + "options": { + "implementation": "/packages/plugin-less/compiled/less/index.js", + "lessOptions": { + "javascriptEnabled": true, + "paths": [ + "/node_modules", + ], + }, + "sourceMap": false, + }, + }, + ], }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "/packages/plugin-less/compiled/less-loader/index.js", - "options": { - "implementation": "/packages/plugin-less/compiled/less/index.js", - "lessOptions": { - "javascriptEnabled": true, - "paths": [ - "/node_modules", - ], - }, - "sourceMap": false, + "dependency": { + "not": "url", }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/style-loader/index.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 2, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-less/compiled/less-loader/index.js", + "options": { + "implementation": "/packages/plugin-less/compiled/less/index.js", + "lessOptions": { + "javascriptEnabled": true, + "paths": [ + "/node_modules", + ], + }, + "sourceMap": false, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.less\\$/, - "type": "asset/source", }, ] `; @@ -228,113 +236,117 @@ exports[`plugin-less > should add less-loader with excludes 1`] = ` "dependency": { "not": "url", }, - "exclude": [ - /node_modules/, - ], - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.less\\$/, - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 2, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/plugin-less/compiled/less-loader/index.js", - "options": { - "implementation": "/packages/plugin-less/compiled/less/index.js", - "lessOptions": { - "javascriptEnabled": true, - "paths": [ - "/node_modules", - ], - }, - "sourceMap": false, - }, - }, - ], - }, - { - "exclude": [ - /node_modules/, - ], - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.less\\$/, - "use": [ + "oneOf": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 2, - "modules": false, - "sourceMap": false, + "dependency": { + "not": "url", }, + "exclude": [ + /node_modules/, + ], + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 2, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-less/compiled/less-loader/index.js", + "options": { + "implementation": "/packages/plugin-less/compiled/less/index.js", + "lessOptions": { + "javascriptEnabled": true, + "paths": [ + "/node_modules", + ], + }, + "sourceMap": false, + }, + }, + ], }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "/packages/plugin-less/compiled/less-loader/index.js", - "options": { - "implementation": "/packages/plugin-less/compiled/less/index.js", - "lessOptions": { - "javascriptEnabled": true, - "paths": [ - "/node_modules", - ], - }, - "sourceMap": false, + "dependency": { + "not": "url", }, + "exclude": [ + /node_modules/, + ], + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 2, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-less/compiled/less-loader/index.js", + "options": { + "implementation": "/packages/plugin-less/compiled/less/index.js", + "lessOptions": { + "javascriptEnabled": true, + "paths": [ + "/node_modules", + ], + }, + "sourceMap": false, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.less\\$/, - "type": "asset/source", }, ] `; @@ -345,107 +357,111 @@ exports[`plugin-less > should add less-loader with tools.less 1`] = ` "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.less\\$/, - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 2, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, + "oneOf": [ { - "loader": "/packages/plugin-less/compiled/less-loader/index.js", - "options": { - "implementation": "/packages/plugin-less/compiled/less/index.js", - "lessOptions": { - "javascriptEnabled": false, - "paths": [ - "/node_modules", - ], - }, - "sourceMap": false, + "dependency": { + "not": "url", }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 2, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-less/compiled/less-loader/index.js", + "options": { + "implementation": "/packages/plugin-less/compiled/less/index.js", + "lessOptions": { + "javascriptEnabled": false, + "paths": [ + "/node_modules", + ], + }, + "sourceMap": false, + }, + }, + ], }, - ], - }, - { - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.less\\$/, - "use": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 2, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/plugin-less/compiled/less-loader/index.js", - "options": { - "implementation": "/packages/plugin-less/compiled/less/index.js", - "lessOptions": { - "javascriptEnabled": false, - "paths": [ - "/node_modules", - ], - }, - "sourceMap": false, + "dependency": { + "not": "url", }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 2, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-less/compiled/less-loader/index.js", + "options": { + "implementation": "/packages/plugin-less/compiled/less/index.js", + "lessOptions": { + "javascriptEnabled": false, + "paths": [ + "/node_modules", + ], + }, + "sourceMap": false, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.less\\$/, - "type": "asset/source", }, ] `; @@ -456,121 +472,125 @@ exports[`plugin-less > should allow to use Less plugins 1`] = ` "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.less\\$/, - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 2, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, + "oneOf": [ { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "dependency": { + "not": "url", }, - }, - { - "loader": "/packages/plugin-less/compiled/less-loader/index.js", - "options": { - "implementation": "/packages/plugin-less/compiled/less/index.js", - "lessOptions": { - "javascriptEnabled": true, - "paths": [ - "/node_modules", - ], - "plugins": [ - MockPlugin { - "options": { - "foo": "bar", - }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 2, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-less/compiled/less-loader/index.js", + "options": { + "implementation": "/packages/plugin-less/compiled/less/index.js", + "lessOptions": { + "javascriptEnabled": true, + "paths": [ + "/node_modules", + ], + "plugins": [ + MockPlugin { + "options": { + "foo": "bar", + }, + }, + ], }, - ], + "sourceMap": false, + }, }, - "sourceMap": false, - }, + ], }, - ], - }, - { - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.less\\$/, - "use": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 2, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "dependency": { + "not": "url", }, - }, - { - "loader": "/packages/plugin-less/compiled/less-loader/index.js", - "options": { - "implementation": "/packages/plugin-less/compiled/less/index.js", - "lessOptions": { - "javascriptEnabled": true, - "paths": [ - "/node_modules", - ], - "plugins": [ - MockPlugin { - "options": { - "foo": "bar", - }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 2, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, }, - ], + "sourceMap": false, + }, }, - "sourceMap": false, - }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-less/compiled/less-loader/index.js", + "options": { + "implementation": "/packages/plugin-less/compiled/less/index.js", + "lessOptions": { + "javascriptEnabled": true, + "paths": [ + "/node_modules", + ], + "plugins": [ + MockPlugin { + "options": { + "foo": "bar", + }, + }, + ], + }, + "sourceMap": false, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.less\\$/, - "type": "asset/source", }, ] `; diff --git a/packages/plugin-less/tests/index.test.ts b/packages/plugin-less/tests/index.test.ts index 8f9551755d..53195591cf 100644 --- a/packages/plugin-less/tests/index.test.ts +++ b/packages/plugin-less/tests/index.test.ts @@ -108,8 +108,8 @@ describe('plugin-less', () => { }); const bundlerConfigs = await rsbuild.initConfigs(); - expect(matchRules(bundlerConfigs[0], 'a.less').length).toBe(2); - expect(matchRules(bundlerConfigs[0], 'b.less').length).toBe(5); + expect(matchRules(bundlerConfigs[0], 'a.less').length).toBe(1); + expect(matchRules(bundlerConfigs[0], 'b.less').length).toBe(2); }); it('should be compatible with Rsbuild < 1.3.0', async () => { @@ -136,7 +136,7 @@ describe('plugin-less', () => { await rsbuild.initConfigs(); const bundlerConfigs = await rsbuild.initConfigs(); - expect(matchRules(bundlerConfigs[0], 'a.less').length).toBe(2); + expect(matchRules(bundlerConfigs[0], 'a.less').length).toBe(1); expect(matchRules(bundlerConfigs[0], 'a.less?inline').length).toBe(0); }); }); diff --git a/packages/plugin-sass/src/index.ts b/packages/plugin-sass/src/index.ts index 144eb40b0b..b651ec992c 100644 --- a/packages/plugin-sass/src/index.ts +++ b/packages/plugin-sass/src/index.ts @@ -117,38 +117,42 @@ export const pluginSass = ( rewriteUrls ? true : isUseSourceMap, ); + const cssRule = chain.module.rules.get(CHAIN_ID.RULE.CSS); const rule = chain.module .rule(findRuleId(chain, CHAIN_ID.RULE.SASS)) .test(include) + .dependency(cssRule.get('dependency')) .resolve.preferRelative(true) .end(); - - // Rsbuild < 1.3.0 does not have the raw and inline rules - const inlineRule = CHAIN_ID.RULE.CSS_INLINE - ? chain.module - .rule(findRuleId(chain, CHAIN_ID.RULE.SASS_INLINE)) - .test(include) - : null; - - // Support for importing raw Sass files - if (CHAIN_ID.RULE.CSS_RAW) { - const cssRawRule = chain.module.rules.get(CHAIN_ID.RULE.CSS_RAW); - chain.module - .rule(CHAIN_ID.RULE.SASS_RAW) - .test(include) - .type('asset/source') - .resourceQuery(cssRawRule.get('resourceQuery')); - } - - // Update the normal rule and the inline rule + const cssInlineRule = cssRule.oneOfs.get(CHAIN_ID.ONE_OF.CSS_INLINE); + const cssRawRule = cssRule.oneOfs.get(CHAIN_ID.ONE_OF.CSS_RAW); + + // Inline Sass for `?inline` imports + const sassInlineRule = rule + .oneOf(CHAIN_ID.ONE_OF.SASS_INLINE) + .type('javascript/auto') + .resourceQuery(cssInlineRule.get('resourceQuery')); + + // Raw Sass for `?raw` imports + rule + .oneOf(CHAIN_ID.ONE_OF.SASS_RAW) + .type('asset/source') + .resourceQuery(cssRawRule.get('resourceQuery')); + + // Main Sass transform + const sassMainRule = rule + .oneOf(CHAIN_ID.ONE_OF.SASS_MAIN) + .type('javascript/auto'); + + // Update the main rule and the inline rule const updateRules = ( - callback: (rule: RspackChain.Rule, type: 'normal' | 'inline') => void, + callback: ( + rule: RspackChain.Rule, + type: 'main' | 'inline', + ) => void, ) => { - callback(rule, 'normal'); - - if (inlineRule) { - callback(inlineRule, 'inline'); - } + callback(sassMainRule, 'main'); + callback(sassInlineRule, 'inline'); }; const sassLoaderPath = path.join( @@ -178,15 +182,16 @@ export const pluginSass = ( } // Copy the builtin CSS rules - const cssRule = chain.module.rules.get( - type === 'normal' ? CHAIN_ID.RULE.CSS : CHAIN_ID.RULE.CSS_INLINE, - ); + const cssBranchRule = + type === 'main' + ? cssRule.oneOfs.get(CHAIN_ID.ONE_OF.CSS_MAIN) + : cssInlineRule; rule.dependency(cssRule.get('dependency')); - rule.sideEffects(cssRule.get('sideEffects')); - rule.resourceQuery(cssRule.get('resourceQuery')); + rule.sideEffects(cssBranchRule.get('sideEffects')); + rule.resourceQuery(cssBranchRule.get('resourceQuery')); - for (const id of Object.keys(cssRule.uses.entries())) { - const loader = cssRule.uses.get(id); + for (const id of Object.keys(cssBranchRule.uses.entries())) { + const loader = cssBranchRule.uses.get(id); const options = loader.get('options') ?? {}; const clonedOptions = deepmerge>({}, options); diff --git a/packages/plugin-sass/tests/__snapshots__/index.test.ts.snap b/packages/plugin-sass/tests/__snapshots__/index.test.ts.snap index fae1acae42..795683be6a 100644 --- a/packages/plugin-sass/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-sass/tests/__snapshots__/index.test.ts.snap @@ -6,123 +6,127 @@ exports[`plugin-sass > should add sass-loader 1`] = ` "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 3, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", - "options": { - "join": [Function], - "sourceMap": false, - }, - }, - { - "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", - "options": { - "api": "modern-compiler", - "implementation": "/node_modules//sass-embedded/dist/lib/index.js", - "sassOptions": { - "quietDeps": true, - "silenceDeprecations": [ - "import", - ], - }, - "sourceMap": true, - }, - }, - ], - }, - { - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "use": [ - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 3, - "modules": false, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, + "oneOf": [ + { + "dependency": { + "not": "url", + }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 3, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", + "options": { + "join": [Function], + "sourceMap": false, + }, + }, + { + "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", + "options": { + "api": "modern-compiler", + "implementation": "/node_modules//sass-embedded/dist/lib/index.js", + "sassOptions": { + "quietDeps": true, + "silenceDeprecations": [ + "import", + ], + }, + "sourceMap": true, + }, + }, + ], }, { - "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", - "options": { - "join": [Function], - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", - "options": { - "api": "modern-compiler", - "implementation": "/node_modules//sass-embedded/dist/lib/index.js", - "sassOptions": { - "quietDeps": true, - "silenceDeprecations": [ - "import", - ], - }, - "sourceMap": true, + "dependency": { + "not": "url", }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 3, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", + "options": { + "join": [Function], + "sourceMap": false, + }, + }, + { + "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", + "options": { + "api": "modern-compiler", + "implementation": "/node_modules//sass-embedded/dist/lib/index.js", + "sassOptions": { + "quietDeps": true, + "silenceDeprecations": [ + "import", + ], + }, + "sourceMap": true, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "type": "asset/source", }, ] `; @@ -133,123 +137,127 @@ exports[`plugin-sass > should add sass-loader and css-loader when injectStyles 1 "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "use": [ - { - "loader": "/packages/core/compiled/style-loader/index.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 3, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", - "options": { - "join": [Function], - "sourceMap": false, - }, - }, - { - "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", - "options": { - "api": "modern-compiler", - "implementation": "/node_modules//sass-embedded/dist/lib/index.js", - "sassOptions": { - "quietDeps": true, - "silenceDeprecations": [ - "import", - ], - }, - "sourceMap": true, - }, - }, - ], - }, - { - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "use": [ - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 3, - "modules": false, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, + "oneOf": [ + { + "dependency": { + "not": "url", + }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 3, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", + "options": { + "join": [Function], + "sourceMap": false, + }, + }, + { + "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", + "options": { + "api": "modern-compiler", + "implementation": "/node_modules//sass-embedded/dist/lib/index.js", + "sassOptions": { + "quietDeps": true, + "silenceDeprecations": [ + "import", + ], + }, + "sourceMap": true, + }, + }, + ], }, { - "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", - "options": { - "join": [Function], - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", - "options": { - "api": "modern-compiler", - "implementation": "/node_modules//sass-embedded/dist/lib/index.js", - "sassOptions": { - "quietDeps": true, - "silenceDeprecations": [ - "import", - ], - }, - "sourceMap": true, + "dependency": { + "not": "url", }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/style-loader/index.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 3, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", + "options": { + "join": [Function], + "sourceMap": false, + }, + }, + { + "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", + "options": { + "api": "modern-compiler", + "implementation": "/node_modules//sass-embedded/dist/lib/index.js", + "sassOptions": { + "quietDeps": true, + "silenceDeprecations": [ + "import", + ], + }, + "sourceMap": true, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "type": "asset/source", }, ] `; @@ -260,129 +268,133 @@ exports[`plugin-sass > should add sass-loader with excludes 1`] = ` "dependency": { "not": "url", }, - "exclude": [ - /node_modules/, - ], - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 3, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", - "options": { - "join": [Function], - "sourceMap": false, - }, - }, - { - "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", - "options": { - "api": "modern-compiler", - "implementation": "/node_modules//sass-embedded/dist/lib/index.js", - "sassOptions": { - "quietDeps": true, - "silenceDeprecations": [ - "import", - ], - }, - "sourceMap": true, - }, - }, - ], - }, - { - "exclude": [ - /node_modules/, - ], - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "use": [ - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 3, - "modules": false, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, + "oneOf": [ + { + "dependency": { + "not": "url", + }, + "exclude": [ + /node_modules/, + ], + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 3, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", + "options": { + "join": [Function], + "sourceMap": false, + }, + }, + { + "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", + "options": { + "api": "modern-compiler", + "implementation": "/node_modules//sass-embedded/dist/lib/index.js", + "sassOptions": { + "quietDeps": true, + "silenceDeprecations": [ + "import", + ], + }, + "sourceMap": true, + }, + }, + ], }, { - "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", - "options": { - "join": [Function], - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", - "options": { - "api": "modern-compiler", - "implementation": "/node_modules//sass-embedded/dist/lib/index.js", - "sassOptions": { - "quietDeps": true, - "silenceDeprecations": [ - "import", - ], - }, - "sourceMap": true, + "dependency": { + "not": "url", }, + "exclude": [ + /node_modules/, + ], + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 3, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", + "options": { + "join": [Function], + "sourceMap": false, + }, + }, + { + "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", + "options": { + "api": "modern-compiler", + "implementation": "/node_modules//sass-embedded/dist/lib/index.js", + "sassOptions": { + "quietDeps": true, + "silenceDeprecations": [ + "import", + ], + }, + "sourceMap": true, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "type": "asset/source", }, ] `; @@ -393,125 +405,129 @@ exports[`plugin-sass > should allow to use legacy API and mute deprecation warni "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 3, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", - "options": { - "join": [Function], - "sourceMap": false, - }, - }, - { - "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", - "options": { - "api": "legacy", - "implementation": "/node_modules//sass-embedded/dist/lib/index.js", - "sassOptions": { - "quietDeps": true, - "silenceDeprecations": [ - "import", - "legacy-js-api", - ], - }, - "sourceMap": true, - }, - }, - ], - }, - { - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "use": [ - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 3, - "modules": false, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, + "oneOf": [ + { + "dependency": { + "not": "url", + }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 3, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", + "options": { + "join": [Function], + "sourceMap": false, + }, + }, + { + "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", + "options": { + "api": "legacy", + "implementation": "/node_modules//sass-embedded/dist/lib/index.js", + "sassOptions": { + "quietDeps": true, + "silenceDeprecations": [ + "import", + "legacy-js-api", + ], + }, + "sourceMap": true, + }, + }, + ], }, { - "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", - "options": { - "join": [Function], - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", - "options": { - "api": "legacy", - "implementation": "/node_modules//sass-embedded/dist/lib/index.js", - "sassOptions": { - "quietDeps": true, - "silenceDeprecations": [ - "import", - "legacy-js-api", - ], - }, - "sourceMap": true, + "dependency": { + "not": "url", }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 3, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/packages/plugin-sass/compiled/resolve-url-loader/index.js", + "options": { + "join": [Function], + "sourceMap": false, + }, + }, + { + "loader": "/packages/plugin-sass/compiled/sass-loader/index.js", + "options": { + "api": "legacy", + "implementation": "/node_modules//sass-embedded/dist/lib/index.js", + "sassOptions": { + "quietDeps": true, + "silenceDeprecations": [ + "import", + "legacy-js-api", + ], + }, + "sourceMap": true, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.s\\(\\?:a\\|c\\)ss\\$/, - "type": "asset/source", }, ] `; diff --git a/packages/plugin-sass/tests/index.test.ts b/packages/plugin-sass/tests/index.test.ts index 71b91a15b5..81f72e30b3 100644 --- a/packages/plugin-sass/tests/index.test.ts +++ b/packages/plugin-sass/tests/index.test.ts @@ -77,8 +77,8 @@ describe('plugin-sass', () => { }); const bundlerConfigs = await rsbuild.initConfigs(); - expect(matchRules(bundlerConfigs[0], 'a.scss').length).toBe(2); - expect(matchRules(bundlerConfigs[0], 'b.scss').length).toBe(5); + expect(matchRules(bundlerConfigs[0], 'a.scss').length).toBe(1); + expect(matchRules(bundlerConfigs[0], 'b.scss').length).toBe(2); }); it('should be compatible with Rsbuild < 1.3.0', async () => { @@ -105,7 +105,7 @@ describe('plugin-sass', () => { await rsbuild.initConfigs(); const bundlerConfigs = await rsbuild.initConfigs(); - expect(matchRules(bundlerConfigs[0], 'a.scss').length).toBe(2); + expect(matchRules(bundlerConfigs[0], 'a.scss').length).toBe(1); expect(matchRules(bundlerConfigs[0], 'a.scss?inline').length).toBe(0); }); }); diff --git a/packages/plugin-stylus/src/index.ts b/packages/plugin-stylus/src/index.ts index 58d0c4b8f7..7fc1628884 100644 --- a/packages/plugin-stylus/src/index.ts +++ b/packages/plugin-stylus/src/index.ts @@ -86,49 +86,56 @@ export const pluginStylus = (options?: PluginStylusOptions): RsbuildPlugin => ({ const test = /\.styl(us)?$/; + const cssRule = chain.module.rules.get(CHAIN_ID.RULE.CSS); const rule = chain.module .rule(CHAIN_ID.RULE.STYLUS) .test(test) + .dependency(cssRule.get('dependency')) .resolve.preferRelative(true) .end(); - - // Rsbuild < 1.3.0 does not have the raw and inline rules - const inlineRule = CHAIN_ID.RULE.CSS_INLINE - ? chain.module.rule(CHAIN_ID.RULE.STYLUS_INLINE).test(test) - : null; - - // Support for importing raw Stylus files - if (CHAIN_ID.RULE.CSS_RAW) { - const cssRawRule = chain.module.rules.get(CHAIN_ID.RULE.CSS_RAW); - chain.module - .rule(CHAIN_ID.RULE.STYLUS_RAW) - .test(test) - .type('asset/source') - .resourceQuery(cssRawRule.get('resourceQuery')); - } - - // Update the normal rule and the inline rule + const cssInlineRule = cssRule.oneOfs.get(CHAIN_ID.ONE_OF.CSS_INLINE); + const cssRawRule = cssRule.oneOfs.get(CHAIN_ID.ONE_OF.CSS_RAW); + + // Inline Stylus for `?inline` imports + const stylusInlineRule = rule + .oneOf(CHAIN_ID.ONE_OF.STYLUS_INLINE) + .type('javascript/auto') + .resourceQuery(cssInlineRule.get('resourceQuery')); + + // Raw Stylus for `?raw` imports + rule + .oneOf(CHAIN_ID.ONE_OF.STYLUS_RAW) + .type('asset/source') + .resourceQuery(cssRawRule.get('resourceQuery')); + + // Main Stylus transform + const stylusMainRule = rule + .oneOf(CHAIN_ID.ONE_OF.STYLUS_MAIN) + .type('javascript/auto'); + + // Update the main rule and the inline rule const updateRules = ( - callback: (rule: RspackChain.Rule, type: 'normal' | 'inline') => void, + callback: ( + rule: RspackChain.Rule, + type: 'main' | 'inline', + ) => void, ) => { - callback(rule, 'normal'); - - if (inlineRule) { - callback(inlineRule, 'inline'); - } + callback(stylusMainRule, 'main'); + callback(stylusInlineRule, 'inline'); }; updateRules((rule, type) => { // Copy the builtin CSS rules - const cssRule = chain.module.rules.get( - type === 'normal' ? CHAIN_ID.RULE.CSS : CHAIN_ID.RULE.CSS_INLINE, - ); + const cssBranchRule = + type === 'main' + ? cssRule.oneOfs.get(CHAIN_ID.ONE_OF.CSS_MAIN) + : cssInlineRule; rule.dependency(cssRule.get('dependency')); - rule.sideEffects(cssRule.get('sideEffects')); - rule.resourceQuery(cssRule.get('resourceQuery')); + rule.sideEffects(cssBranchRule.get('sideEffects')); + rule.resourceQuery(cssBranchRule.get('resourceQuery')); - for (const id of Object.keys(cssRule.uses.entries())) { - const loader = cssRule.uses.get(id); + for (const id of Object.keys(cssBranchRule.uses.entries())) { + const loader = cssBranchRule.uses.get(id); const options = loader.get('options') ?? {}; const clonedOptions = deepmerge>({}, options); diff --git a/packages/plugin-stylus/tests/__snapshots__/index.test.ts.snap b/packages/plugin-stylus/tests/__snapshots__/index.test.ts.snap index 994ba3498c..ee27d477d7 100644 --- a/packages/plugin-stylus/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-stylus/tests/__snapshots__/index.test.ts.snap @@ -6,93 +6,97 @@ exports[`plugin-stylus > should add stylus loader config correctly 1`] = ` "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.styl\\(us\\)\\?\\$/, - "use": [ + "oneOf": [ { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 2, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, - }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/node_modules//stylus-loader/dist/cjs.js", - "options": { - "sourceMap": false, - }, - }, - ], - }, - { - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.styl\\(us\\)\\?\\$/, - "use": [ - { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 2, - "modules": false, - "sourceMap": false, + "dependency": { + "not": "url", }, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 2, + "modules": false, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/node_modules//stylus-loader/dist/cjs.js", + "options": { + "sourceMap": false, + }, + }, + ], }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "/node_modules//stylus-loader/dist/cjs.js", - "options": { - "sourceMap": false, + "dependency": { + "not": "url", }, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", + }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 2, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/node_modules//stylus-loader/dist/cjs.js", + "options": { + "sourceMap": false, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.styl\\(us\\)\\?\\$/, - "type": "asset/source", }, ] `; @@ -103,99 +107,103 @@ exports[`plugin-stylus > should allow to configure stylus options 1`] = ` "dependency": { "not": "url", }, - "resolve": { - "preferRelative": true, - }, - "resourceQuery": { - "not": [ - /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, - /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - ], - }, - "sideEffects": true, - "test": /\\\\\\.styl\\(us\\)\\?\\$/, - "use": [ - { - "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", - }, + "oneOf": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "importLoaders": 2, - "modules": { - "auto": true, - "exportGlobals": false, - "exportLocalsConvention": "camelCase", - "localIdentName": "[path][name]__[local]-[hash:base64:6]", - "namedExport": false, - }, - "sourceMap": false, + "dependency": { + "not": "url", }, - }, - { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], - }, - }, - { - "loader": "/node_modules//stylus-loader/dist/cjs.js", - "options": { - "sourceMap": false, - "stylusOptions": { - "lineNumbers": false, + "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "exportType": "string", + "importLoaders": 2, + "modules": false, + "sourceMap": false, + }, }, - }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/node_modules//stylus-loader/dist/cjs.js", + "options": { + "sourceMap": false, + "stylusOptions": { + "lineNumbers": false, + }, + }, + }, + ], }, - ], - }, - { - "resourceQuery": /\\[\\?&\\]inline\\(\\?:&\\|=\\|\\$\\)/, - "sideEffects": true, - "test": /\\\\\\.styl\\(us\\)\\?\\$/, - "use": [ { - "loader": "/packages/core/compiled/css-loader/index.js", - "options": { - "exportType": "string", - "importLoaders": 2, - "modules": false, - "sourceMap": false, - }, + "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "type": "asset/source", }, { - "loader": "builtin:lightningcss-loader", - "options": { - "errorRecovery": true, - "targets": [ - "chrome >= 107", - "edge >= 107", - "firefox >= 104", - "safari >= 16", - ], + "dependency": { + "not": "url", }, - }, - { - "loader": "/node_modules//stylus-loader/dist/cjs.js", - "options": { - "sourceMap": false, - "stylusOptions": { - "lineNumbers": false, + "sideEffects": true, + "type": "javascript/auto", + "use": [ + { + "loader": "/node_modules//@rspack/core/dist/cssExtractLoader.js", }, - }, + { + "loader": "/packages/core/compiled/css-loader/index.js", + "options": { + "importLoaders": 2, + "modules": { + "auto": true, + "exportGlobals": false, + "exportLocalsConvention": "camelCase", + "localIdentName": "[path][name]__[local]-[hash:base64:6]", + "namedExport": false, + }, + "sourceMap": false, + }, + }, + { + "loader": "builtin:lightningcss-loader", + "options": { + "errorRecovery": true, + "targets": [ + "chrome >= 107", + "edge >= 107", + "firefox >= 104", + "safari >= 16", + ], + }, + }, + { + "loader": "/node_modules//stylus-loader/dist/cjs.js", + "options": { + "sourceMap": false, + "stylusOptions": { + "lineNumbers": false, + }, + }, + }, + ], }, ], - }, - { - "resourceQuery": /\\[\\?&\\]raw\\(\\?:&\\|=\\|\\$\\)/, + "resolve": { + "preferRelative": true, + }, "test": /\\\\\\.styl\\(us\\)\\?\\$/, - "type": "asset/source", }, ] `; diff --git a/packages/plugin-stylus/tests/index.test.ts b/packages/plugin-stylus/tests/index.test.ts index 16c21e7e93..4be7d4d4c3 100644 --- a/packages/plugin-stylus/tests/index.test.ts +++ b/packages/plugin-stylus/tests/index.test.ts @@ -53,7 +53,7 @@ describe('plugin-stylus', () => { await rsbuild.initConfigs(); const bundlerConfigs = await rsbuild.initConfigs(); - expect(matchRules(bundlerConfigs[0], 'a.styl').length).toBe(2); + expect(matchRules(bundlerConfigs[0], 'a.styl').length).toBe(1); expect(matchRules(bundlerConfigs[0], 'a.styl?inline').length).toBe(0); }); });