Skip to content

fix: do not transform esX for rspack.target field #237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion e2e/cases/shims/esm/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,23 @@ import { generateBundleEsmConfig } from '@e2e/helper';
import { defineConfig } from '@rslib/core';

export default defineConfig({
lib: [generateBundleEsmConfig()],
lib: [
generateBundleEsmConfig({
output: {
distPath: {
root: './dist/normal',
},
},
}),
generateBundleEsmConfig({
syntax: 'esnext',
output: {
distPath: {
root: './dist/with-syntax',
},
},
}),
],
output: {
target: 'node',
},
Expand Down
4 changes: 3 additions & 1 deletion e2e/cases/shims/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import { describe, expect, test } from 'vitest';
test('shims for __dirname and __filename in ESM', async () => {
const fixturePath = join(__dirname, 'esm');
const { entries } = await buildAndGetResults(fixturePath);

for (const shim of [
'import { fileURLToPath as __webpack_fileURLToPath__ } from "url";',
'var src_dirname = __webpack_dirname__(__webpack_fileURLToPath__(import.meta.url));',
'var src_filename = __webpack_fileURLToPath__(import.meta.url);',
// import.meta.url should not be substituted
'const importMetaUrl = import.meta.url;',
]) {
expect(entries.esm).toContain(shim);
expect(entries.esm0).toContain(shim);
}
expect(entries.esm0).toBe(entries.esm1);
});

describe('shims for `import.meta.url` in CJS', () => {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"test:e2e": "cd e2e && pnpm run test",
"test:unit": "vitest run --project unit*",
"test:unit:watch": "vitest --project unit*",
"testu": "pnpm run test:unit -u && pnpm run test:artifact -u",
"update:rsbuild": "npx taze minor --include /rsbuild/ -w -r -l",
"watch": "pnpm build --watch"
},
Expand Down
9 changes: 3 additions & 6 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { logger } from './utils/logger';
import {
ESX_TO_BROWSERSLIST,
transformSyntaxToBrowserslist,
transformSyntaxToRspackTarget,
} from './utils/syntax';
import { loadTsconfig } from './utils/tsconfig';

Expand Down Expand Up @@ -578,19 +579,15 @@ const composeSyntaxConfig = (
target?: RsbuildConfigOutputTarget,
): RsbuildConfig => {
// Defaults to ESNext, Rslib will assume all of the latest JavaScript and CSS features are supported.

if (syntax) {
const resolvedBrowserslist = transformSyntaxToBrowserslist(syntax, target);
return {
tools: {
rspack: (config) => {
config.target = resolvedBrowserslist.map(
(item) => `browserslist:${item}` as const,
);
config.target = transformSyntaxToRspackTarget(syntax);
},
},
output: {
overrideBrowserslist: resolvedBrowserslist,
overrideBrowserslist: transformSyntaxToBrowserslist(syntax, target),
},
};
}
Expand Down
43 changes: 42 additions & 1 deletion packages/core/src/utils/syntax.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { RsbuildConfig } from '@rsbuild/core';
import type { RsbuildConfig, Rspack } from '@rsbuild/core';
import type {
EcmaScriptVersion,
FixedEcmaVersions,
Expand Down Expand Up @@ -37,6 +37,12 @@ const calcEsnextBrowserslistByTarget = (target: RsbuildConfigOutputTarget) => {
return LATEST_TARGET_VERSIONS.web;
};

const RSPACK_TARGET_UNLISTED_MODERN_ECMA_VERSIONS: EcmaScriptVersion[] = [
'es2023',
'es2024',
'esnext',
] satisfies EcmaScriptVersion[];

/**
* The esX to browserslist mapping is transformed from esbuild:
* https://github.com/evanw/esbuild/blob/main/internal/compat/js_table.go
Expand Down Expand Up @@ -158,6 +164,40 @@ export const ESX_TO_BROWSERSLIST: Record<
},
} as const;

export function transformSyntaxToRspackTarget(
syntax: Syntax,
): Rspack.Configuration['target'] {
const handleSyntaxItem = (syntaxItem: EcmaScriptVersion | string): string => {
const normalizedSyntaxItem = syntaxItem.toLowerCase();

if (normalizedSyntaxItem.startsWith('es')) {
if (normalizedSyntaxItem in ESX_TO_BROWSERSLIST) {
// The latest EcmaScript version supported by Rspack's `target` is es2022.
// Higher versions are treated as es2022.
if (
RSPACK_TARGET_UNLISTED_MODERN_ECMA_VERSIONS.includes(
normalizedSyntaxItem as EcmaScriptVersion,
)
) {
return 'es2022';
}

return normalizedSyntaxItem;
}

throw new Error(`Unsupported ES version: ${syntaxItem}`);
}

return `browserslist:${syntaxItem}`;
};

if (Array.isArray(syntax)) {
return syntax.map(handleSyntaxItem) as Rspack.Configuration['target'];
}

return [handleSyntaxItem(syntax)] as Rspack.Configuration['target'];
}

export function transformSyntaxToBrowserslist(
syntax: Syntax,
target?: NonNullable<RsbuildConfig['output']>['target'],
Expand All @@ -166,6 +206,7 @@ export function transformSyntaxToBrowserslist(
syntaxItem: EcmaScriptVersion | string,
): string[] => {
const normalizedSyntaxItem = syntaxItem.toLowerCase();

if (normalizedSyntaxItem.startsWith('es')) {
if (normalizedSyntaxItem in ESX_TO_BROWSERSLIST) {
const browserslistItem =
Expand Down
51 changes: 46 additions & 5 deletions packages/core/tests/syntax.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { describe, expect, test } from 'vitest';
import { transformSyntaxToBrowserslist } from '../src/utils/syntax';
import {
transformSyntaxToBrowserslist,
transformSyntaxToRspackTarget,
} from '../src/utils/syntax';

describe('Correctly resolve syntax', () => {
test('esX', async () => {
describe('transformSyntaxToBrowserslist', () => {
test('esX', () => {
expect(transformSyntaxToBrowserslist('es6')).toMatchInlineSnapshot(`
[
"Chrome >= 63.0.0",
Expand Down Expand Up @@ -56,7 +59,7 @@ describe('Correctly resolve syntax', () => {
);
});

test('browserslist', async () => {
test('browserslist', () => {
expect(
transformSyntaxToBrowserslist(['fully supports es6-module']),
).toMatchInlineSnapshot(`
Expand All @@ -75,7 +78,7 @@ describe('Correctly resolve syntax', () => {
`);
});

test('combined', async () => {
test('combined', () => {
expect(
transformSyntaxToBrowserslist(['Chrome 123', 'es5']),
).toMatchInlineSnapshot(`
Expand All @@ -97,3 +100,41 @@ describe('Correctly resolve syntax', () => {
);
});
});

describe('transformSyntaxToRspackTarget', () => {
test('esX', () => {
const es2023 = transformSyntaxToRspackTarget('es2023');
const es2024 = transformSyntaxToRspackTarget('es2024');
const esnext = transformSyntaxToRspackTarget('esnext');

expect(es2023).toEqual(es2024);
expect(es2023).toEqual(esnext);

expect(es2023).toMatchInlineSnapshot(
`
[
"es2022",
]
`,
);

expect(transformSyntaxToRspackTarget('es2015')).toMatchInlineSnapshot(
`
[
"es2015",
]
`,
);
});

test('combined', () => {
expect(
transformSyntaxToRspackTarget(['Chrome 123', 'es2023']),
).toMatchInlineSnapshot(`
[
"browserslist:Chrome 123",
"es2022",
]
`);
});
});
Loading