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

🚀 Transform Function Declarations #23358

Closed
wants to merge 11 commits into from
Closed

🚀 Transform Function Declarations #23358

wants to merge 11 commits into from

Conversation

kristoferbaxter
Copy link
Contributor

@kristoferbaxter kristoferbaxter commented Jul 16, 2019

Babel Plugin that safely converts function declaration to arrow function declarations, where possible losslessly.

function foo(a, b) {
  return a + b;
}

compiles to

const foo = (a, b) => a + b;

This PR does not enable the plugin, as we want to ship Babel/Multipass before testing.


const BAIL_OUT_CONDITIONS = {
// If this isn't a FunctionDeclaration, bail out on modification.
isNotFunction: (t, path) => !t.isFunctionDeclaration(path.node),
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are you ignoring function expressions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Scope, starting with a very small surface. Happy to extend though if this is too restrictive.


// If the FunctionDeclaration identifier is newed in the scope of this program, bail out on modification.
isNewedInProgramScope: (t, path) => {
const methodName = path.get('id').node.name;
Copy link
Contributor

Choose a reason for hiding this comment

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

Use path.scope.getBinding(name) to quickly find all references to the identifier.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I find the current syntax far more expressive of it's intent. Is there a strong push here to change?

Copy link
Contributor

Choose a reason for hiding this comment

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

It's like a bajillion times faster for large files.

@dreamofabear
Copy link

Neat. I'm curious what the expected benefits are (binary size?) and why we don't just change the source and add a linter to prefer arrows over functions.

Found out last week that this is recommended by Google's style guide too:
https://google.github.io/styleguide/jsguide.html#features-functions-arrow-functions

Prefer arrow functions over the function keyword

@kristoferbaxter
Copy link
Contributor Author

The goal is a binary size savings for the module build, but without a migration until proven valuable.

Since this transform is mostly lossless, it could only be applied on the module build without touching the nomodule build.

.log(
`Bail on ${
path.get('id') && path.get('id').node.name
? `function ${path.node.id.name}:`
Copy link
Member

Choose a reason for hiding this comment

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

Could we add a message string function in conjunction with "avoid else, return/continue early" to prevent Hadouken nesting? 😬

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure thing, makes sense.

Choose a reason for hiding this comment

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

Lol @ hadouken nesting.

* See the License for the specific language governing permissions and
* limitations under the License.
*/
const thing = async (a, b) => a + b;
Copy link
Member

Choose a reason for hiding this comment

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

nit: newlines in test files.

@kristoferbaxter
Copy link
Contributor Author

@alanorozco is going to take this PR and drive to completion. Thanks Alan for taking this on!

@alanorozco
Copy link
Member

alanorozco commented Jul 29, 2019

@kristoferbaxter What's the current state? Is the plugin ready but depending on the post-Closure Babel step?

EDIT: Cleared up offline.

Remaining tasks:

  • Optimization through Babel structure suggested above.
  • Post-Closure Babel step.

Will apply optimization but disable the plugin. Then I'll include it in the post-Closure step.

I'll see if I can work on this PR directly, if not I'll fork it.

@kristoferbaxter
Copy link
Contributor Author

Thanks @alanorozco – sorry for missing your question here and thanks for following up offline.

@kristoferbaxter
Copy link
Contributor Author

Closed in favor of #26779

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

Successfully merging this pull request may close these issues.

None yet

5 participants