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

A flat carbon-components-react entrypoint is not tree-shakeable #5442

Closed
joshblack opened this issue Feb 25, 2020 · 5 comments
Closed

A flat carbon-components-react entrypoint is not tree-shakeable #5442

joshblack opened this issue Feb 25, 2020 · 5 comments
Labels
package: react carbon-components-react type: bug 🐛

Comments

@joshblack
Copy link
Contributor

While verifying v10.10 over in #5398, we noticed a regression in bundle size when using carbon-components-react along with Webpack. Notably, when we were using babel to compile our components then webpack picked up on sideEffects: false for module file paths and correctly inferred that they had no side effects.

In a single entrypoint, we run into a set of problems with assignment expressions. Consider the following situations:

Note: all situations can be run in a Terser sandbox here to verify output

// Input
!function() {
  const MyComponent = function () {};
  MyComponent.propTypes = {};
}();

// Output (correct)
// Input
!function() {
  const MyComponent = function () {};
  MyComponent.propTypes = {};
  MyComponent.defaultProps = {};
}();

// Output (multiple assignments deopts)
// https://github.com/terser/terser/issues/293
!function() {
    const MyComponent = function() {};
    MyComponent.propTypes = {}, MyComponent.defaultProps = {};
}();
// Input
!function() {
  const MyComponent = React.forwardRef(
    function () {}
  );
}();

// Output (unable to infer if getter has side-effect)
React.forwardRef(function() {});
// Input
!function() {
  const MyComponent = /*#__PURE__*/ React.forwardRef(
    function () {}
  );
}();

// Output (#__PURE__ annotation correctly tree-shakes)
// Input
!function() {
  const MyComponent = /*#__PURE__*/ React.forwardRef(
    function () {}
  );
  MyComponent.propTypes = {};
}();

// Output (Assignment expression deopts)
/* */ React.forwardRef(function() {}).propTypes = {};

As a result of these situations, we need to update our build process before we can ship a single entrypoint generated by Rollup for our ESM and CJS bundles. We would need to make the following changes:

Links & Resources

@joshblack joshblack added type: bug 🐛 impact: high 😱 severity: 1 https://ibm.biz/carbon-severity package: react carbon-components-react labels Feb 25, 2020
@joshblack joshblack changed the title carbon-components-react entrypoint is not tree-shakeable A flat carbon-components-react entrypoint is not tree-shakeable Jul 9, 2020
@joshblack joshblack removed impact: high 😱 severity: 1 https://ibm.biz/carbon-severity labels Jan 11, 2021
@joshblack
Copy link
Contributor Author

We're going to proceed with a non-flat entrypoint for the foreseeable future and leverage the sideEffects flag for webpack interop.

@leximarie
Copy link

@joshblack What does this mean for consumers? Do we need to import everything from "carbon-components-react/es/{componentPath}" for tree shaking to work? For large applications this seems like a burden.

Also it seems like if importing from "carbon-components-react" imports all of the components combined AND the individual modules.
Screen Shot 2021-04-12 at 10 04 14 AM

@joshblack
Copy link
Contributor Author

Hi there @leximarie!

The project is currently set up to be tree-shaken with webpack because of the sideEffects flag. Most likely if something is not being dropped, there is some configuration issue or some CommonJS module that is being included.

Here's the result of a build using the stock create-react-app tool along with importing button:

Snippet

import { Button } from 'carbon-components-react';

// Used in App component

image

image

@leximarie
Copy link

leximarie commented Apr 12, 2021

@joshblack It looks like it works if I am only importing Button (possibly others, but I can't test every component), so are there components that break tree-shaking? For example, I am not using DatePicker anywhere in our application but the DatePicker module is included in the bundle.

@joshblack
Copy link
Contributor Author

@leximarie it may be that a component being used is dependent on DatePicker internally versus the application specifying it explicitly. If you could share some steps to reproduce the bundle/tree-shake deopt I can definitely take a look!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package: react carbon-components-react type: bug 🐛
Projects
None yet
Development

No branches or pull requests

2 participants