-
-
Notifications
You must be signed in to change notification settings - Fork 141
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
Static properties on components break tree-shaking #245
Comments
UPDATE 8/30/19: Example output: const MyComponent =
/*#__PURE__*/
function () {
function MyComponent() {
return _react.default.createElement(Wrapper);
}
MyComponent.displayName = 'Foo';
return FunctionComponent;
}(); Here are some more details: As with /*#__PURE__*/
Object.assign(MyComponent, { displayName: 'Foo' }) I wrote a Babel plugin to test this out and verify that it works: I tested it on our app, but didn't write unit tests for it yet because I wanted to share it here first...while it would be possible to solve this with a separate Babel plugin, I think it would be better if this functionality were part of babel-plugin-styled-components. BTW, my plugin isn't actually checking that styled-components is used; it just applies this transformation to all React components since I figured there was no reason not to (perhaps there are other edge cases that would also cause static properties to break tree-shaking). Also, I did run into an issue with Rollup... Let me back up first and explain that we have a library for reusable UI components that we're importing from our app. We want the tree-shaking to happen in our app so that if we import only some of the library components, only those components are included in the bundle. We are building the library with rollup. The problem is that by default, rollup completely removes the /*#__PURE__*/
Object.assign(MyComponent, { displayName: 'Foo' }) There is a workaround though: rollup allows you to turn off this feature by adding this to the config:
(Or you can pass |
This is very interesting, thank you for digging into this! 🙏 A PR that makes adds the IIFE wrapper (next to the PURE comment) when setting |
Great, glad you are open to including this. I can probably work on a PR for this sometime in the next week or two. |
Amazing, can't wait @mbrowne! 🙏 |
For anyone who's interested, I created a test repo so that others can easily reproduce this issue, and also so that we have something to test against to ensure that my PR (when it's ready) covers all the bases: If you run |
Is this issue actually specific to styled-components? Maybe i've got something goofed in my project i'm in currently, but regardless of using styled-components, if I add a static property ( Edit: Maybe its because my project is using webpack instead of rollup. Sounds like rollup is able to detect the static properties on function components, but webpack (well technically uglifyjs or terser) doesn't 🤷🏻♂️ |
@ammmze It isn't only an issue for styled-components. But in order to address it in a different plugin, that plugin would have to be aware of how to detect styled components, and duplicate all that detection logic that's already included in To elaborate a bit on detecting a styled component: it can't be done the same way as for a regular React component. Babel plugins analyze the source code only, so detection methods used to detect React components used by other Babel plugins (like babel-plugin-transform-react-remove-prop-types, to give one example) wouldn't work here. |
Gotcha! So it looks like with the fix you have in the PR, it only seems to take effect for components are literally made from styled components (i.e. const Foo = (props) => (<div {...props}>Foo</div>);
Foo.displayName = 'Foo';
export default Foo; |
@ammmze Yeah, I had forgotten about that until someone pointed it out to me recently. They told me they're now using both my PR to this repo and my older plugin, babel-plugin-pure-static-props. I still think that all the use cases related to styled-components should be handled by babel-plugin-styled-components, and that other plugins shouldn't be concerning themselves with detecting styled components. But for other use cases, I'm thinking maybe I should un-deprecate babel-plugin-pure-static-props and update it with the efficiency improvements I made as part of this PR. |
👍🏻 That is what I'm thinking. I think it makes perfect sense for the It blew up when it hit an old class component (really we have a bunch of them...this was just the first one it hit) we have in our stuff...
It gave me the following:
But I can dig into that and report in your repo. |
@mbrowne FYI i've forked your project and i'm setting up test fixtures to cover some various use cases and I'll submit a PR when complete |
In our app we are finding that any time a component that uses styled-components has a static property added to it, that component is always included in the bundle even if it's not imported, i.e. tree shaking does not work. For example:
In some cases we're able to remove the
displayName
or use default function argument values instead ofdefaultProps
, but there are other cases where we do need to use these properties.This seems to be caused by the way terser (or uglify-js) removes dead code and isn't really an issue in babel-plugin-styled-components per se, but it would be great if babel-plugin-styled-components could include an option to address this.
The text was updated successfully, but these errors were encountered: