From cf56507dbfd41c4af63de511a320971668d5204f Mon Sep 17 00:00:00 2001 From: um Date: Thu, 18 Jan 2024 05:34:12 +0800 Subject: [PATCH] feat(plugin-legacy): add `modernTargets` option (#15506) Co-authored-by: bluwy --- packages/plugin-legacy/README.md | 13 ++++++++++++- packages/plugin-legacy/package.json | 1 + packages/plugin-legacy/src/index.ts | 21 +++++++++++++++++++-- packages/plugin-legacy/src/types.ts | 4 ++++ pnpm-lock.yaml | 18 +++++++++++++++++- 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/packages/plugin-legacy/README.md b/packages/plugin-legacy/README.md index 27f6f22e803be8..5e28fb32d63b75 100644 --- a/packages/plugin-legacy/README.md +++ b/packages/plugin-legacy/README.md @@ -40,12 +40,23 @@ npm add -D terser - **Type:** `string | string[] | { [key: string]: string }` - **Default:** [`'last 2 versions and not dead, > 0.3%, Firefox ESR'`](https://browsersl.ist/#q=last+2+versions+and+not+dead%2C+%3E+0.3%25%2C+Firefox+ESR) - If explicitly set, it's passed on to [`@babel/preset-env`](https://babeljs.io/docs/en/babel-preset-env#targets). + If explicitly set, it's passed on to [`@babel/preset-env`](https://babeljs.io/docs/en/babel-preset-env#targets) when rendering **legacy chunks**. The query is also [Browserslist compatible](https://github.com/browserslist/browserslist). See [Browserslist Best Practices](https://github.com/browserslist/browserslist#best-practices) for more details. If it's not set, plugin-legacy will load [the browserslist config sources](https://github.com/browserslist/browserslist#queries) and then fallback to the default value. +### `modernTargets` + +- **Type:** `string | string[]` +- **Default:** [`'edge>=80, firefox>=72, chrome>=80, safari>=13.1, chromeAndroid>=80, iOS>=13.1'`](https://browsersl.ist/#q=edge%3E%3D80%2C+firefox%3E%3D72%2C+chrome%3E%3D80%2C+safari%3E%3D13.1%2C+chromeAndroid%3E%3D80%2C+iOS%3E%3D13.1) + + If explicitly set, it's passed on to [`@babel/preset-env`](https://babeljs.io/docs/en/babel-preset-env#targets) when rendering **modern chunks**. + + The query is also [Browserslist compatible](https://github.com/browserslist/browserslist). See [Browserslist Best Practices](https://github.com/browserslist/browserslist#best-practices) for more details. + + If it's not set, plugin-legacy will fallback to the default value. + ### `polyfills` - **Type:** `boolean | string[]` diff --git a/packages/plugin-legacy/package.json b/packages/plugin-legacy/package.json index 2c400ea4d14993..13248cf94d73f2 100644 --- a/packages/plugin-legacy/package.json +++ b/packages/plugin-legacy/package.json @@ -45,6 +45,7 @@ "@babel/preset-env": "^7.23.8", "browserslist": "^4.22.2", "core-js": "^3.35.0", + "esbuild-plugin-browserslist": "^0.10.0", "magic-string": "^0.30.5", "regenerator-runtime": "^0.14.1", "systemjs": "^6.14.3" diff --git a/packages/plugin-legacy/src/index.ts b/packages/plugin-legacy/src/index.ts index 9495d868d71502..d7f0bb206547aa 100644 --- a/packages/plugin-legacy/src/index.ts +++ b/packages/plugin-legacy/src/index.ts @@ -24,6 +24,7 @@ import type { } from '@babel/core' import colors from 'picocolors' import browserslist from 'browserslist' +import { resolveToEsbuildTarget } from 'esbuild-plugin-browserslist' import type { Options } from './types' import { detectModernBrowserCode, @@ -125,6 +126,7 @@ const prefixedHashInFileNameRE = /\W?\[hash(:\d+)?\]/ function viteLegacyPlugin(options: Options = {}): Plugin[] { let config: ResolvedConfig let targets: Options['targets'] + let modernTargets: Options['modernTargets'] // browsers supporting ESM + dynamic import + import.meta + async generator const modernTargetsEsbuild = [ @@ -183,6 +185,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { } let overriddenBuildTarget = false + let overriddenDefaultModernTargets = false const legacyConfigPlugin: Plugin = { name: 'vite:legacy-config', @@ -205,7 +208,10 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { // Vite's default target browsers are **not** the same. // See https://github.com/vitejs/vite/pull/10052#issuecomment-1242076461 overriddenBuildTarget = config.build.target !== undefined - config.build.target = modernTargetsEsbuild + overriddenDefaultModernTargets = options.modernTargets !== undefined + config.build.target = options.modernTargets + ? resolveToEsbuildTarget(browserslist(options.modernTargets)) + : modernTargetsEsbuild } } @@ -226,6 +232,13 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { ), ) } + if (overriddenDefaultModernTargets) { + config.logger.warn( + colors.yellow( + `plugin-legacy 'modernTargets' option overrode the builtin targets of modern chunks. Some versions of browsers between legacy and modern may not be supported.`, + ), + ) + } }, } @@ -322,6 +335,10 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { 'last 2 versions and not dead, > 0.3%, Firefox ESR' isDebug && console.log(`[@vitejs/plugin-legacy] targets:`, targets) + modernTargets = options.modernTargets || modernTargetsBabel + isDebug && + console.log(`[@vitejs/plugin-legacy] modernTargets:`, modernTargets) + const getLegacyOutputFileName = ( fileNames: | string @@ -394,7 +411,7 @@ function viteLegacyPlugin(options: Options = {}): Plugin[] { genModern ) { // analyze and record modern polyfills - await detectPolyfills(raw, modernTargetsBabel, modernPolyfills) + await detectPolyfills(raw, modernTargets, modernPolyfills) } const ms = new MagicString(raw) diff --git a/packages/plugin-legacy/src/types.ts b/packages/plugin-legacy/src/types.ts index 954617d900d241..99e241c398c9eb 100644 --- a/packages/plugin-legacy/src/types.ts +++ b/packages/plugin-legacy/src/types.ts @@ -3,6 +3,10 @@ export interface Options { * default: 'defaults' */ targets?: string | string[] | { [key: string]: string } + /** + * default: 'edge>=80, firefox>=72, chrome>=80, safari>=13.1, chromeAndroid>=80, iOS>=13.1' + */ + modernTargets?: string | string[] /** * default: true */ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e4be54806e977b..66cfa9efcd4f3c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -207,6 +207,9 @@ importers: core-js: specifier: ^3.35.0 version: 3.35.0 + esbuild-plugin-browserslist: + specifier: ^0.10.0 + version: 0.10.0(browserslist@4.22.2) magic-string: specifier: ^0.30.5 version: 0.30.5 @@ -5633,6 +5636,20 @@ packages: ext: 1.6.0 dev: false + /esbuild-plugin-browserslist@0.10.0(browserslist@4.22.2): + resolution: {integrity: sha512-rZWFcp3l+73xDiJB+Vl9UqP1VVs+L4E0lygbwJl6UTmW2qQago7DLT56hBu0vocH/TtZsAcRHj0+qHqkkB5Gww==} + engines: {node: '>=18'} + peerDependencies: + browserslist: ^4.21.8 + esbuild: ~0.19.2 + dependencies: + browserslist: 4.22.2 + debug: 4.3.4 + zod: 3.21.4 + transitivePeerDependencies: + - supports-color + dev: false + /esbuild@0.18.20: resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} engines: {node: '>=12'} @@ -9619,7 +9636,6 @@ packages: /zod@3.21.4: resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} - dev: true file:playground/alias/dir/module: resolution: {directory: playground/alias/dir/module, type: directory}