Skip to content
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

@embroider/macros babel plugin: Optional chaining expression gets aggressively optimized to undefined #2212

Open
ArnaudWeyts opened this issue Dec 16, 2024 · 0 comments

Comments

@ArnaudWeyts
Copy link

Summary

While upgrading to Embroider in our main app, I noticed that the babel plugin for @embroider/macros transpiles code like aKnownValue?.foo to undefined prematurely.

Steps to reproduce

I created a repo here which showcases the issue: https://github.com/ArnaudWeyts/embroider-macros-reproduction

What happens is the following:

const aKnownValue = {};
aKnownValue.foo = true;
console.log(aKnownValue?.foo);

gets transpiled into

const aKnownValue = {};
aKnownValue.foo = true;
console.log(undefined);

We have several places in our codebase where this optional chaining is applied, and it's currently blocking us from upgrading to Embroider since it seems like Embroider makes this babel plugin run on all the source code while it didn't before.

I tried to pinpoint why this was happening but it seems like this is currently happening by design, as I noticed there's a test that makes sure this works:

test('optional chaining nullish member access', () => {
let code = transform(`const result = knownUndefinedValue?.x;`);
expect(code).toMatch(`result = undefined`);
});

Other pointers that I discovered:

  • Exact place where the code is replaced:
    path.replaceWith(buildLiterals(result.value, context));
  • The evaluator that returns a "confident" undefined:
    return {
    confident: true,
    get value() {
    if (optionalChain) {
    return confidentObject.value != null
    ? confidentObject.value[confidentProperty.value]
    : confidentObject.value;
    } else {
    return confidentObject.value[confidentProperty.value];
    }
    },
    hasRuntimeImplementation:
    confidentObject.hasRuntimeImplementation || confidentProperty.hasRuntimeImplementation,
    };

If anyone could help me give some pointers as what exactly needs to happen, I can look into creating a PR, but I'm not really sure where this issue should be fixed.

Thanks for working on this project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant