# babel-plugin-transform-react-remove-prop-types > Remove unnecessary React propTypes from the production build. [![npm version](https://img.shields.io/npm/v/babel-plugin-transform-react-remove-prop-types.svg)](https://www.npmjs.com/package/babel-plugin-transform-react-remove-prop-types) [![npm downloads](https://img.shields.io/npm/dm/babel-plugin-transform-react-remove-prop-types.svg)](https://www.npmjs.com/package/babel-plugin-transform-react-remove-prop-types) [![Build Status](https://travis-ci.org/oliviertassinari/babel-plugin-transform-react-remove-prop-types.svg?branch=master)](https://travis-ci.org/oliviertassinari/babel-plugin-transform-react-remove-prop-types) [![Dependencies](https://img.shields.io/david/oliviertassinari/babel-plugin-transform-react-remove-prop-types.svg)](https://david-dm.org/oliviertassinari/babel-plugin-transform-react-remove-prop-types) [![DevDependencies](https://img.shields.io/david/dev/oliviertassinari/babel-plugin-transform-react-remove-prop-types.svg)](https://david-dm.org/oliviertassinari/babel-plugin-transform-react-remove-prop-types?type=dev) ## Installation ```sh npm install --save-dev babel-plugin-transform-react-remove-prop-types ``` ## The problem solved Remove React `propTypes` from the production build, as they are only used in development. You can **save bandwidth** by removing them. ## Example **In** ```jsx const Baz = (props) => (
); Baz.propTypes = { className: PropTypes.string }; ``` **Out** ```jsx const Baz = (props) => (
); ``` ### With comment annotation The majority of cases should be addressed by default by this plugin. In some cases, for example when using HOCs (High Order Components), like *react-redux*'s `connect`, or component inheritance ([although it's NOT recommended](https://facebook.github.io/react/docs/composition-vs-inheritance.html)), a comment after the `propTypes` definition may be used to force the removal: ```js Component.propTypes /* remove-proptypes */ = {} ``` ## Usage ### Via `.babelrc` (Recommended) **.babelrc** without options: ```json { "env": { "production": { "plugins": ["transform-react-remove-prop-types"] } } } ``` with options: ```json { "env": { "production": { "plugins": [ ["transform-react-remove-prop-types", { "mode": "wrap", "ignoreFilenames": ["node_modules"] }] ] } } } ``` ### Via CLI ```sh babel --plugins transform-react-remove-prop-types script.js ``` ### Via Node API without options: ```js require('babel-core').transform('code', { plugins: [ 'transform-react-remove-prop-types', ], }); ``` with options: ```js require('babel-core').transform('code', { plugins: [ [ 'transform-react-remove-prop-types', { mode: 'wrap', ignoreFilenames: ['node_modules'], }, ], ], }); ``` ## Options ### `mode` - `remove` (default): the `propTypes` definitions are removed from the source code. - `wrap`: the `propTypes` definitions are wrapped with the following code: ```js Component.propTypes = process.env.NODE_ENV !== "production" ? { // ... } : {}; ``` Accessing `Component.propTypes.className` won't throw. It's a tradeoff between the size of the output file and the likelihood libraries like [react-native-hyperlink](https://github.com/obipawan/react-native-hyperlink/pull/11) breaks. - `unsafe-wrap`: the `propTypes` definitions are wrapped with the following code: ```js if (process.env.NODE_ENV !== "production") { Component.propTypes = { // ... } } ``` Accessing `Component.propTypes.className` will throw. The *wrap* modes are targeting React libraries like [material-ui](https://github.com/callemall/material-ui) or [react-native-web](https://github.com/necolas/react-native-web). They are not intended to be used by application authors. ### `removeImport` - `true`: the import statements are removed as well. This option only works if `mode` is set to `remove`: ```js import PropTypes from 'prop-types' ``` - `false` (default): does not remove the import statements. ### `ignoreFilenames` This filter generates a regular expression. Any filenames containing one of the array's strings will be ignored. By **default**, we match everything. Following the [Is it safe?](#user-content-is-it-safe) section, you might encounter a component depending on the `propTypes` at runtime to work. For this reason, we provide an array options to filter out some files and folders. For instance, you can ignore all the npm modules: ```js ignoreFilenames: ['node_modules'], ``` ### `additionalLibraries` This option gives the possibility to remove other `propTypes` in addition to the canonical `prop-types`. For instance, by default ```js import PropTypes from 'prop-types' import ImmutablePropTypes from 'react-immutable-proptypes' ``` will result in the latter not to be removed, while with: ```js additionalLibraries: ['react-immutable-proptypes'], ``` both will be removed. #### Regular expressions If you are using Babel 7 or newer and your config is stored in [`babel.config.js`](https://babeljs.io/docs/en/configuration#babelconfigjs), you can also use a regular expression to describe modules, which should be removed. This would be particularly useful when using custom prop types validators, implemented as part of your own source code. For example ```js import CustomPropTypes from '../../prop-types/my-own-validator' import OtherCustomPropTypes from '../../prop-types/my-other-validator' ``` would be removed with the following setting ```js additionalLibraries: [/\/prop-types\/.*$/] ``` If you use an index file ```js import CustomPropTypes from '../../prop-types' ``` you could set it up as ```js additionalLibraries: [/\/prop-types$/] ``` ### `classNameMatchers` Use this option to enable this plugin to run on components that extend a class different than `React.Component` or `React.PureComponent`. Given this example: ```js class MyComponent extends BaseComponent { ... } ``` You would use: ```js classNameMatchers: ["BaseComponent"] ``` ### `createReactClassName` Use this option to set a custom name for the import of the `create-react-class` package that is different than `createReactClass`. Given this example: ```js import createClass from 'create-react-class'; ``` You would use: ```js createReactClassName: 'createClass' ``` ## Is it safe? If you are using the `propTypes` in a conventional way, i.e by using them to perform type checking on the properties, that plugin should be **safe to use**. However, some libraries are accessing the `propTypes` on the component directly. For instance [react-native-vector-icons](https://github.com/oblador/react-native-vector-icons/blob/3d1f2a5b7175d6e4c8985676940240776543ff60/lib/icon-button.js#L59) use them to split the properties between two components: ```js const touchableProps = pick(restProps, Object.keys(TouchableHighlight.propTypes)); ``` :warning: The plugin is breaking that code if it ends up removing `TouchableHighlight.propTypes`. Make sure you are: - Not using that pattern in your source code. If you do, explicitly **export** the `propTypes` to work around that limitation. - Not parsing the `node_modules`. If you do, test that your code is still working before shipping into production. [eslint-plugin-react has a rule forbid-foreign-prop-types](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/forbid-foreign-prop-types.md) that can help you make this plugin safer to use. ## License MIT