Skip to content
New issue

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

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

Already on GitHub? # to your account

fix(es/minifier): Fix minification of framer-motion by checking cons.termniates() #9818

Merged

Conversation

sjchmiela
Copy link
Contributor

@sjchmiela sjchmiela commented Dec 28, 2024

Description:

Next.js 15 seems to minify parts of framer-motion's code in an invalid way, changing the meaning. The original function modifies the single definition variable as it changes meaning (see input.js):

  • if definition is a function, it calls it and saves the return value as definition
  • if definition is a string, it resolves animation variant based on value as name and saves the variant as definition
  • if definition is again a function, it calls it again and saves the return value as definition again

However, swc seems to be not noticing that definition may be mutated between the calls and collapses all ifs into one:

// `resolveVariantFromProps` in framer-motion
// https://github.com/motiondivision/motion/blob/ecd97f7dce8954be300aa73ab6a96208437941c5/packages/framer-motion/src/render/utils/resolve-variants.ts#L31-L72
export function resolveVariantFromProps(props, definition, custom, visualElement) {
    if ("function" == typeof definition || ("string" == typeof definition && (definition = props.variants && props.variants[definition]), "function" == typeof definition)) {
        const [current, velocity] = getValueState(visualElement);
        definition = definition(void 0 !== custom ? custom : props.custom, current, velocity);
    }
    return definition;
}

which skips the first call to definition, first "resolution" step.

Note: I suspect the output.js may not be precisely what SWC may output as minified code (maybe there is a way to minify it further). It definitely differs from the current output though by the initial call and reassignment to definition.

Copy link

changeset-bot bot commented Dec 28, 2024

🦋 Changeset detected

Latest commit: 91ed6a3

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant
Copy link

CLAassistant commented Dec 28, 2024

CLA assistant check
All committers have signed the CLA.

@sjchmiela sjchmiela force-pushed the sjchmiela/add-framer-motion-test-case branch from 52df9f2 to a60aa86 Compare December 28, 2024 22:42
@sjchmiela sjchmiela changed the title fix(es/minifier): Add test case for an example in framer-motion fix(es/minifier): Add failing test case for an example in framer-motion Dec 28, 2024
@sjchmiela sjchmiela marked this pull request as ready for review December 28, 2024 22:44
@sjchmiela sjchmiela requested a review from a team as a code owner December 28, 2024 22:44
Copy link

codspeed-hq bot commented Dec 29, 2024

CodSpeed Performance Report

Merging #9818 will not alter performance

Comparing sjchmiela:sjchmiela/add-framer-motion-test-case (91ed6a3) with main (512c91f)

Summary

✅ 194 untouched benchmarks

@kdy1 kdy1 added this to the Planned milestone Dec 29, 2024
@kdy1
Copy link
Member

kdy1 commented Dec 29, 2024

Thank you for reducing the edge case! Actually it's the most hard part of minifier work...

@kdy1 kdy1 self-assigned this Dec 29, 2024
@Austaras
Copy link
Member

A more simple example of why we need to check if cons terminates.

@kdy1 kdy1 requested a review from a team as a code owner December 31, 2024 08:39
Copy link
Member

@kdy1 kdy1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@kdy1 kdy1 changed the title fix(es/minifier): Add failing test case for an example in framer-motion fix(es/minifier): Fix minification of framer-motion by checking cons.termniates() Dec 31, 2024
@kdy1 kdy1 merged commit 512c91f into swc-project:main Dec 31, 2024
21 of 22 checks passed
@kdy1 kdy1 modified the milestones: Planned, v1.10.6 Jan 7, 2025
@swc-project swc-project locked as resolved and limited conversation to collaborators Feb 7, 2025
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants