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

Avoid compiling the _typeof helper with itself #11049

Merged
merged 2 commits into from Jan 27, 2020

Conversation

nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Jan 23, 2020

Q                       A
Fixed Issues? Fixes #11047, fixes #10996, fixes #8571, fixes #9127, fixes #11036, ref #2954, ref #3737
Patch: Bug Fix? Yes
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

We already had some logic to prevent the typeof-symbol plugin from transpiling its own helper. It worked by generating the helper name and checking if the current path is inside a function or a variable declaration with that name.

However, it had a few problems:

  1. It doesn't work with @babel/runtime, because the generated name is a unique identifier so it's guaranteed not to be equal to the _typeof helper name.
  2. Sometimes, multiple names are generated (_typeof2 and _typeof3), causing circular dependencies. This is probably caused by running twice the plugin, but we can avoid failing in that case.

I initially hard-coded the helper name in the isUnderHelper logic to make it work with @babel/runtime, but:

  1. It doesn't fix (2)
  2. If @babel/runtime is bundled in an app/library by rollup, the function name might change
  3. It doesn't work with minifiers.

I then decided to introduce a "@babel/helpers - typeof" directive, which has a few advantage:

  1. We don't need to generate the helper code before checking if we are inside the helper, which would always lead to duplicated code when transpiling @babel/runtime/helpers/typeof
  2. It fixes (2) and works with Rollup.

The directive still doesn't work with Terser and UglifyJS because they strip them by default. We could either suggest to whoever finds this bug to set the directives: false option in their minifier settings, or we could ask UglifyJS and Terser's maintainers if they could keep this specific directive in the minified output.

This PR makes it safe to transpile @babel/runtime, which should provide a solution for #9903

@nicolo-ribaudo nicolo-ribaudo added the PR: Bug Fix 🐛 A type of pull request used for our changelog categories label Jan 23, 2020
resolvePath(path, (err, path) => (err ? reject(err) : resolve(path))),
);
const readFile = path =>
new Promise((resolve, reject) =>

Choose a reason for hiding this comment

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

Can be refactored using util.promisify
Example:

const readFile = path => util.promisify(fs.readFile)(path, "utf8")

Copy link
Member Author

Choose a reason for hiding this comment

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

No, it's not supported by Node 6.
When we'll drop it, we'll directly use fs.promises.

Copy link
Member

@jridgewell jridgewell left a comment

Choose a reason for hiding this comment

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

Are we sure bundlers aren't just going to strip the directive?

@nicolo-ribaudo
Copy link
Member Author

If the file is already bundled, then Babel can't reference it and wouldn't introduce a circular dependency but only duplicate the helper. Anyway, I don't think that bundlers strip directives, especially if they are inside a nested function.

@soryy708
Copy link

Don't assume, verify.

@nicolo-ribaudo
Copy link
Member Author

Rollup doesn't, Parcel doesn't, Webpack doesn't.

@nicolo-ribaudo nicolo-ribaudo merged commit 916429b into babel:master Jan 27, 2020
@nicolo-ribaudo nicolo-ribaudo deleted the typeof-circular-fix branch January 27, 2020 21:02
@davixyz
Copy link

davixyz commented Jan 29, 2020

Hi! when is this getting released?

@nicolo-ribaudo
Copy link
Member Author

Tomorrow probably 😁

rajasekarm pushed a commit to rajasekarm/babel that referenced this pull request Feb 17, 2020
* Avoid compiling the typeof helper with itself

* Update fixtures
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Apr 30, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: Bug Fix 🐛 A type of pull request used for our changelog categories
Projects
None yet
5 participants