Skip to content

fix: let lightningcss minimizer inherit loader options #4392

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 19, 2025
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
24 changes: 24 additions & 0 deletions e2e/cases/css/css-minify-inherit/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { build, dev, rspackOnlyTest } from '@e2e/helper';
import { expect } from '@playwright/test';

rspackOnlyTest(
'should let lightningcss minimizer inherit from tools.lightningcssLoader',
async ({ page }) => {
const cssIndex = join(__dirname, 'dist/static/css/index.css');

await dev({
cwd: __dirname,
page,
});
const devContent = await readFile(cssIndex, 'utf-8');
expect(devContent).toContain('margin-inline-end: 100px;');

await build({
cwd: __dirname,
});
const buildContent = await readFile(cssIndex, 'utf-8');
expect(buildContent).toContain('margin-inline-end:100px');
},
);
18 changes: 18 additions & 0 deletions e2e/cases/css/css-minify-inherit/rsbuild.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { defineConfig } from '@rsbuild/core';

export default defineConfig({
dev: {
writeToDisk: true,
},
output: {
filenameHash: false,
overrideBrowserslist: ['Chrome >= 53'],
},
tools: {
lightningcssLoader: {
exclude: {
logicalProperties: true,
},
},
},
});
3 changes: 3 additions & 0 deletions e2e/cases/css/css-minify-inherit/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.foo {
margin-inline-end: 100px;
}
1 change: 1 addition & 0 deletions e2e/cases/css/css-minify-inherit/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './index.css';
47 changes: 28 additions & 19 deletions packages/core/src/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,29 @@ const getCSSModulesLocalIdentName = (
? '[local]-[hash:base64:6]'
: '[path][name]__[local]-[hash:base64:6]');

export const getLightningCSSLoaderOptions = (
config: NormalizedEnvironmentConfig,
targets: string[],
): Rspack.LightningcssLoaderOptions => {
const userOptions =
typeof config.tools.lightningcssLoader === 'object'
? config.tools.lightningcssLoader
: {};

const initialOptions: Rspack.LightningcssLoaderOptions = {
targets,
};

if (config.mode === 'production' && config.output.injectStyles) {
initialOptions.minify = true;
}

return reduceConfigs<Rspack.LightningcssLoaderOptions>({
initial: initialOptions,
config: userOptions,
});
};

// If the target is not `web` and the modules option of css-loader is enabled,
// we must enable exportOnlyLocals to only exports the modules identifier mappings.
// Otherwise, the compiled CSS code may contain invalid code, such as `new URL`.
Expand Down Expand Up @@ -290,29 +313,15 @@ export const pluginCss = (): RsbuildPlugin => ({
) {
importLoaders++;

const userOptions =
config.tools.lightningcssLoader === true
? {}
: config.tools.lightningcssLoader;

const initialOptions: Rspack.LightningcssLoaderOptions = {
targets: environment.browserslist,
};

if (config.mode === 'production' && config.output.injectStyles) {
initialOptions.minify = true;
}

const loaderOptions =
reduceConfigs<Rspack.LightningcssLoaderOptions>({
initial: initialOptions,
config: userOptions,
});
const lightningcssOptions = getLightningCSSLoaderOptions(
config,
environment.browserslist,
);

rule
.use(CHAIN_ID.USE.LIGHTNINGCSS)
.loader('builtin:lightningcss-loader')
.options(loaderOptions);
.options(lightningcssOptions);
}

const postcssLoaderOptions = await getPostcssLoaderOptions({
Expand Down
23 changes: 22 additions & 1 deletion packages/core/src/plugins/minimize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import type {
} from '@rspack/core';
import { rspack } from '@rspack/core';
import deepmerge from 'deepmerge';
import { isPlainObject, pick } from '../helpers';
import type { NormalizedEnvironmentConfig, RsbuildPlugin } from '../types';
import { getLightningCSSLoaderOptions } from './css';

export const getSwcMinimizerOptions = (
config: NormalizedEnvironmentConfig,
Expand Down Expand Up @@ -111,9 +113,28 @@ export const pluginMinimize = (): RsbuildPlugin => ({
}

if (minifyCss && isRspack) {
const loaderOptions = getLightningCSSLoaderOptions(
config,
environment.browserslist,
);

const defaultOptions: LightningCssMinimizerRspackPluginOptions = {
// If user has configured `tools.lightningcssLoader` options,
// we should will use them as the default minimizer options.
// This helps to keep development and production consistent.
minimizerOptions: {
targets: environment.browserslist,
targets: isPlainObject(loaderOptions.targets)
? environment.browserslist
: loaderOptions.targets,
...pick(loaderOptions, [
'draft',
'include',
'exclude',
'nonStandard',
'pseudoClasses',
'unusedSymbols',
'errorRecovery',
]),
},
};

Expand Down
73 changes: 55 additions & 18 deletions website/docs/en/config/output/minify.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ type Minify =
| boolean
| {
js?: boolean;
jsOptions?: SwcJsMinimizerRspackPluginOptions;
jsOptions?: Rspack.SwcJsMinimizerRspackPluginOptions;
css?: boolean;
cssOptions?: LightningCssMinimizerRspackPluginOptions;
cssOptions?: Rspack.LightningcssMinimizerRspackPluginOptions;
};
```

Expand All @@ -19,18 +19,13 @@ Configure whether to enable code minification in production mode, or to configur

By default, JS and CSS code will be automatically minimized in production mode to improve page performance. If you do not want to minify the code, you can set `minify` to `false` to disable minification for all code. Alternatively, you can control the behavior of code minification through detailed configuration of the `minify` option. Below are detailed explanations for each configuration option:

Here are explanations for each field:

- `js`: Whether to enable minification for JavaScript code.
- `jsOptions`: JS code minification configuration, which will be merged with the default configuration and passed to SWC.
- `css`: Whether to enable minification for CSS code.
- `cssOptions`: CSS code minification configuration, which will be merged with the default configuration and passed to Lightning CSS.

## Example

### Disable all minification
### Disable minification

```js
Set `minify` to `false` to disable JS and CSS code minification:

```ts title="rsbuild.config.ts"
export default {
output: {
minify: false,
Expand All @@ -39,12 +34,21 @@ export default {
```

:::tip
This configuration is usually used for debugging and troubleshooting. It is not recommended to disable code minification in production builds, as it will significantly degrade the page performance.
This usage is usually used for debugging and troubleshooting. It is not recommended to disable code minification in production builds, as it will significantly degrade the page performance.
:::

### Disable JavaScript minification
## Options

### minify.js

- **Type:** `boolean`
- **Default:** `mode === 'production'`

Whether to enable minification for JavaScript code.

For example, disable JavaScript minification:

```js
```ts title="rsbuild.config.ts"
export default {
output: {
minify: {
Expand All @@ -54,11 +58,16 @@ export default {
};
```

### JavaScript minify options
### minify.jsOptions

- **Type:** `Rspack.SwcJsMinimizerRspackPluginOptions`
- **Default:** `{}`

`output.minify.jsOptions` is used to configure SWC's minification options. For detailed configurations, please refer to [SwcJsMinimizerRspackPlugin](https://rspack.dev/plugins/rspack/swc-js-minimizer-rspack-plugin). The following configuration will override the default settings, disable the mangle feature.

```js
For example, disable the mangle feature:

```ts title="rsbuild.config.ts"
export default {
output: {
minify: {
Expand All @@ -74,11 +83,35 @@ export default {

> Refer to [Configure SWC](/guide/basic/configure-swc) for more details.

### CSS minify options
### minify.css

- **Type:** `boolean`
- **Default:** `mode === 'production'`

Whether to enable minification for CSS code.

For example, disable CSS minification:

```ts title="rsbuild.config.ts"
export default {
output: {
minify: {
css: false,
},
},
};
```

### minify.cssOptions

- **Type:** `Rspack.LightningcssMinimizerRspackPluginOptions`
- **Default:** inherit from [tools.lightningcssLoader](/config/tools/lightningcss-loader)

`output.minify.cssOptions` is used to configure Lightning CSS's minification options. For specific configuration items, please refer to [LightningCssMinimizerRspackPlugin Documentation](https://rspack.dev/plugins/rspack/lightning-css-minimizer-rspack-plugin).

```js
For example, disable error recovery:

```ts title="rsbuild.config.ts"
export default {
output: {
minify: {
Expand All @@ -91,3 +124,7 @@ export default {
},
};
```

:::tip
When you configure some options in [tools.lightningcssLoader](/config/tools/lightningcss-loader), `output.minify.cssOptions` will automatically inherit these options, which ensures that the CSS code transformation behavior in the development build is consistent with that in the production build.
:::
Loading
Loading