Skip to content

Better tree-shaking for React components #730

Closed

Description

@omgovich

Hi! Thanks for your work! Love microbundle and use it every day.

I'm the maintainer of an open-source React-components library and I recently noticed that when I use React.forwardRef or React.memo the components became un-tree-shakeable.

I dig into this problem and found out that Babel fixed that several months ago in their @babel/preset-react package:
https://babeljs.io/blog/2020/05/25/7.10.0#better-tree-shaking-for-react-components-11428httpsgithubcombabelbabelpull11428

Unfortunately, I couldn't find a way to use it with microbundle.

Activity

  1. developit commented on Sep 23, 2020

    @developit
    Owner

    I believe currently we remove @__PURE__ annotations, which is affecting this.

  2. omgovich commented on Sep 24, 2020

    @omgovich
    Author

    Hi, @developit! Thanks for fast response)
    As far as I understand there is no way to automatically mark things like React.forwardRef as pure annotations except using @babel/plugin-transform-react-pure-annotations (which is included to @babel/preset-react).

  3. omgovich commented on Sep 24, 2020

    @omgovich
    Author
  4. developit commented on Nov 5, 2020

    @developit
    Owner

    Have you tried using a custom babel configuration with Microbundle? .babelrc / "babel" in package.json is supported, so you could add {"presets":["@babel/preset-react"]}.

  5. omgovich commented on Nov 6, 2020

    @omgovich
    Author

    Hi @developit!
    Started to dig deeper into my build output.

    First thing I found out that if I set --no-compress my bundle has /*#__PURE__*/. If compression is enabled, all comments including PURE ones are gone.
    I assume that Terser just cleans all comments. Probably we should find a way to "ask" him to leave /*#__PURE__*/.

  6. omgovich commented on Nov 6, 2020

    @omgovich
    Author

    Second thing:

    @babel/plugin-transform-react-pure-annotations is a part of @babel/preset-react which already installed to my project with microbundle. Besides that @babel/preset-react (tried to add this via babelrc) doesn't add /*#__PURE__*/ to React.memo and React.lazy.

    But If I add @babel/plugin-transform-react-pure-annotations to babel config, it works:

    image
    Xnip2020-11-06_11-27-00

  7. omgovich commented on Nov 6, 2020

    @omgovich
    Author

    As far as I understand @babel/preset-react has to add @babel/plugin-transform-react-pure-annotations if pure option isn't false:
    https://github.com/babel/babel/blob/main/packages/babel-preset-react/src/index.js

    But it doesn't work for some reason:
    image

  8. omgovich commented on Nov 6, 2020

    @omgovich
    Author

    I guess I found the reason: microbundle enables @babel/preset-react only if --jsxImportSource was passed (see screenshot above).
    But I don't have one on my CLI command.

  9. omgovich commented on Nov 6, 2020

    @omgovich
    Author

    I'm not sure that it's the correct behavior. I mean shouldn't microbundle use default React setup if no jsxImportSource option present?

    I read the docs and it felt like this option is for custom stuff:

    --jsxImportSource  Specify the automatic import source for JSX like preact
    
  10. omgovich commented on Nov 6, 2020

    @omgovich
    Author

    So there are two things to solve:

    1. Keeping /*#__PURE__*/ after compression.
    2. Enabling @babel/preset-react for React apps?
  11. omgovich commented on Nov 6, 2020

    @omgovich
    Author

    Terser preserves PURE comments since 4.6.3:
    terser/terser@35b1723

    preserve_annotations option is false by default.
    https://github.com/terser/terser#format-options

    image

  12. omgovich commented on Nov 6, 2020

    @omgovich
    Author

    I assume the rollup plugin that microbundle use now doesn't support that:
    image

  13. omgovich commented on Nov 6, 2020

    @omgovich
    Author

    Next versions of rollup-plugin-terser require rollup v2, so probably that's not so easy to fix 😞

  14. developit commented on Nov 6, 2020

    @developit
    Owner

    There's a PR open that updates all of our dependencies. In Terser 4, the option is output.preserveComments.

  15. omgovich commented on Nov 9, 2020

    @omgovich
    Author

    Hi! What about @babel/preset-react? What is the preferable way to use it with React?

  16. developit commented on Dec 18, 2020

    @developit
    Owner

    This should all be fixed as of #738. The release will go out shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancement 🚀has-fixA fix is available, but may not yet be released.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions