Skip to content

SWC minifier incorrectly merges conditions (semantic change) #11517

@lerrybe

Description

@lerrybe

Describe the bug

Thank you for creating such a great tool.

While testing, I noticed that the runtime behavior of the code built with SWC differs from the behavior in the development environment, and during this process I discovered the following issue.

In the SWC Playground, the following behavior also can be observed.

When two conditional branches have similar structures and differ only by string literals, the minifier appears to treat them as equivalent and merges them into a single branch.

Input code

export const buildErrorLog = ({
  errorType,
  mode,
}: {
  errorType?: string;
  mode: 'modeA' | 'modeB';
}) => {
  const isModeA = mode === 'modeA';
  const isModeB = mode === 'modeB';
  
  if (errorType === 'A_ERROR') {
    const message = 'A error occured';
    return { fieldX: true, fieldY: true, message };
  }
  if (errorType === 'B_ERROR') {
    const message = 'B error occured';
    return { fieldX: true, fieldY: true, message };
  }
  return { fieldX: true, fieldY: true, message: 'Invalid configuration' };
};

Config

This behavior occurs in the SWC Playground when compiling TypeScript targeting ES2015 or later with minify, compress, and mangle enabled.

(A SWC Playground link is attached.)

Link to the code that reproduces this issue

https://play.swc.rs/?version=1.11.29&code=H4sIAAAAAAAAA62RzWoDIRSF93mKszOBPMEMtkTIopBSGLpoVmE6OoMw0XDV0pL47tGxU%2BgPlEJBuB78zjkXVK8nSx6dNc7jOehRboks7ewAjuV5AaisH99Oap3E0co0Y4VPL7cVnCdthvodqcDy2DBcyk2wehFX4DeTsbRpd5%2BZ1JMJcM5nV%2F2FEd8YMTHp6B7Ljz3K%2B%2BawbZqHhq2mrjnpqJxrh4QkoGwO23WBlJyiAFI%2BkMEZvVajfKrgKah1UftZzSkxe%2BLP%2FeK3fvGP%2FX9xpV%2B5My%2FtqGXeqddDoNZra1iOi%2FUVIb6EWAsCAAA%3D&config=H4sIAAAAAAAAA41VwW7bMAy99ysCn3doB3Qo9gG77RsExaIcdbJoiJSboMi%2Fl1bsNG1oY5cg5tMjRfKRen%2FY7ZpXapvfu3f5Kx%2BDzQT5%2Bi0WOiW2R7E0fBqA2hwGbn4sKNMEeRsJqul8QRq2uQOeWEA%2FH5%2BeZ0YTEQkWxmzrQwr%2BdBuzxX7IQHRjE6u4LD0kpq%2F8Gcv4NgGcy619jxjBpg3EWDIhMXSQNcctxmgHAjParHiZbmpzINRCTGBhcGbIOKh4coEDJol5jzqwzrToQIFChpbDCBpNYgktkaSn5FNhB%2FvSdbXP39gw2lgsKzHhWFsit1W8HjAQG1%2BSVsILuFKDCzgX9zszeJOBS073vFcMaaUn%2FwCkAtESJduD5ree8KKnNbbfZIbkRbJ8UnDRt5Zlgk6KakLwSmWnykDmoHUzgystTJVttevM8Er5KDgw4L1oRXFNb4HbgxZ0GnT0CiD9tV5T1QUw1ylcwaeB2ID%2FSJasC2w%2B0Vs%2BrKN06vcYNwL0wAd0GwekFYzrcJYtcRzW8ZIciDTAqUcKVeB%2BCcgAMJpY9%2BWdNmQ8xKPpIu4%2F18R84Hzdw71NXZ33m33JOEQYIa7J%2BD9GZBOVu42TqpfJvpteeNFEaWXwwtPjl2dDUnlYfmtSTY%2Bu3CRUNXl5Tn41n4eWl2OpWhPo70KsdTp%2FAKKyMmzjBgAA

SWC Info output

No response

Expected behavior

The minifier should not merge these two conditional branches.

Actual behavior

export const buildErrorLog = ({ errorType: e, mode: r }) =>
"A_ERROR" === e || "B_ERROR" === e
? { fieldX: !0, fieldY: !0, message: "A error occured" }
: { fieldX: !0, fieldY: !0, message: "Invalid configuration" };

Version

1.11.29

Additional context

Based on testing in the playground, this issue appears to occur when targeting over ES2015, starting from version 1.11.29.

(I am currently using version 1.13.19)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions