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

perf(gatsby/babel): Optimize hook destructuring #22619

Merged
merged 12 commits into from Apr 16, 2020
Merged

Conversation

blainekasten
Copy link
Contributor

Description

Thanks to @developit for giving us a great rundown of the benefit of this feature and also shipping it to next.

I took the liberty to make it into a package so other ecosystems and companies outside of Gatsby/next could benefit from it. Is there a problem with this approach?

Documentation

Do we document our babel setup anywhere? or micro optimizations we do? cc @gatsbyjs/learning

Related Issues

#19943

@blainekasten blainekasten requested review from a team as code owners March 28, 2020 03:34
pvdz
pvdz previously approved these changes Mar 28, 2020
Copy link
Contributor

@pvdz pvdz left a comment

Choose a reason for hiding this comment

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

um, ok :)

@laurieontech
Copy link
Contributor

@blainekasten We have section on Gatsby internals that it could fit well in! We recently updated the webpack config with @wardpeet's new chunking functionality.

https://www.gatsbyjs.org/docs/production-app/

Copy link
Contributor

@pieh pieh left a comment

Choose a reason for hiding this comment

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

Do we need this as separate package or can it be just a file inside our gatsby-preset-gatsby? As soon as we release this is separate package we defacto become maintainers for this? (If there is no standalone package like this already).

packages/babel-preset-gatsby/src/index.js Outdated Show resolved Hide resolved
@blainekasten
Copy link
Contributor Author

So I'm not certain we need this at all...

I looked at the output from next when you build and have a useState:

It compiles to this:

var a=Object(Q.useState)(0),b=a[0],c=a[1];

Which is peculiar, because it's different than the test that is written in general. But then I tested my changes with gatsby and I got the same results. Seems great, but then I tested against gatsby master and got the same results

So I'm not sure if this plugin in general is just not doing what it's supposed to do for us or next, or the way it's working means we don't actually need this plugin for some reason.

cc @developit for advice because I'm not really sure what the aim still is. Do we want to see {0:a,1:b} or b=a[0],c=a[1] ?

@blainekasten blainekasten added status: awaiting reviewer response A pull request that is currently awaiting a reviewer's response status: blocked This issue/PR can't be solved at the moment and shouldn't be closed/merged labels Apr 10, 2020
@developit
Copy link
Contributor

developit commented Apr 10, 2020

This only affects modern output where destructuring is preserved, or legacy output when Babel is in non-loose mode (example). Babel's loose mode output already dissolves destructured arrays (example) and treats them as objects.

It's safe to apply this optimization for both modern and non-modern output, but it will only provide value in modern output.

@developit
Copy link
Contributor

Just to clarify, here's a breakdown:

Input:

const [count, setCount] = useState(0);

Output: (non-modern / ES5)

(note that this is identical to the output without hook destructuring optimization)

var _temp = Object(Q.useState)(0),
    count = _temp[0],
    setCount = _temp[1];

Output: (modern)

var { 0: count, 1: setCount } = Object(Q.useState)(0);

@blainekasten blainekasten added bot: merge on green Gatsbot will merge these PRs automatically when all tests passes and removed status: awaiting reviewer response A pull request that is currently awaiting a reviewer's response status: blocked This issue/PR can't be solved at the moment and shouldn't be closed/merged labels Apr 15, 2020
@blainekasten blainekasten requested a review from a team as a code owner April 15, 2020 20:58
@blainekasten
Copy link
Contributor Author

@developit Thanks for the clarification :) I was talking to @wardpeet shortly before you posted this and realized exactly what you described. Good news, I tested this in a gatsby project by creating a .babelrc with this config:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": { "esmodules": true }
      }
    ],
    "@babel/preset-react"
  ],
  "plugins": [
    "../gatsby/packages/babel-preset-gatsby/optimize-hook-destructuring.js"
  ]
}

and saw the expected object destructured from the plugin.

So I would say this plugin is ready to be merged, even though the value it gives won't be seen until we ship modern builds (soon!)

@blainekasten
Copy link
Contributor Author

@laurieontech I think I'm going to skip adding to docs for this one. This is a very small benefit that users don't really need to think about or know about. modern builds will be a more applicable effort to document. Let me know if you disagree 👍

pvdz
pvdz previously approved these changes Apr 16, 2020
@pvdz
Copy link
Contributor

pvdz commented Apr 16, 2020

/home/circleci/project/packages/babel-preset-gatsby/src/optimize-hook-destructuring.ts
11:6 error Use an interface instead of a type @typescript-eslint/consistent-type-definitions

@laurieontech
Copy link
Contributor

@blainekasten I think that's ok given the changes.

@pvdz
Copy link
Contributor

pvdz commented Apr 16, 2020

Errors for the build are unrelated to this. Let's merge it.

@pvdz pvdz merged commit b3343ab into master Apr 16, 2020
@delete-merged-branch delete-merged-branch bot deleted the optimize-hook-destructuring branch April 16, 2020 14:54
@pvdz pvdz changed the title Optimize hook destructuring perf(gatsby/babel): Optimize hook destructuring Apr 16, 2020
@kitos
Copy link
Contributor

kitos commented May 12, 2020

@blainekasten @pieh @developit I am not completely sure whether it is babel issue or my/gatsby misconfiguration. But after updating gatsby this optimization broke my build, because of the following syntax:

let [{ someProp, ...rest }, setState] = useState()

I assumed that this is a babel plugin issue (even though I wasn't able to reproduce it in babel repl).
You can check find a PR with potential fix here.

@pieh
Copy link
Contributor

pieh commented May 12, 2020

---edited

Ignore this comment

@kitos

I just tried yours and what our current babel transform generate is (check snapshot):

it(`should object destructuring`, () => {
    const input = trim`
      import { useState } from 'react';
      let [{ someProp, ...rest }, setState] = useState({ someProp: 'a', otherProp: 'b' });
    `

    expect(() => babel(input)).not.toThrow()
    expect(babel(input)).toMatchInlineSnapshot(
      `"\\"use strict\\";var _react=require(\\"react\\");let{0:{someProp,...rest},1:setState}=(0,_react.useState)({someProp:'a',otherProp:'b'});"`
    )
  })

So theoretically it should be fine? What's exact error you are seeing? Is it actually babel or syntax error or runtime error? Also do you actually use the code as is - are you not passing any initial state value? I think it would be undefined if not specified so you would get "Cannot read property 'someProp' of undefined" in runtime if you are using it exactly as you show in example?

Also as sidenote - we diverged a bit from initial implementation in this PR already because of #23438 (but this doesn't seem to affect your example)

@pieh
Copy link
Contributor

pieh commented May 12, 2020

Ah, ok I just checked your PR in babel - yeah - seems like it you accurately found real culprit and seems like your PR already getting approvals, so it's bit of our hands (other than maybe trying to temprorily disable this transform while we wait for new release for babel-plugin-proposal-object-rest-spread

Sorry for sending previous comment before checking on the linked PR (please ignore :P)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bot: merge on green Gatsbot will merge these PRs automatically when all tests passes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants