From f22abba6056ea719c04ebf82902c282f38198812 Mon Sep 17 00:00:00 2001 From: neverland Date: Fri, 6 Sep 2024 14:02:38 +0800 Subject: [PATCH] fix: lightningcss-loader not work when using PostCSS (#3396) --- .../style-loader-lightningcss/index.test.ts | 27 +++++++++++++++++++ .../rsbuild.config.ts | 7 +++++ .../style-loader-lightningcss/src/index.css | 7 +++++ .../style-loader-lightningcss/src/index.js | 1 + .../tailwindcss-vendor-prefix/.browserslistrc | 2 ++ .../tailwindcss-vendor-prefix/index.test.ts | 20 ++++++++++++++ .../postcss.config.cjs | 9 +++++++ .../rsbuild.config.ts | 10 +++++++ .../tailwindcss-vendor-prefix/src/index.css | 1 + .../tailwindcss-vendor-prefix/src/index.html | 7 +++++ .../tailwindcss-vendor-prefix/src/index.ts | 1 + .../tailwind.config.cjs | 10 +++++++ .../tests/__snapshots__/default.test.ts.snap | 4 +++ packages/core/prebundle.config.mjs | 22 ++++++++++----- packages/core/src/plugins/css.ts | 1 + packages/core/src/types/thirdParty.ts | 5 ++++ .../tests/__snapshots__/builder.test.ts.snap | 1 + .../core/tests/__snapshots__/css.test.ts.snap | 5 ++++ .../tests/__snapshots__/default.test.ts.snap | 4 +++ .../__snapshots__/environments.test.ts.snap | 2 ++ .../tests/__snapshots__/index.test.ts.snap | 4 +++ .../tests/__snapshots__/index.test.ts.snap | 1 + .../tests/__snapshots__/index.test.ts.snap | 3 +++ .../tests/__snapshots__/index.test.ts.snap | 2 ++ 24 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 e2e/cases/css/style-loader-lightningcss/index.test.ts create mode 100644 e2e/cases/css/style-loader-lightningcss/rsbuild.config.ts create mode 100644 e2e/cases/css/style-loader-lightningcss/src/index.css create mode 100644 e2e/cases/css/style-loader-lightningcss/src/index.js create mode 100644 e2e/cases/css/tailwindcss-vendor-prefix/.browserslistrc create mode 100644 e2e/cases/css/tailwindcss-vendor-prefix/index.test.ts create mode 100644 e2e/cases/css/tailwindcss-vendor-prefix/postcss.config.cjs create mode 100644 e2e/cases/css/tailwindcss-vendor-prefix/rsbuild.config.ts create mode 100644 e2e/cases/css/tailwindcss-vendor-prefix/src/index.css create mode 100644 e2e/cases/css/tailwindcss-vendor-prefix/src/index.html create mode 100644 e2e/cases/css/tailwindcss-vendor-prefix/src/index.ts create mode 100644 e2e/cases/css/tailwindcss-vendor-prefix/tailwind.config.cjs diff --git a/e2e/cases/css/style-loader-lightningcss/index.test.ts b/e2e/cases/css/style-loader-lightningcss/index.test.ts new file mode 100644 index 0000000000..040eb9fd80 --- /dev/null +++ b/e2e/cases/css/style-loader-lightningcss/index.test.ts @@ -0,0 +1,27 @@ +import { build, rspackOnlyTest } from '@e2e/helper'; +import { expect } from '@playwright/test'; + +const fixtures = __dirname; + +rspackOnlyTest( + 'should use lightningcss-loader to transform and minify CSS when injectStyles is true', + async () => { + const rsbuild = await build({ + cwd: fixtures, + }); + + // injectStyles worked + const files = await rsbuild.unwrapOutputJSON(); + + // should inline minified css + const indexJsFile = Object.keys(files).find( + (file) => file.includes('index.') && file.endsWith('.js'), + )!; + + expect( + files[indexJsFile].includes( + '@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){.item{-webkit-user-select:none;user-select:none;background:linear-gradient(#fff,#000);transition:all .5s}}', + ), + ).toBeTruthy(); + }, +); diff --git a/e2e/cases/css/style-loader-lightningcss/rsbuild.config.ts b/e2e/cases/css/style-loader-lightningcss/rsbuild.config.ts new file mode 100644 index 0000000000..0d8884a67e --- /dev/null +++ b/e2e/cases/css/style-loader-lightningcss/rsbuild.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from '@rsbuild/core'; + +export default defineConfig({ + output: { + injectStyles: true, + }, +}); diff --git a/e2e/cases/css/style-loader-lightningcss/src/index.css b/e2e/cases/css/style-loader-lightningcss/src/index.css new file mode 100644 index 0000000000..f2b42a90bb --- /dev/null +++ b/e2e/cases/css/style-loader-lightningcss/src/index.css @@ -0,0 +1,7 @@ +@media (min-resolution: 2dppx) { + .item { + transition: all 0.5s; + user-select: none; + background: linear-gradient(to bottom, white, black); + } +} diff --git a/e2e/cases/css/style-loader-lightningcss/src/index.js b/e2e/cases/css/style-loader-lightningcss/src/index.js new file mode 100644 index 0000000000..6a9a4b1328 --- /dev/null +++ b/e2e/cases/css/style-loader-lightningcss/src/index.js @@ -0,0 +1 @@ +import './index.css'; diff --git a/e2e/cases/css/tailwindcss-vendor-prefix/.browserslistrc b/e2e/cases/css/tailwindcss-vendor-prefix/.browserslistrc new file mode 100644 index 0000000000..59fbd5b04d --- /dev/null +++ b/e2e/cases/css/tailwindcss-vendor-prefix/.browserslistrc @@ -0,0 +1,2 @@ +IE >= 11 +Chrome >= 10 diff --git a/e2e/cases/css/tailwindcss-vendor-prefix/index.test.ts b/e2e/cases/css/tailwindcss-vendor-prefix/index.test.ts new file mode 100644 index 0000000000..242880701e --- /dev/null +++ b/e2e/cases/css/tailwindcss-vendor-prefix/index.test.ts @@ -0,0 +1,20 @@ +import { build, rspackOnlyTest } from '@e2e/helper'; +import { expect } from '@playwright/test'; + +rspackOnlyTest( + 'should generate tailwindcss utilities with vendor prefixes correctly', + async () => { + const rsbuild = await build({ + cwd: __dirname, + }); + + const files = await rsbuild.unwrapOutputJSON(); + const indexCssFile = Object.keys(files).find( + (file) => file.includes('index.') && file.endsWith('.css'), + )!; + + expect(files[indexCssFile]).toContain('-webkit-user-select: none;'); + expect(files[indexCssFile]).toContain('-ms-user-select: none;'); + expect(files[indexCssFile]).toContain('user-select: none;'); + }, +); diff --git a/e2e/cases/css/tailwindcss-vendor-prefix/postcss.config.cjs b/e2e/cases/css/tailwindcss-vendor-prefix/postcss.config.cjs new file mode 100644 index 0000000000..efe50fc2f0 --- /dev/null +++ b/e2e/cases/css/tailwindcss-vendor-prefix/postcss.config.cjs @@ -0,0 +1,9 @@ +const path = require('node:path'); + +module.exports = { + plugins: { + tailwindcss: { + config: path.join(__dirname, './tailwind.config.cjs'), + }, + }, +}; diff --git a/e2e/cases/css/tailwindcss-vendor-prefix/rsbuild.config.ts b/e2e/cases/css/tailwindcss-vendor-prefix/rsbuild.config.ts new file mode 100644 index 0000000000..8858c3d3c7 --- /dev/null +++ b/e2e/cases/css/tailwindcss-vendor-prefix/rsbuild.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from '@rsbuild/core'; + +export default defineConfig({ + html: { + template: './src/index.html', + }, + output: { + minify: false, + }, +}); diff --git a/e2e/cases/css/tailwindcss-vendor-prefix/src/index.css b/e2e/cases/css/tailwindcss-vendor-prefix/src/index.css new file mode 100644 index 0000000000..65dd5f63a7 --- /dev/null +++ b/e2e/cases/css/tailwindcss-vendor-prefix/src/index.css @@ -0,0 +1 @@ +@tailwind utilities; diff --git a/e2e/cases/css/tailwindcss-vendor-prefix/src/index.html b/e2e/cases/css/tailwindcss-vendor-prefix/src/index.html new file mode 100644 index 0000000000..29c19a0013 --- /dev/null +++ b/e2e/cases/css/tailwindcss-vendor-prefix/src/index.html @@ -0,0 +1,7 @@ + + + + +

Hello world!

+ + diff --git a/e2e/cases/css/tailwindcss-vendor-prefix/src/index.ts b/e2e/cases/css/tailwindcss-vendor-prefix/src/index.ts new file mode 100644 index 0000000000..6a9a4b1328 --- /dev/null +++ b/e2e/cases/css/tailwindcss-vendor-prefix/src/index.ts @@ -0,0 +1 @@ +import './index.css'; diff --git a/e2e/cases/css/tailwindcss-vendor-prefix/tailwind.config.cjs b/e2e/cases/css/tailwindcss-vendor-prefix/tailwind.config.cjs new file mode 100644 index 0000000000..e03a0c3e05 --- /dev/null +++ b/e2e/cases/css/tailwindcss-vendor-prefix/tailwind.config.cjs @@ -0,0 +1,10 @@ +const path = require('node:path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [path.join(__dirname, './src/**/*.{html,js,ts,jsx,tsx}')], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/packages/compat/webpack/tests/__snapshots__/default.test.ts.snap b/packages/compat/webpack/tests/__snapshots__/default.test.ts.snap index 3ff421417a..019cc77dcd 100644 --- a/packages/compat/webpack/tests/__snapshots__/default.test.ts.snap +++ b/packages/compat/webpack/tests/__snapshots__/default.test.ts.snap @@ -56,6 +56,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 0, "modules": { "auto": true, @@ -418,6 +419,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when produ { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 0, "modules": { "auto": true, @@ -776,6 +778,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 0, "modules": { "auto": true, @@ -1081,6 +1084,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 0, "modules": { "auto": true, diff --git a/packages/core/prebundle.config.mjs b/packages/core/prebundle.config.mjs index f8508ac06e..81e519aeb9 100644 --- a/packages/core/prebundle.config.mjs +++ b/packages/core/prebundle.config.mjs @@ -5,13 +5,6 @@ import fs from 'node:fs'; */ import { join } from 'node:path'; -// The package size of `schema-utils` is large, and validate has a performance overhead of tens of ms. -// So we skip the validation and let TypeScript to ensure type safety. -const writeEmptySchemaUtils = (task) => { - const schemaUtilsPath = join(task.distPath, 'schema-utils.js'); - fs.writeFileSync(schemaUtilsPath, 'module.exports.validate = () => {};'); -}; - // postcss-loader and css-loader use `semver` to compare PostCSS ast version, // Rsbuild uses the same PostCSS version and do not need the comparison. const writeEmptySemver = (task) => { @@ -168,6 +161,21 @@ export default { postcss: '../postcss', picocolors: '../picocolors', }, + beforeBundle(task) { + // Temp fix for https://github.com/web-infra-dev/rspack/issues/7819 + replaceFileContent(join(task.depPath, 'dist/index.js'), (content) => + content.replaceAll( + 'if (meta) {', + 'if (meta && !rawOptions._skipReuseAST) {', + ), + ); + replaceFileContent(join(task.depPath, 'dist/index.js'), (content) => + content.replaceAll( + 'this.getOptions(_options.default)', + 'this.getOptions()', + ), + ); + }, afterBundle: writeEmptySemver, }, { diff --git a/packages/core/src/plugins/css.ts b/packages/core/src/plugins/css.ts index 5040b39854..84997c6555 100644 --- a/packages/core/src/plugins/css.ts +++ b/packages/core/src/plugins/css.ts @@ -173,6 +173,7 @@ const getCSSLoaderOptions = ({ localIdentName, }, sourceMap: config.output.sourceMap.css, + _skipReuseAST: config.tools.lightningcssLoader !== false, }; const mergedCssLoaderOptions = reduceConfigs({ diff --git a/packages/core/src/types/thirdParty.ts b/packages/core/src/types/thirdParty.ts index c0f9d0af23..caff45ba17 100644 --- a/packages/core/src/types/thirdParty.ts +++ b/packages/core/src/types/thirdParty.ts @@ -187,6 +187,11 @@ export interface CSSLoaderOptions { * @default 'array' */ exportType?: 'array' | 'string' | 'css-style-sheet'; + /** + * Temp fix for https://github.com/web-infra-dev/rspack/issues/7819 + * @private + */ + _skipReuseAST?: boolean; } export type StyleLoaderInjectType = diff --git a/packages/core/tests/__snapshots__/builder.test.ts.snap b/packages/core/tests/__snapshots__/builder.test.ts.snap index 5b29011bd1..190c541dc3 100644 --- a/packages/core/tests/__snapshots__/builder.test.ts.snap +++ b/packages/core/tests/__snapshots__/builder.test.ts.snap @@ -43,6 +43,7 @@ exports[`should use rspack as default bundler > apply rspack correctly 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 1, "modules": { "auto": true, diff --git a/packages/core/tests/__snapshots__/css.test.ts.snap b/packages/core/tests/__snapshots__/css.test.ts.snap index 3459c6a864..caf1d8f63a 100644 --- a/packages/core/tests/__snapshots__/css.test.ts.snap +++ b/packages/core/tests/__snapshots__/css.test.ts.snap @@ -18,6 +18,7 @@ exports[`plugin-css > should use custom cssModules rule when using output.cssMod { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 1, "modules": { "auto": [Function], @@ -68,6 +69,7 @@ exports[`plugin-css injectStyles > should apply ignoreCssLoader when injectStyle { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 0, "modules": { "auto": true, @@ -108,6 +110,7 @@ exports[`plugin-css injectStyles > should use css-loader + style-loader when inj { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 1, "modules": { "auto": true, @@ -156,6 +159,7 @@ exports[`should ensure isolation of PostCSS config objects between different bui { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 2, "modules": { "auto": true, @@ -214,6 +218,7 @@ exports[`should ensure isolation of PostCSS config objects between different bui { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 2, "modules": { "auto": true, diff --git a/packages/core/tests/__snapshots__/default.test.ts.snap b/packages/core/tests/__snapshots__/default.test.ts.snap index a7204b500f..4e8c356549 100644 --- a/packages/core/tests/__snapshots__/default.test.ts.snap +++ b/packages/core/tests/__snapshots__/default.test.ts.snap @@ -43,6 +43,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 1, "modules": { "auto": true, @@ -437,6 +438,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when prod { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 1, "modules": { "auto": true, @@ -893,6 +895,7 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 0, "modules": { "auto": true, @@ -1227,6 +1230,7 @@ exports[`tools.rspack > should match snapshot 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 1, "modules": { "auto": true, diff --git a/packages/core/tests/__snapshots__/environments.test.ts.snap b/packages/core/tests/__snapshots__/environments.test.ts.snap index 8163956c81..b36354bd55 100644 --- a/packages/core/tests/__snapshots__/environments.test.ts.snap +++ b/packages/core/tests/__snapshots__/environments.test.ts.snap @@ -1429,6 +1429,7 @@ exports[`environment config > tools.rspack / bundlerChain can be used in environ { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 1, "modules": { "auto": true, @@ -1770,6 +1771,7 @@ exports[`environment config > tools.rspack / bundlerChain can be used in environ { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 0, "modules": { "auto": true, diff --git a/packages/plugin-less/tests/__snapshots__/index.test.ts.snap b/packages/plugin-less/tests/__snapshots__/index.test.ts.snap index 4a3198c1e7..ab54022fd5 100644 --- a/packages/plugin-less/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-less/tests/__snapshots__/index.test.ts.snap @@ -15,6 +15,7 @@ exports[`plugin-less > should add less-loader 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 2, "modules": { "auto": true, @@ -70,6 +71,7 @@ exports[`plugin-less > should add less-loader and css-loader when injectStyles 1 { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 2, "modules": { "auto": true, @@ -128,6 +130,7 @@ exports[`plugin-less > should add less-loader with excludes 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 2, "modules": { "auto": true, @@ -183,6 +186,7 @@ exports[`plugin-less > should add less-loader with tools.less 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 2, "modules": { "auto": true, diff --git a/packages/plugin-react/tests/__snapshots__/index.test.ts.snap b/packages/plugin-react/tests/__snapshots__/index.test.ts.snap index 57b686f5a1..0d41ecd468 100644 --- a/packages/plugin-react/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-react/tests/__snapshots__/index.test.ts.snap @@ -58,6 +58,7 @@ exports[`plugins/react > should work with swc-loader 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 1, "modules": { "auto": true, diff --git a/packages/plugin-sass/tests/__snapshots__/index.test.ts.snap b/packages/plugin-sass/tests/__snapshots__/index.test.ts.snap index 9c8ca5c995..23a13f8707 100644 --- a/packages/plugin-sass/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-sass/tests/__snapshots__/index.test.ts.snap @@ -15,6 +15,7 @@ exports[`plugin-sass > should add sass-loader 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 3, "modules": { "auto": true, @@ -72,6 +73,7 @@ exports[`plugin-sass > should add sass-loader and css-loader when injectStyles 1 { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 3, "modules": { "auto": true, @@ -132,6 +134,7 @@ exports[`plugin-sass > should add sass-loader with excludes 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 3, "modules": { "auto": true, diff --git a/packages/plugin-stylus/tests/__snapshots__/index.test.ts.snap b/packages/plugin-stylus/tests/__snapshots__/index.test.ts.snap index 0058fb26cf..aeef0cbf81 100644 --- a/packages/plugin-stylus/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-stylus/tests/__snapshots__/index.test.ts.snap @@ -15,6 +15,7 @@ exports[`plugin-stylus > should add stylus loader config correctly 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 2, "modules": { "auto": true, @@ -63,6 +64,7 @@ exports[`plugin-stylus > should allow to configure stylus options 1`] = ` { "loader": "/packages/core/compiled/css-loader/index.js", "options": { + "_skipReuseAST": true, "importLoaders": 2, "modules": { "auto": true,