ReactTraining / react-media

CSS media queries for React

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

removing prop types causes issues

bdwain opened this issue · comments

My app started having issues since #112 when I run it in prod mode. Even if the prop type verifications aren't run, some things rely on the prop types of a component to work properly (such as https://github.com/ngReact/ngReact).

Also, I have a component that wraps the Media component and reuses some of its proptypes like this

MediaQueryPhoneAndTablet.propTypes = {
  children: Media.propTypes.children,
  render: Media.propTypes.render
};

which I think is a valid use of proptypes.

My thought is while it can save a few bytes, a library should not be removing its proptypes and if an app wants that to be done, it's up to the app to do it.

I'm happy to make a PR to revert the changes if they'll be accepted.

Honestly curious; do you have production code that is dependent on prop types?

Yea I use both of the examples I gave in my original post. While none of the actual prop type validations happen in prod, the existence of those keys is important still.

Oh yeah, sorry if this was unclear, but prop types should still be available when using a development build. In 1.9.2, as long as you don't set process.env.NODE_ENV === 'production', you should get a bundle including prop types. See this piece of code if you're interested.

Oh wait, I get what you mean now. You're not stripping your own prop types, and you're referencing Media.propTypes, so that will break in production. I see 🤔

Yep. To me, this seems similar to minifying. It's not the job of the library author to remove the proptypes from the code. It's the job of the end user.

Funny, I actually said the same here a while ago 😅! However, in the thread referenced there Dan Abramov clearly states the recommendation from the React team is to refrain from using prop types in production behavior.

He continues to say that he's comfortable with enforcing the removal of prop types in user code (in the context of CRA), but is not comfortable with removing prop types from node_modules, because some third party code could rely on them. I might misinterpret him here, but as I understand it he'd actually prefer it if prop types wouldn't be used in any production code, including libraries.

Now I think the trade-off here is about ease of use. The current setup should work "out-of-the-box" in the majority of cases. Your suggestion of shifting the responsibility of removing prop types to the user does lend more power - you can reuse the prop types, and keep them in your production bundle if you like. However, it also makes it considerably more difficult to strip them out if you wanted to. Not only would one have to add the babel plugin, one would also have to create an exception somewhere (probably in a webpack config) to make sure react-media is not ignored by babel.

And as a final question to you. Besides your app referencing Media.propTypes, are there other ways your app breaks in production because we're stripping prop types? You mention ngReact, I don't know how this lib works 😅.

I get why he's saying that, but if there's not an organized push to get the whole ecosystem to stop using proptypes in production, then some libraries (like ngreact) are going continue relying on them in prod. And as long as that's true, people won't be able to use those libraries with libraries that remove their proptypes in production.

Nothing else breaks in my app right now, though ngReact could. ngReact lets you wrap your react components in angular components if your app has both (which might be the case if you're migrating from angular to react). It knows which angular component props to watch by looking at the react component's proptypes. So if those are not there, you can't use that component with ng-react. If I wanted to wrap a React-Media component in ng-react, I would not be able to use the new version.

Interesting, so if you want to use ngReact, you wouldn't even be able to remove prop types at all.

Personally, I prefer the current setup. If we manage to find workarounds for problems like this ngReact thing, I would argue we leave it as it's currently implemented. I realize this makes it impossible in your case to reference Media.propTypes, since you're not stripping your prop types in your production build. But it seems you're really only doing that in a wrapper around <Media>, which you wouldn't write on a day-to-day basis, right?

What I meant to say was in case one chooses to not strip prop types in production, they will not be able to reference Media.propTypes at all, since that will break their production build. Now this would be a big problem if people were regularly referencing Media.propTypes, but I would expect that not to be the case.

Frankly, the only real use case I can think of where you want to reuse them is in the case you outline in the original post, where you wrap <Media> in a <MediaQueryPhoneAndTablet>-type thing. So I would argue that if you'd have a handful of those components, it'd be doable (though cumbersome for those components) to manually define the prop types. And remember, this is not the case when you do choose to strip prop types at production, as is recommended.

To me, this resonates with "Make the right thing, the easy thing to do". What do you think?

Oh and I didn't think this through very well, but for a workaround, do you think something like this would work for the ngReact case?

// in your entrypoint
import Media from 'react-media';
Media.propTypes = { ... }

Well I'd have to copy all of the proptypes, not just the ones I pass through from my wrapper, which is a bit awkward to do, and I'd be relying on knowledge of the specific build process of one library. But as of now I don't wrap Media components in ngreact, so it's not a big problem for me. So maybe if no one else has an issue then it's fine.

I'll close this for now. In the end it's a trade off, and I'd be happy to receive feedback from people having a problem with this. If sufficiently many people run into this, we might reconsider shipping prop types in the production bundle.