From 4a73ff2aeb4e41199539fef5e968b7973e47d9aa Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Wed, 29 Sep 2021 15:19:18 +0800 Subject: [PATCH 1/3] feat: add `build.cssMinifyTarget` option fixes #4746 fixes #5070 --- docs/config/index.md | 11 +++++++++++ packages/playground/css/__tests__/css.spec.ts | 11 +++++++++++ packages/playground/css/main.js | 2 ++ packages/playground/css/minify.css | 3 +++ packages/playground/css/vite.config.js | 3 +++ packages/vite/src/node/build.ts | 14 ++++++++++++++ packages/vite/src/node/plugins/css.ts | 2 +- 7 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 packages/playground/css/minify.css diff --git a/docs/config/index.md b/docs/config/index.md index f53d9d51ad3fd9..6821c8b1a5b803 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -643,6 +643,17 @@ createServer() If disabled, all CSS in the entire project will be extracted into a single CSS file. +### build.cssMinifyTarget + +- **Type:** `string | string[]` +- **Default:** the same as [`build.target`](/config/#build-target) + + This options allows users to set a different browser target for CSS minification from the one used for JavaScript transpilation. + + It should only be used when you are targeting a non-mainstream browser. + One example is Android WeChat WebView, which supports most modern JavaScript features but not the [`#RGBA` hexadecimal color notation in CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgb_colors). + In this case, you need to set `build.cssMinifyTarget` to `chrome61` to prevent vite from transform `rgba()` colors into `#RGBA` hexadecimal notations. + ### build.sourcemap - **Type:** `boolean | 'inline' | 'hidden'` diff --git a/packages/playground/css/__tests__/css.spec.ts b/packages/playground/css/__tests__/css.spec.ts index ad5d9f344813e4..010f028a14ea82 100644 --- a/packages/playground/css/__tests__/css.spec.ts +++ b/packages/playground/css/__tests__/css.spec.ts @@ -338,3 +338,14 @@ test('inlined', async () => { // should not insert css expect(await getColor('.inlined')).toBe('black') }) + +test('minify css', async () => { + if (!isBuild) { + return + } + + // should keep the rgba() syntax + const cssFile = findAssetFile(/index\.\w+\.css$/) + expect(cssFile).toMatch('rgba(') + expect(cssFile).not.toMatch('#ffff00b3') +}) diff --git a/packages/playground/css/main.js b/packages/playground/css/main.js index cd2d6fda9ac0d5..24a278c8687940 100644 --- a/packages/playground/css/main.js +++ b/packages/playground/css/main.js @@ -1,3 +1,5 @@ +import './minify.css' + import css from './imported.css' text('.imported-css', css) diff --git a/packages/playground/css/minify.css b/packages/playground/css/minify.css new file mode 100644 index 00000000000000..ada062407cdb38 --- /dev/null +++ b/packages/playground/css/minify.css @@ -0,0 +1,3 @@ +.test-minify { + color: rgba(255, 255, 0, 0.7); +} diff --git a/packages/playground/css/vite.config.js b/packages/playground/css/vite.config.js index d49dcf4207834d..995f18674eab8a 100644 --- a/packages/playground/css/vite.config.js +++ b/packages/playground/css/vite.config.js @@ -3,6 +3,9 @@ const path = require('path') * @type {import('vite').UserConfig} */ module.exports = { + build: { + cssMinifyTarget: 'chrome61' + }, resolve: { alias: { '@': __dirname diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index f11046c97fec25..904e4da96ee10c 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -102,6 +102,15 @@ export interface BuildOptions { * @default true */ cssCodeSplit?: boolean + /** + * An optional separate target for CSS minification. + * As esbuild only supports configuring targets to mainstream + * browsers, users may need this option when they are targeting + * a niche browser that comes with most modern JavaScript features + * but has poor CSS support, e.g. Android WeChat WebView, which + * doesn't support the #RGBA syntax. + */ + cssMinifyTarget?: TransformOptions['target'] | false /** * If `true`, a separate sourcemap file will be created. If 'inline', the * sourcemap will be appended to the resulting output file as data URI. @@ -232,6 +241,7 @@ export function resolveBuildOptions(raw?: BuildOptions): ResolvedBuildOptions { assetsDir: 'assets', assetsInlineLimit: 4096, cssCodeSplit: !raw?.lib, + cssMinifyTarget: false, sourcemap: false, rollupOptions: {}, commonjsOptions: { @@ -275,6 +285,10 @@ export function resolveBuildOptions(raw?: BuildOptions): ResolvedBuildOptions { resolved.target = 'es2019' } + if (!resolved.cssMinifyTarget) { + resolved.cssMinifyTarget = resolved.target + } + // normalize false string into actual false if ((resolved.minify as any) === 'false') { resolved.minify = false diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index dd7366874d984b..03de00b9c6d443 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -906,7 +906,7 @@ async function minifyCSS(css: string, config: ResolvedConfig) { const { code, warnings } = await transform(css, { loader: 'css', minify: true, - target: config.build.target || undefined + target: config.build.cssMinifyTarget || undefined }) if (warnings.length) { const msgs = await formatMessages(warnings, { kind: 'warning' }) From 9f2707337da4f8cca748d681b61ac968b9cca341 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Wed, 29 Sep 2021 15:48:44 +0800 Subject: [PATCH 2/3] feat(plugin-legacy): set `build.cssMinifyTarget` fixes #4930 --- packages/plugin-legacy/index.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/plugin-legacy/index.js b/packages/plugin-legacy/index.js index a0a44499e34822..8c12bf804d2451 100644 --- a/packages/plugin-legacy/index.js +++ b/packages/plugin-legacy/index.js @@ -86,6 +86,15 @@ function viteLegacyPlugin(options = {}) { if (!config.build) { config.build = {} } + + if (!config.build.cssMinifyTarget) { + // Hint for esbuild that we are targeting legacy browsers when minifying CSS. + // Full CSS compat table available at https://github.com/evanw/esbuild/blob/78e04680228cf989bdd7d471e02bbc2c8d345dc9/internal/compat/css_table.go + // But note that only the `HexRGBA` feature affects the minify outcome. + // HSL & rebeccapurple values will be minified away regardless the target. + // So targeting `chrome61` suffices to fix the compatiblity issue. + config.build.cssMinifyTarget = 'chrome61' + } } } @@ -125,7 +134,7 @@ function viteLegacyPlugin(options = {}) { bundle, facadeToModernPolyfillMap, config.build, - options.externalSystemJS, + options.externalSystemJS ) return } @@ -156,7 +165,7 @@ function viteLegacyPlugin(options = {}) { // force using terser for legacy polyfill minification, since esbuild // isn't legacy-safe config.build, - options.externalSystemJS, + options.externalSystemJS ) } } From 1bd13247c24f896b76edeb2c96da25f4dd574002 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Wed, 29 Sep 2021 19:59:25 +0800 Subject: [PATCH 3/3] refactor: rename `cssMinifyTarget` to `cssTarget` --- docs/config/index.md | 4 ++-- packages/playground/css/vite.config.js | 2 +- packages/plugin-legacy/index.js | 4 ++-- packages/vite/src/node/build.ts | 8 ++++---- packages/vite/src/node/plugins/css.ts | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/config/index.md b/docs/config/index.md index 6821c8b1a5b803..5fe4de59fd1a93 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -643,7 +643,7 @@ createServer() If disabled, all CSS in the entire project will be extracted into a single CSS file. -### build.cssMinifyTarget +### build.cssTarget - **Type:** `string | string[]` - **Default:** the same as [`build.target`](/config/#build-target) @@ -652,7 +652,7 @@ createServer() It should only be used when you are targeting a non-mainstream browser. One example is Android WeChat WebView, which supports most modern JavaScript features but not the [`#RGBA` hexadecimal color notation in CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#rgb_colors). - In this case, you need to set `build.cssMinifyTarget` to `chrome61` to prevent vite from transform `rgba()` colors into `#RGBA` hexadecimal notations. + In this case, you need to set `build.cssTarget` to `chrome61` to prevent vite from transform `rgba()` colors into `#RGBA` hexadecimal notations. ### build.sourcemap diff --git a/packages/playground/css/vite.config.js b/packages/playground/css/vite.config.js index 995f18674eab8a..e4dc8d5a9f265f 100644 --- a/packages/playground/css/vite.config.js +++ b/packages/playground/css/vite.config.js @@ -4,7 +4,7 @@ const path = require('path') */ module.exports = { build: { - cssMinifyTarget: 'chrome61' + cssTarget: 'chrome61' }, resolve: { alias: { diff --git a/packages/plugin-legacy/index.js b/packages/plugin-legacy/index.js index 8c12bf804d2451..295fff9b95c4c3 100644 --- a/packages/plugin-legacy/index.js +++ b/packages/plugin-legacy/index.js @@ -87,13 +87,13 @@ function viteLegacyPlugin(options = {}) { config.build = {} } - if (!config.build.cssMinifyTarget) { + if (!config.build.cssTarget) { // Hint for esbuild that we are targeting legacy browsers when minifying CSS. // Full CSS compat table available at https://github.com/evanw/esbuild/blob/78e04680228cf989bdd7d471e02bbc2c8d345dc9/internal/compat/css_table.go // But note that only the `HexRGBA` feature affects the minify outcome. // HSL & rebeccapurple values will be minified away regardless the target. // So targeting `chrome61` suffices to fix the compatiblity issue. - config.build.cssMinifyTarget = 'chrome61' + config.build.cssTarget = 'chrome61' } } } diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 904e4da96ee10c..0d376ac13d8ec8 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -110,7 +110,7 @@ export interface BuildOptions { * but has poor CSS support, e.g. Android WeChat WebView, which * doesn't support the #RGBA syntax. */ - cssMinifyTarget?: TransformOptions['target'] | false + cssTarget?: TransformOptions['target'] | false /** * If `true`, a separate sourcemap file will be created. If 'inline', the * sourcemap will be appended to the resulting output file as data URI. @@ -241,7 +241,7 @@ export function resolveBuildOptions(raw?: BuildOptions): ResolvedBuildOptions { assetsDir: 'assets', assetsInlineLimit: 4096, cssCodeSplit: !raw?.lib, - cssMinifyTarget: false, + cssTarget: false, sourcemap: false, rollupOptions: {}, commonjsOptions: { @@ -285,8 +285,8 @@ export function resolveBuildOptions(raw?: BuildOptions): ResolvedBuildOptions { resolved.target = 'es2019' } - if (!resolved.cssMinifyTarget) { - resolved.cssMinifyTarget = resolved.target + if (!resolved.cssTarget) { + resolved.cssTarget = resolved.target } // normalize false string into actual false diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 03de00b9c6d443..1a62bf7f028d13 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -906,7 +906,7 @@ async function minifyCSS(css: string, config: ResolvedConfig) { const { code, warnings } = await transform(css, { loader: 'css', minify: true, - target: config.build.cssMinifyTarget || undefined + target: config.build.cssTarget || undefined }) if (warnings.length) { const msgs = await formatMessages(warnings, { kind: 'warning' })