Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 19 additions & 21 deletions packages/core/src/configChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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',
Expand Down
54 changes: 30 additions & 24 deletions packages/core/src/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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'));
}
Expand All @@ -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<RspackChain.Rule>,
type: 'main' | 'inline',
) => void,
options: { skipMain?: boolean } = {},
) => {
if (!options.skipNormal) {
callback(rule, 'normal');
if (!options.skipMain) {
callback(mainRule, 'main');
}
callback(inlineRule, 'inline');
};
Expand Down Expand Up @@ -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 },
);
}

Expand Down Expand Up @@ -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 },
);
}

Expand Down Expand Up @@ -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
Expand Down
136 changes: 66 additions & 70 deletions packages/core/tests/__snapshots__/builder.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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": "<ROOT>/node_modules/<PNPM_INNER>/@rspack/core/dist/cssExtractLoader.js",
},
"oneOf": [
{
"loader": "<ROOT>/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": "<ROOT>/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": "<ROOT>/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": "<ROOT>/node_modules/<PNPM_INNER>/@rspack/core/dist/cssExtractLoader.js",
},
{
"loader": "<ROOT>/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": {
Expand Down
Loading
Loading