Skip to content

Commit

Permalink
fix: let lightningcss minimizer inherit loader options (#4392)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan authored Jan 19, 2025
1 parent ba996d3 commit b9b4cfb
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 58 deletions.
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

1 comment on commit b9b4cfb

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Ran ecosystem CI: Open

suite result
modernjs ❌ failure
plugins ✅ success
rspress ✅ success
rslib ✅ success
examples ✅ success

Please sign in to comment.