diff --git a/e2e/cases/css/css-minify-inherit/index.test.ts b/e2e/cases/css/css-minify-inherit/index.test.ts new file mode 100644 index 0000000000..a1116db921 --- /dev/null +++ b/e2e/cases/css/css-minify-inherit/index.test.ts @@ -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'); + }, +); diff --git a/e2e/cases/css/css-minify-inherit/rsbuild.config.ts b/e2e/cases/css/css-minify-inherit/rsbuild.config.ts new file mode 100644 index 0000000000..072811c1cf --- /dev/null +++ b/e2e/cases/css/css-minify-inherit/rsbuild.config.ts @@ -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, + }, + }, + }, +}); diff --git a/e2e/cases/css/css-minify-inherit/src/index.css b/e2e/cases/css/css-minify-inherit/src/index.css new file mode 100644 index 0000000000..ece212fed2 --- /dev/null +++ b/e2e/cases/css/css-minify-inherit/src/index.css @@ -0,0 +1,3 @@ +.foo { + margin-inline-end: 100px; +} diff --git a/e2e/cases/css/css-minify-inherit/src/index.js b/e2e/cases/css/css-minify-inherit/src/index.js new file mode 100644 index 0000000000..6a9a4b1328 --- /dev/null +++ b/e2e/cases/css/css-minify-inherit/src/index.js @@ -0,0 +1 @@ +import './index.css'; diff --git a/packages/core/src/plugins/css.ts b/packages/core/src/plugins/css.ts index cae8f7ec08..974871555a 100644 --- a/packages/core/src/plugins/css.ts +++ b/packages/core/src/plugins/css.ts @@ -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({ + 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`. @@ -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({ - 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({ diff --git a/packages/core/src/plugins/minimize.ts b/packages/core/src/plugins/minimize.ts index 1c8d967f7c..96e055d833 100644 --- a/packages/core/src/plugins/minimize.ts +++ b/packages/core/src/plugins/minimize.ts @@ -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, @@ -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', + ]), }, }; diff --git a/website/docs/en/config/output/minify.mdx b/website/docs/en/config/output/minify.mdx index f19781f2f2..862197d95b 100644 --- a/website/docs/en/config/output/minify.mdx +++ b/website/docs/en/config/output/minify.mdx @@ -7,9 +7,9 @@ type Minify = | boolean | { js?: boolean; - jsOptions?: SwcJsMinimizerRspackPluginOptions; + jsOptions?: Rspack.SwcJsMinimizerRspackPluginOptions; css?: boolean; - cssOptions?: LightningCssMinimizerRspackPluginOptions; + cssOptions?: Rspack.LightningcssMinimizerRspackPluginOptions; }; ``` @@ -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, @@ -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: { @@ -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: { @@ -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: { @@ -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. +::: diff --git a/website/docs/zh/config/output/minify.mdx b/website/docs/zh/config/output/minify.mdx index 75c9144cab..e20abdf699 100644 --- a/website/docs/zh/config/output/minify.mdx +++ b/website/docs/zh/config/output/minify.mdx @@ -7,9 +7,9 @@ type Minify = | boolean | { js?: boolean; - jsOptions?: SwcJsMinimizerRspackPluginOptions; + jsOptions?: Rspack.SwcJsMinimizerRspackPluginOptions; css?: boolean; - cssOptions?: LightningCssMinimizerRspackPluginOptions; + cssOptions?: Rspack.LightningcssMinimizerRspackPluginOptions; }; ``` @@ -19,18 +19,13 @@ type Minify = 默认情况下,JS 和 CSS 代码会在生产模式构建时被自动压缩,从而提升页面性能。如果你不希望执行代码压缩,可以将 `minify` 设置为 `false` 关闭对所有代码的压缩。或者可以通过 `minify` 选项的详细配置来控制代码压缩的行为。 -下面是各个字段的说明: - -- `js`: 是否开启对 JavaScript 代码的压缩。 -- `jsOptions`: JS 代码压缩配置,将会与默认配置合并传给 SWC。 -- `css`: 是否开启对 CSS 代码的压缩。 -- `cssOptions`: CSS 代码压缩配置,将会与默认配置合并传给 Lightning CSS。 - ## 示例 -### 禁用所有压缩 +### 禁用压缩 -```js +将 `minify` 设置为 `false` 可以禁用 JS 和 CSS 代码的压缩: + +```ts title="rsbuild.config.ts" export default { output: { minify: false, @@ -39,12 +34,21 @@ export default { ``` :::tip -该配置项通常用于代码调试和问题排查,不建议在生产模式禁用代码压缩,否则会导致页面性能显著下降。 +该用法通常用于代码调试和问题排查,不建议在生产模式禁用代码压缩,否则会导致页面性能显著下降。 ::: -### 禁用 JavaScript 压缩 +## 选项 + +### minify.js + +- **类型:** `boolean` +- **默认值:** `mode === 'production'` + +是否开启对 JavaScript 代码的压缩。 + +例如禁用 JavaScript 压缩: -```js +```ts title="rsbuild.config.ts" export default { output: { minify: { @@ -54,13 +58,16 @@ export default { }; ``` -### JavaScript 压缩选项 +### minify.jsOptions -`output.minify.jsOptions` 用于配置 SWC 的压缩选项,具体配置项请参考 [SwcJsMinimizerRspackPlugin 文档](https://rspack.dev/plugins/rspack/swc-js-minimizer-rspack-plugin)。 +- **类型:** `Rspack.SwcJsMinimizerRspackPluginOptions` +- **默认值:** `{}` + +`output.minify.jsOptions` 用于配置 SWC 的压缩选项,具体配置项请参考 [SwcJsMinimizerRspackPlugin 文档](https://rspack.dev/zh/plugins/rspack/swc-js-minimizer-rspack-plugin)。 例如,关闭变量和函数名的重命名: -```js +```ts title="rsbuild.config.ts" export default { output: { minify: { @@ -76,11 +83,35 @@ export default { > 参考 [配置 SWC](/guide/basic/configure-swc) 了解更多。 -### CSS 压缩选项 +### minify.css + +- **类型:** `boolean` +- **默认值:** `mode === 'production'` + +是否开启对 CSS 代码的压缩。 -`output.minify.cssOptions` 用于配置 Lightning CSS 的压缩选项,具体配置项请参考 [LightningCssMinimizerRspackPlugin 文档](https://rspack.dev/plugins/rspack/lightning-css-minimizer-rspack-plugin)。 +例如禁用 CSS 压缩: -```js +```ts title="rsbuild.config.ts" +export default { + output: { + minify: { + css: false, + }, + }, +}; +``` + +### minify.cssOptions + +- **类型:** `Rspack.LightningcssMinimizerRspackPluginOptions` +- **默认值:** 继承 [tools.lightningcssLoader](/config/tools/lightningcss-loader) 的值 + +`output.minify.cssOptions` 用于配置 Lightning CSS 的压缩选项,具体配置项请参考 [LightningCssMinimizerRspackPlugin 文档](https://rspack.dev/zh/plugins/rspack/lightning-css-minimizer-rspack-plugin)。 + +例如,关闭 `errorRecovery` 选项: + +```ts title="rsbuild.config.ts" export default { output: { minify: { @@ -93,3 +124,7 @@ export default { }, }; ``` + +:::tip +当你在 [tools.lightningcssLoader](/config/tools/lightningcss-loader) 中配置了一些选项时,`output.minify.cssOptions` 会自动继承这些选项,这样可以确保开发环境和生产环境的 CSS 代码转换行为保持一致。 +:::