From b1504e4359b5d4f74026c62a1754aa92e9c181c8 Mon Sep 17 00:00:00 2001 From: fi3ework Date: Tue, 21 Oct 2025 15:32:35 +0800 Subject: [PATCH] fix: align esX browserslist expression to caniuse --- packages/core/src/utils/syntax.ts | 113 ++++++++---------- packages/core/tests/config.test.ts | 13 +- packages/core/tests/syntax.test.ts | 18 ++- tests/integration/cli/build/build.test.ts | 2 +- .../syntax/__fixtures__/src/index.ts | 4 +- .../syntax/__snapshots__/index.test.ts.snap | 64 +++++++++- tests/integration/syntax/index.test.ts | 2 + 7 files changed, 132 insertions(+), 84 deletions(-) diff --git a/packages/core/src/utils/syntax.ts b/packages/core/src/utils/syntax.ts index d4cf76fab..7a09e228b 100644 --- a/packages/core/src/utils/syntax.ts +++ b/packages/core/src/utils/syntax.ts @@ -40,11 +40,8 @@ const RSPACK_TARGET_UNLISTED_MODERN_ECMA_VERSIONS: EcmaScriptVersion[] = [ ] satisfies EcmaScriptVersion[]; /** - * The esX to browserslist mapping is transformed from esbuild: - * https://github.com/evanw/esbuild/blob/main/internal/compat/js_table.go - * It does not completely align with the browserslist query of Rsbuild now: + * The esX to browserslist mapping is transformed from * https://github.com/rspack-contrib/browserslist-to-es-version - * TODO: align with Rsbuild, we may should align with SWC */ export const ESX_TO_BROWSERSLIST: Record< FixedEcmaVersions, @@ -63,90 +60,84 @@ export const ESX_TO_BROWSERSLIST: Record< safari: '3.1.0', }, es6: { - chrome: '63.0.0', - edge: '79.0.0', - firefox: '67.0.0', - ios: '13.0.0', - node: '13.2.0', - opera: '50.0.0', - safari: '13.0.0', + chrome: '51.0.0', + edge: '15.0.0', + firefox: '54.0.0', + safari: '10.0.0', + opera: '38.0.0', + samsung: '5.0.0', }, es2015: { - chrome: '63.0.0', - edge: '79.0.0', - firefox: '67.0.0', - ios: '13.0.0', - node: '13.2.0', - opera: '50.0.0', - safari: '13.0.0', + chrome: '51.0.0', + edge: '15.0.0', + firefox: '54.0.0', + safari: '10.0.0', + opera: '38.0.0', + samsung: '5.0.0', }, es2016: { - chrome: '63.0.0', - edge: '79.0.0', - firefox: '67.0.0', - ios: '13.0.0', - node: '13.2.0', - opera: '50.0.0', - safari: '13.0.0', + chrome: '52.0.0', + edge: '15.0.0', + firefox: '54.0.0', + safari: '10.3.0', + opera: '39.0.0', + samsung: '6.2.0', }, es2017: { - chrome: '63.0.0', - edge: '79.0.0', - firefox: '67.0.0', - ios: '13.0.0', - node: '13.2.0', - opera: '50.0.0', - safari: '13.0.0', + chrome: '57.0.0', + edge: '15.0.0', + firefox: '54.0.0', + safari: '11.0.0', + opera: '44.0.0', + samsung: '6.2.0', }, es2018: { chrome: '64.0.0', edge: '79.0.0', firefox: '78.0.0', - ios: '16.4.0', - node: '13.2.0', - opera: '51.0.0', safari: '16.4.0', + opera: '51.0.0', + samsung: '8.2.0', }, es2019: { - chrome: '66.0.0', + chrome: '73.0.0', edge: '79.0.0', firefox: '78.0.0', - ios: '16.4.0', - node: '13.2.0', - opera: '53.0.0', - safari: '16.4.0', + safari: '17.0.0', + opera: '60.0.0', + samsung: '11.1.0', }, es2020: { - chrome: '91.0.0', - edge: '91.0.0', + chrome: '80.0.0', + edge: '80.0.0', firefox: '80.0.0', - ios: '16.4.0', - node: '16.1.0', - opera: '77.0.0', - safari: '16.4.0', + safari: '17.0.0', + opera: '67.0.0', + samsung: '13.0.0', }, es2021: { - chrome: '91.0.0', - edge: '91.0.0', + chrome: '85.0.0', + edge: '85.0.0', firefox: '80.0.0', - ios: '16.4.0', - node: '16.1.0', - opera: '77.0.0', - safari: '16.4.0', + safari: '17.0.0', + opera: '71.0.0', + samsung: '14.0.0', }, es2022: { - chrome: '91.0.0', + chrome: '94.0.0', + edge: '94.0.0', firefox: '93.0.0', - ios: '16.4.0', - node: '16.11.0', - safari: '16.4.0', + safari: '17.0.0', + opera: '80.0.0', + samsung: '17.0.0', }, es2023: { - chrome: '91.0.0', - firefox: '93.0.0', - ios: '16.4.0', - node: '16.11.0', - safari: '16.4.0', + chrome: '110.0.0', + edge: '110.0.0', + firefox: '115.0.0', + safari: '17.0.0', + opera: '96.0.0', + samsung: '21.0.0', }, es2024: calcEsnextBrowserslistByTarget, esnext: calcEsnextBrowserslistByTarget, diff --git a/packages/core/tests/config.test.ts b/packages/core/tests/config.test.ts index 194f164ae..b455f4af8 100644 --- a/packages/core/tests/config.test.ts +++ b/packages/core/tests/config.test.ts @@ -419,13 +419,12 @@ describe('syntax', () => { composedRsbuildConfig[0]!.config.output?.overrideBrowserslist, ).toMatchInlineSnapshot(` [ - "chrome >= 63.0.0", - "edge >= 79.0.0", - "firefox >= 67.0.0", - "ios >= 13.0.0", - "node >= 13.2.0", - "opera >= 50.0.0", - "safari >= 13.0.0", + "chrome >= 51.0.0", + "edge >= 15.0.0", + "firefox >= 54.0.0", + "safari >= 10.0.0", + "opera >= 38.0.0", + "samsung >= 5.0.0", ] `); }); diff --git a/packages/core/tests/syntax.test.ts b/packages/core/tests/syntax.test.ts index 9dd876bc2..37f3d5797 100644 --- a/packages/core/tests/syntax.test.ts +++ b/packages/core/tests/syntax.test.ts @@ -74,13 +74,12 @@ describe('transformSyntaxToBrowserslist', () => { transformSyntaxToBrowserslist('es2015', 'web'), ).toMatchInlineSnapshot(` [ - "chrome >= 63.0.0", - "edge >= 79.0.0", - "firefox >= 67.0.0", - "ios >= 13.0.0", - "node >= 13.2.0", - "opera >= 50.0.0", - "safari >= 13.0.0", + "chrome >= 51.0.0", + "edge >= 15.0.0", + "firefox >= 54.0.0", + "safari >= 10.0.0", + "opera >= 38.0.0", + "samsung >= 5.0.0", ] `); @@ -91,10 +90,9 @@ describe('transformSyntaxToBrowserslist', () => { "chrome >= 64.0.0", "edge >= 79.0.0", "firefox >= 78.0.0", - "ios >= 16.4.0", - "node >= 13.2.0", - "opera >= 51.0.0", "safari >= 16.4.0", + "opera >= 51.0.0", + "samsung >= 8.2.0", ] `); diff --git a/tests/integration/cli/build/build.test.ts b/tests/integration/cli/build/build.test.ts index 1f3be98f5..cdfd06e92 100644 --- a/tests/integration/cli/build/build.test.ts +++ b/tests/integration/cli/build/build.test.ts @@ -153,7 +153,7 @@ describe('build command', async () => { const files = await globContentJSON(path.join(fixturePath, 'dist')); expect(files).toMatchInlineSnapshot(` { - "/tests/integration/cli/build/no-config/dist/a/index.js": "const withoutConfig = 1000; + "/tests/integration/cli/build/no-config/dist/a/index.js": "var withoutConfig = 1000; export { withoutConfig }; ", } diff --git a/tests/integration/syntax/__fixtures__/src/index.ts b/tests/integration/syntax/__fixtures__/src/index.ts index 0edafff17..17f5cd20c 100644 --- a/tests/integration/syntax/__fixtures__/src/index.ts +++ b/tests/integration/syntax/__fixtures__/src/index.ts @@ -7,5 +7,7 @@ export class Foo { } export function foo(options: unknown = {}): void { - console.log(options); + const a = {}; + const b = { ...a, b: 1 }; + console.log(options, b); } diff --git a/tests/integration/syntax/__snapshots__/index.test.ts.snap b/tests/integration/syntax/__snapshots__/index.test.ts.snap index 298819e2e..603206fff 100644 --- a/tests/integration/syntax/__snapshots__/index.test.ts.snap +++ b/tests/integration/syntax/__snapshots__/index.test.ts.snap @@ -8,7 +8,12 @@ exports[`should downgrade class private method by default 1`] = ` #bar() {} } function foo(options = {}) { - console.log(options); + const a = {}; + const b = { + ...a, + b: 1 + }; + console.log(options, b); } export { Foo, foo }; " @@ -26,6 +31,48 @@ function _class_private_method_init(obj, privateSet) { _check_private_redeclaration(obj, privateSet); privateSet.add(obj); } +function _define_property(obj, key, value) { + if (key in obj) Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + else obj[key] = value; + return obj; +} +function _object_spread(target) { + for(var i = 1; i < arguments.length; i++){ + var source = null != arguments[i] ? arguments[i] : {}; + var ownKeys = Object.keys(source); + if ("function" == typeof Object.getOwnPropertySymbols) ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + ownKeys.forEach(function(key) { + _define_property(target, key, source[key]); + }); + } + return target; +} +function src_ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + if (enumerableOnly) symbols = symbols.filter(function(sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + keys.push.apply(keys, symbols); + } + return keys; +} +function _object_spread_props(target, source) { + source = null != source ? source : {}; + if (Object.getOwnPropertyDescriptors) Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + else src_ownKeys(Object(source)).forEach(function(key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + return target; +} var _bar = /*#__PURE__*/ new WeakSet(); class Foo { constructor(){ @@ -35,8 +82,12 @@ class Foo { } function bar() {} function foo() { - let options = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; - console.log(options); + var options = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; + var a = {}; + var b = _object_spread_props(_object_spread({}, a), { + b: 1 + }); + console.log(options, b); } export { Foo, foo }; " @@ -50,7 +101,12 @@ exports[`should downgrade class private method with output.syntax config 2`] = ` #bar() {} } function foo(options = {}) { - console.log(options); + const a = {}; + const b = { + ...a, + b: 1 + }; + console.log(options, b); } export { Foo, foo }; " diff --git a/tests/integration/syntax/index.test.ts b/tests/integration/syntax/index.test.ts index ac37c35ae..575177e50 100644 --- a/tests/integration/syntax/index.test.ts +++ b/tests/integration/syntax/index.test.ts @@ -18,9 +18,11 @@ test('should downgrade class private method with output.syntax config', async () expect(entries.esm0).toMatchSnapshot(); expect(entries.esm0).not.toContain('#bar'); + expect(entries.esm0).not.toContain('...a'); expect(entries.esm1).toMatchSnapshot(); expect(entries.esm1).toContain('#bar'); + expect(entries.esm1).toContain('...a'); expect(entries.cjs0).toContain('#bar'); expect(entries.cjs0).toContain('()=>{'); // test webpack runtime arrow function