├── .babelrc ├── .circleci └── config.yml ├── .eslintignore ├── .eslintrc.js ├── .flowconfig ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── flow └── interfaces │ └── mocha.js ├── package.json ├── prettier.config.js ├── src ├── index.js ├── isAnnotatedForRemoval.js ├── isStatelessComponent.js └── remove.js ├── test ├── fixtures.test.js ├── fixtures │ ├── additional-libraries-regexp │ │ ├── actual.js │ │ ├── custom-prop-types.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ └── options.js │ ├── additional-libraries │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ └── options.json │ ├── bugfix-169 │ │ ├── actual.js │ │ └── expected-remove-es6.js │ ├── bugfix-175 │ │ ├── actual.js │ │ └── expected-unsafe-wrap-es6.js │ ├── bugfix-assignment │ │ ├── actual.js │ │ └── expected-remove-es6.js │ ├── class-comment-annotation │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ └── expected-remove-es6.js │ ├── class-name-matchers-no-match │ │ ├── actual.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── class-name-matchers │ │ ├── actual.js │ │ ├── expected-wrap-es5.js │ │ ├── expected-wrap-es6.js │ │ └── options.json │ ├── const-in-anonymous-validator │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── create-class │ │ ├── actual.js │ │ └── expected-remove-es6.js │ ├── dont-remove-used-import │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ └── options.json │ ├── es-class-assign-property-variable-export │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── es-class-assign-property-variable │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── es-class-assign-property │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── es-class-extend-component │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── es-class-extend-deopt │ │ ├── actual.js │ │ ├── expected-remove-es6.js │ │ └── expected-wrap-es6.js │ ├── es-class-extend-global-base-component │ │ ├── actual.js │ │ └── expected-remove-es6.js │ ├── es-class-inheritance │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── es-class-no-name │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── es-class-static-property │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── flow │ │ ├── actual.js │ │ ├── expected-wrap-es5.js │ │ └── options.json │ ├── ignore-filenames │ │ ├── actual.js │ │ ├── expected-remove-es6.js │ │ └── options.json │ ├── issue-106 │ │ ├── actual.js │ │ └── expected-wrap-es6.js │ ├── not-react-assign-property │ │ ├── actual.js │ │ ├── expected-remove-es6.js │ │ └── expected-wrap-es6.js │ ├── not-react │ │ ├── actual.js │ │ └── expected-remove-es6.js │ ├── react-create-class-custom-name-no-property-name │ │ ├── actual.js │ │ ├── expected-remove-es6.js │ │ ├── notReact.js │ │ └── options.json │ ├── react-create-class-custom-name │ │ ├── actual.js │ │ ├── expected-remove-es6.js │ │ └── options.json │ ├── react-create-class │ │ ├── actual.js │ │ └── expected-remove-es6.js │ ├── recursive │ │ ├── actual.js │ │ └── expected-remove-es6.js │ ├── remove-import-proptypes │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ └── options.json │ ├── shared-prop-type-variable │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── stateless-arrow-return-function │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── stateless-force-removal │ │ ├── actual.js │ │ └── expected-remove-es6.js │ ├── stateless-functional-components │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── stateless-return-undefined │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── unsafe-wrap │ │ ├── actual.js │ │ ├── expected.js │ │ └── options.json │ ├── variable-assignment-member-expressions │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ ├── variable-assignment │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ ├── expected-remove-es6.js │ │ ├── expected-wrap-es5.js │ │ └── expected-wrap-es6.js │ └── variable-comment-annotation │ │ ├── actual.js │ │ ├── expected-remove-es5.js │ │ └── expected-remove-es6.js ├── mocha.opts └── utils.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "ie": "10", 8 | "node": "6" 9 | } 10 | } 11 | ], 12 | "@babel/preset-react", 13 | "@babel/preset-flow" 14 | ], 15 | "plugins": [ 16 | "@babel/plugin-proposal-class-properties", 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Use the latest 2.1 version of CircleCI pipeline process engine. 2 | # See: https://circleci.com/docs/2.0/configuration-reference 3 | version: 2.1 4 | 5 | orbs: 6 | # The Node.js orb contains a set of prepackaged CircleCI configuration you can utilize 7 | # Orbs reduce the amount of configuration required for common tasks. 8 | # See the orb documentation here: https://circleci.com/developer/orbs/orb/circleci/node 9 | node: circleci/node@4.1 10 | 11 | 12 | jobs: 13 | # Below is the definition of your job to build and test your app, you can rename and customize it as you want. 14 | build-and-test: 15 | # These next lines define a Docker executor: https://circleci.com/docs/2.0/executor-types/ 16 | # You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub. 17 | # A list of available CircleCI Docker Convenience Images are available here: https://circleci.com/developer/images/image/cimg/node 18 | docker: 19 | - image: cimg/node:15.1 20 | # Then run your tests! 21 | # CircleCI will report the results back to your VCS provider. 22 | steps: 23 | # Checkout the code as the first step. 24 | - checkout 25 | # Next, the node orb's install-packages step will install the dependencies from a package.json. 26 | # The orb install-packages step will also automatically cache them for faster future runs. 27 | # If you are using yarn instead npm, remove the line above and uncomment the two lines below. 28 | - node/install-packages: 29 | pkg-manager: yarn 30 | - run: 31 | name: Run tests 32 | command: npm test 33 | 34 | workflows: 35 | # Below is the definition of your workflow. 36 | # Inside the workflow, you provide the jobs you want to run, e.g this workflow runs the build-and-test job above. 37 | # CircleCI will run this workflow on every commit. 38 | # For more details on extending your workflow, see the configuration docs: https://circleci.com/docs/2.0/configuration-reference/#workflows 39 | sample: 40 | jobs: 41 | - build-and-test 42 | # For running simple node tests, you could optionally use the node/test job from the orb to replicate and replace the job above in fewer lines. 43 | # - node/test 44 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /test/fixtures/ 2 | /lib 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, // So parent files don't get applied 3 | env: { 4 | es6: true, 5 | browser: true, 6 | node: true, 7 | }, 8 | globals: { 9 | preval: false, 10 | }, 11 | extends: ['airbnb', 'plugin:import/recommended'], 12 | parser: 'babel-eslint', 13 | parserOptions: { 14 | ecmaVersion: 7, 15 | sourceType: 'module', 16 | }, 17 | plugins: ['babel', 'flowtype', 'import', 'jsx-a11y', 'prettier'], 18 | settings: { 19 | 'import/resolver': { 20 | node: { 21 | // As configured in webpack 22 | moduleDirectory: ['node_modules', 'src'], 23 | }, 24 | }, 25 | }, 26 | rules: { 27 | 'arrow-body-style': 'off', // Not our taste? 28 | 'max-len': 'off', // Not our taste? 29 | 'arrow-parens': 'off', // Incompatible with prettier 30 | 'no-confusing-arrow': 'off', // Incompatible with prettier 31 | indent: 'off', // Incompatible with prettier 32 | 'space-before-function-paren': 'off', // Incompatible with prettier 33 | semi: ['error', 'never'], 34 | 'consistent-this': ['error', 'self'], 35 | 'no-console': ['error', { allow: ['time', 'timeEnd'] }], // airbnb is using warn 36 | 'no-alert': 'error', // airbnb is using warn 37 | 'function-paren-newline': 'off', // Incompatible with prettier 38 | 'prefer-destructuring': 'off', // Incompatible with prettier 39 | 'object-curly-newline': 'off', // Incompatible with prettier 40 | 'semi-style': 'off', // Incompatible with prettier 41 | 'object-curly-spacing': 'off', // use babel plugin rule 42 | 'no-restricted-properties': 'off', // To remove once react-docgen support ** operator. 43 | 'no-mixed-operators': 'off', // allow a + b * c instead of a + (b * c), prettier conflict 44 | 'comma-dangle': [ 45 | 'error', 46 | { 47 | arrays: 'always-multiline', 48 | objects: 'always-multiline', 49 | imports: 'always-multiline', 50 | exports: 'always-multiline', 51 | functions: 'never', 52 | }, 53 | ], 54 | 'no-unused-vars': ['error', { vars: 'all', args: 'after-used', ignoreRestSiblings: true }], 55 | 56 | 'babel/object-curly-spacing': ['error', 'always'], 57 | 58 | 'import/unambiguous': 'off', 59 | 'import/no-unresolved': 'off', 60 | 'import/no-named-as-default': 'off', 61 | 'import/extensions': 'off', 62 | 'import/no-extraneous-dependencies': 'off', 63 | 'import/prefer-default-export': 'off', 64 | 65 | 'react/jsx-handler-names': [ 66 | 'error', 67 | { 68 | // airbnb is disabling this rule 69 | eventHandlerPrefix: 'handle', 70 | eventHandlerPropPrefix: 'on', 71 | }, 72 | ], 73 | 'react/jsx-indent': 'off', // Incompatible with prettier 74 | 'react/jsx-wrap-multilines': 'off', // Incompatible with prettier 75 | 'react/jsx-indent-props': 'off', // Incompatible with prettier 76 | 'react/jsx-closing-bracket-location': 'off', // Incompatible with prettier 77 | 'react/require-default-props': 'off', // airbnb use error 78 | 'react/forbid-prop-types': 'off', // airbnb use error 79 | 'react/jsx-filename-extension': ['error', { extensions: ['.js'] }], // airbnb is using .jsx 80 | 'react/no-danger': 'error', // airbnb is using warn 81 | 'react/no-direct-mutation-state': 'error', // airbnb is disabling this rule 82 | 'react/no-find-dom-node': 'off', // I don't know 83 | 'react/no-unused-prop-types': 'off', // Is still buggy 84 | 'react/sort-prop-types': 'error', // airbnb do nothing here. 85 | 'react/sort-comp': [ 86 | 2, 87 | { 88 | order: [ 89 | 'type-annotations', 90 | 'static-methods', 91 | 'props', 92 | 'lifecycle', 93 | // '/^handle.+$/', // wishlist -- needs above first 94 | // '/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/', // wishlist -- needs above first 95 | 'everything-else', 96 | '/^render.+$/', 97 | 'render', 98 | ], 99 | }, 100 | ], 101 | 'react/jsx-curly-brace-presence': 'off', // Incompatible with prettier 102 | 'react/jsx-closing-tag-location': 'off', // Incompatible with prettier 103 | 104 | 'prettier/prettier': 'error', 105 | 106 | 'jsx-a11y/no-autofocus': 'off', 107 | 'jsx-a11y/label-has-for': 'off', // Buggy 108 | 'jsx-a11y/anchor-is-valid': [ 109 | 'error', 110 | { 111 | components: ['Link'], 112 | specialLink: ['route'], 113 | aspects: ['noHref', 'invalidHref', 'preferButton'], 114 | }, 115 | ], 116 | }, 117 | } 118 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [libs] 2 | flow/interfaces 3 | 4 | [options] 5 | module.ignore_non_literal_requires=true 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # npm 2 | /node_modules 3 | 4 | # build 5 | /lib 6 | 7 | # log 8 | *.log 9 | 10 | # OS files 11 | .DS_STORE 12 | 13 | # No npm lockfiles 14 | npm-shrinkwrap.json 15 | package-lock.json 16 | 17 | # JetBrains IDE 18 | .idea 19 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /* 2 | !/src/*.js 3 | !/lib/*.js 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | All notable changes are described on the [Releases](https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types/releases) page. 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Nikita Gusakov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # babel-plugin-transform-react-remove-prop-types 2 | 3 | > Remove unnecessary React propTypes from the production build. 4 | 5 | [![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) 6 | [![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) 7 | [![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) 8 | 9 | [![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) 10 | [![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) 11 | 12 | ## Installation 13 | 14 | ```sh 15 | npm install --save-dev babel-plugin-transform-react-remove-prop-types 16 | ``` 17 | 18 | ## The problem solved 19 | 20 | Remove React `propTypes` from the production build, as they are only used in development. 21 | You can **save bandwidth** by removing them. 22 | 23 | ## Example 24 | 25 | **In** 26 | ```jsx 27 | const Baz = (props) => ( 28 |
29 | ); 30 | 31 | Baz.propTypes = { 32 | className: PropTypes.string 33 | }; 34 | ``` 35 | 36 | **Out** 37 | ```jsx 38 | const Baz = (props) => ( 39 |
40 | ); 41 | ``` 42 | 43 | ### With comment annotation 44 | 45 | The majority of cases should be addressed by default by this plugin. 46 | 47 | 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: 48 | 49 | ```js 50 | Component.propTypes /* remove-proptypes */ = {} 51 | ``` 52 | 53 | ## Usage 54 | 55 | ### Via `.babelrc` (Recommended) 56 | 57 | **.babelrc** 58 | 59 | without options: 60 | ```json 61 | { 62 | "env": { 63 | "production": { 64 | "plugins": ["transform-react-remove-prop-types"] 65 | } 66 | } 67 | } 68 | ``` 69 | 70 | with options: 71 | ```json 72 | { 73 | "env": { 74 | "production": { 75 | "plugins": [ 76 | ["transform-react-remove-prop-types", { 77 | "mode": "wrap", 78 | "ignoreFilenames": ["node_modules"] 79 | }] 80 | ] 81 | } 82 | } 83 | } 84 | ``` 85 | 86 | ### Via CLI 87 | 88 | ```sh 89 | babel --plugins transform-react-remove-prop-types script.js 90 | ``` 91 | 92 | ### Via Node API 93 | 94 | without options: 95 | ```js 96 | require('babel-core').transform('code', { 97 | plugins: [ 98 | 'transform-react-remove-prop-types', 99 | ], 100 | }); 101 | ``` 102 | 103 | with options: 104 | ```js 105 | require('babel-core').transform('code', { 106 | plugins: [ 107 | [ 108 | 'transform-react-remove-prop-types', 109 | { 110 | mode: 'wrap', 111 | ignoreFilenames: ['node_modules'], 112 | }, 113 | ], 114 | ], 115 | }); 116 | ``` 117 | 118 | ## Options 119 | 120 | ### `mode` 121 | 122 | - `remove` (default): 123 | the `propTypes` definitions are removed from the source code. 124 | - `wrap`: 125 | the `propTypes` definitions are wrapped with the following code: 126 | ```js 127 | Component.propTypes = process.env.NODE_ENV !== "production" ? { 128 | // ... 129 | } : {}; 130 | ``` 131 | 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. 132 | - `unsafe-wrap`: 133 | the `propTypes` definitions are wrapped with the following code: 134 | ```js 135 | if (process.env.NODE_ENV !== "production") { 136 | Component.propTypes = { 137 | // ... 138 | } 139 | } 140 | ``` 141 | Accessing `Component.propTypes.className` will throw. 142 | 143 | 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). 144 | They are not intended to be used by application authors. 145 | 146 | ### `removeImport` 147 | 148 | - `true`: the import statements are removed as well. This option only works if `mode` is set to `remove`: 149 | ```js 150 | import PropTypes from 'prop-types' 151 | ``` 152 | - `false` (default): does not remove the import statements. 153 | 154 | ### `ignoreFilenames` 155 | 156 | This filter generates a regular expression. 157 | Any filenames containing one of the array's strings will be ignored. 158 | By **default**, we match everything. 159 | 160 | Following the [Is it safe?](#user-content-is-it-safe) section, you might encounter a component 161 | depending on the `propTypes` at runtime to work. 162 | For this reason, we provide an array options to filter out some files and folders. 163 | For instance, you can ignore all the npm modules: 164 | ```js 165 | ignoreFilenames: ['node_modules'], 166 | ``` 167 | 168 | ### `additionalLibraries` 169 | 170 | This option gives the possibility to remove other `propTypes` in addition to the canonical `prop-types`. 171 | 172 | For instance, by default 173 | ```js 174 | import PropTypes from 'prop-types' 175 | import ImmutablePropTypes from 'react-immutable-proptypes' 176 | ``` 177 | will result in the latter not to be removed, while with: 178 | ```js 179 | additionalLibraries: ['react-immutable-proptypes'], 180 | ``` 181 | both will be removed. 182 | 183 | #### Regular expressions 184 | 185 | 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. 186 | 187 | This would be particularly useful when using custom prop types validators, implemented as part of your own source code. For example 188 | 189 | ```js 190 | import CustomPropTypes from '../../prop-types/my-own-validator' 191 | import OtherCustomPropTypes from '../../prop-types/my-other-validator' 192 | ``` 193 | 194 | would be removed with the following setting 195 | 196 | ```js 197 | additionalLibraries: [/\/prop-types\/.*$/] 198 | ``` 199 | 200 | If you use an index file 201 | 202 | ```js 203 | import CustomPropTypes from '../../prop-types' 204 | ``` 205 | 206 | you could set it up as 207 | 208 | ```js 209 | additionalLibraries: [/\/prop-types$/] 210 | ``` 211 | 212 | ### `classNameMatchers` 213 | 214 | Use this option to enable this plugin to run on components that extend a class different than `React.Component` or `React.PureComponent`. 215 | 216 | Given this example: 217 | ```js 218 | class MyComponent extends BaseComponent { 219 | ... 220 | } 221 | ``` 222 | 223 | You would use: 224 | ```js 225 | classNameMatchers: ["BaseComponent"] 226 | ``` 227 | 228 | ### `createReactClassName` 229 | 230 | Use this option to set a custom name for the import of the `create-react-class` package that is different than `createReactClass`. 231 | 232 | Given this example: 233 | 234 | ```js 235 | import createClass from 'create-react-class'; 236 | ``` 237 | 238 | You would use: 239 | 240 | ```js 241 | createReactClassName: 'createClass' 242 | ``` 243 | 244 | ## Is it safe? 245 | 246 | If you are using the `propTypes` in a conventional way, 247 | i.e by using them to perform type checking on the properties, that plugin should be **safe to use**. 248 | 249 | However, some libraries are accessing the `propTypes` on the component directly. 250 | 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: 251 | ```js 252 | const touchableProps = pick(restProps, Object.keys(TouchableHighlight.propTypes)); 253 | ``` 254 | :warning: The plugin is breaking that code if it ends up removing `TouchableHighlight.propTypes`. 255 | 256 | Make sure you are: 257 | - Not using that pattern in your source code. 258 | If you do, explicitly **export** the `propTypes` to work around that limitation. 259 | - Not parsing the `node_modules`. 260 | If you do, test that your code is still working before shipping into production. 261 | 262 | [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. 263 | 264 | ## License 265 | 266 | MIT 267 | -------------------------------------------------------------------------------- /flow/interfaces/mocha.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | type TestFunction = (done: () => void) => void | Promise 4 | 5 | declare var describe: { 6 | (name: string, spec: () => void): void, 7 | only(description: string, spec: () => void): void, 8 | skip(description: string, spec: () => void): void, 9 | timeout(ms: number): void, 10 | } 11 | 12 | declare var context: typeof describe 13 | 14 | declare var it: { 15 | (name: string, spec?: TestFunction): void, 16 | only(description: string, spec: TestFunction): void, 17 | skip(description: string, spec: TestFunction): void, 18 | timeout(ms: number): void, 19 | } 20 | 21 | declare function before(method: TestFunction): void 22 | declare function beforeEach(method: TestFunction): void 23 | declare function after(method: TestFunction): void 24 | declare function afterEach(method: TestFunction): void 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-plugin-transform-react-remove-prop-types", 3 | "version": "0.4.24", 4 | "description": "Remove unnecessary React propTypes from the production build", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "lint": "eslint . && echo \"eslint: no lint errors\"", 8 | "test:unit": "mocha", 9 | "test:watch": "mocha -w", 10 | "prettier": "find . -name \"*.js\" | grep -v -f .eslintignore | xargs prettier --write", 11 | "test": "npm run lint && npm run test:unit", 12 | "prebuild": "rm -rf lib/", 13 | "build": "babel src --out-dir lib", 14 | "version": "npm run build && pkgfiles" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types.git" 19 | }, 20 | "keywords": [ 21 | "babel", 22 | "babel-plugin", 23 | "react", 24 | "minification", 25 | "propTypes" 26 | ], 27 | "author": "Nikita Gusakov", 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types/issues" 31 | }, 32 | "devDependencies": { 33 | "@babel/cli": "^7.1.0", 34 | "@babel/core": "^7.1.0", 35 | "@babel/generator": "^7.0.0", 36 | "@babel/plugin-external-helpers": "^7.0.0", 37 | "@babel/plugin-proposal-class-properties": "^7.1.0", 38 | "@babel/plugin-transform-flow-strip-types": "^7.0.0", 39 | "@babel/preset-env": "^7.1.0", 40 | "@babel/preset-flow": "^7.0.0", 41 | "@babel/preset-react": "^7.0.0", 42 | "@babel/register": "^7.0.0", 43 | "babel-eslint": "^9.0.0", 44 | "babel-plugin-flow-react-proptypes": "^6.1.0", 45 | "chai": "^4.1.2", 46 | "eslint": "^4.11.0", 47 | "eslint-config-airbnb": "^16.1.0", 48 | "eslint-plugin-babel": "^4.1.2", 49 | "eslint-plugin-flowtype": "^2.39.1", 50 | "eslint-plugin-import": "^2.8.0", 51 | "eslint-plugin-jsx-a11y": "^6.0.2", 52 | "eslint-plugin-mocha": "^4.11.0", 53 | "eslint-plugin-prettier": "^2.3.1", 54 | "eslint-plugin-react": "^7.4.0", 55 | "globby": "^8.0.1", 56 | "mocha": "^4.0.1", 57 | "pkgfiles": "^2.3.2", 58 | "prettier": "^1.14.3" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | singleQuote: true, 4 | trailingComma: 'es5', 5 | bracketSpacing: true, 6 | jsxBracketSameLine: false, 7 | parser: 'babylon', 8 | semi: false, 9 | } 10 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require, import/no-dynamic-require */ 2 | 3 | // import generate from 'babel-generator'; 4 | // console.log(generate(node).code); 5 | import isAnnotatedForRemoval from './isAnnotatedForRemoval' 6 | import isStatelessComponent from './isStatelessComponent' 7 | import remove from './remove' 8 | 9 | function isPathReactClass(path, globalOptions) { 10 | const node = path.node 11 | const matchers = globalOptions.classNameMatchers 12 | 13 | if (path.matchesPattern('React.Component') || path.matchesPattern('React.PureComponent')) { 14 | return true 15 | } 16 | 17 | if (node && (node.name === 'Component' || node.name === 'PureComponent')) { 18 | return true 19 | } 20 | 21 | if (node && matchers && matchers.test(node.name)) { 22 | return true 23 | } 24 | 25 | return false 26 | } 27 | 28 | function isReactClass(superClass, scope, globalOptions) { 29 | if (!superClass.node) { 30 | return false 31 | } 32 | 33 | let answer = false 34 | 35 | if (isPathReactClass(superClass, globalOptions)) { 36 | answer = true 37 | } else if (superClass.node.name) { 38 | // Check for inheritance 39 | const className = superClass.node.name 40 | const binding = scope.getBinding(className) 41 | if (!binding) { 42 | answer = false 43 | } else { 44 | const bindingSuperClass = binding.path.get('superClass') 45 | 46 | if (isPathReactClass(bindingSuperClass, globalOptions)) { 47 | answer = true 48 | } 49 | } 50 | } 51 | 52 | return answer 53 | } 54 | 55 | function areSetsEqual(set1, set2) { 56 | if (set1 === set2) { 57 | return true 58 | } 59 | 60 | if (set1.size !== set2.size) { 61 | return false 62 | } 63 | 64 | return !Array.from(set1).some(item => !set2.has(item)) 65 | } 66 | 67 | function memberExpressionRootIdentifier(path) { 68 | // Traverse up to the parent before the topmost member expression, and then 69 | // traverse back down to find the topmost identifier. It seems like there 70 | // might be a better way to do this. 71 | const parent = path.findParent(p => !p.isMemberExpression()) 72 | const { type } = parent.node 73 | 74 | let memberExpression 75 | if (type === 'ObjectProperty') { 76 | // The topmost MemberExpression's parent is an object property, so the 77 | // topmost MemberExpression should be the value. 78 | memberExpression = parent.get('value') 79 | } 80 | 81 | if (!memberExpression || memberExpression.type !== 'MemberExpression') { 82 | // This case is currently unhandled by this plugin. 83 | return null 84 | } 85 | 86 | // We have a topmost MemberExpression now, so we want to traverse down the 87 | // left half untli we no longer see MemberExpressions. This node will give us 88 | // our leftmost identifier. 89 | while (memberExpression.node.object.type === 'MemberExpression') { 90 | memberExpression = memberExpression.get('object') 91 | } 92 | 93 | return memberExpression.get('object') 94 | } 95 | 96 | export default function(api) { 97 | const { template, types, traverse } = api 98 | 99 | const nestedIdentifiers = new Set() 100 | const removedPaths = new WeakSet() 101 | const collectNestedIdentifiers = { 102 | Identifier(path) { 103 | if (path.parent.type === 'MemberExpression') { 104 | // foo.bar 105 | 106 | const root = memberExpressionRootIdentifier(path) 107 | if (root) { 108 | nestedIdentifiers.add(root.node.name) 109 | } 110 | 111 | return 112 | } 113 | 114 | if ( 115 | path.parent.type === 'ObjectProperty' && 116 | (path.parent.key === path.node || path.parent.shorthand) 117 | ) { 118 | // { foo: 'bar' } 119 | // { foo } 120 | return 121 | } 122 | 123 | nestedIdentifiers.add(path.node.name) 124 | }, 125 | } 126 | 127 | return { 128 | visitor: { 129 | Program(programPath, state) { 130 | let ignoreFilenames 131 | let classNameMatchers 132 | 133 | if (state.opts.ignoreFilenames) { 134 | ignoreFilenames = new RegExp(state.opts.ignoreFilenames.join('|'), 'i') 135 | } else { 136 | ignoreFilenames = undefined 137 | } 138 | 139 | if (state.opts.classNameMatchers) { 140 | classNameMatchers = new RegExp(state.opts.classNameMatchers.join('|')) 141 | } else { 142 | classNameMatchers = undefined 143 | } 144 | 145 | const globalOptions = { 146 | visitedKey: `transform-react-remove-prop-types${Date.now()}`, 147 | unsafeWrapTemplate: template( 148 | ` 149 | if (process.env.NODE_ENV !== "production") { 150 | NODE; 151 | } 152 | `, 153 | { placeholderPattern: /^NODE$/ } 154 | ), 155 | wrapTemplate: ({ LEFT, RIGHT }, options = {}) => { 156 | const { as = 'assignmentExpression' } = options 157 | const right = template.expression( 158 | ` 159 | process.env.NODE_ENV !== "production" ? RIGHT : {} 160 | `, 161 | { placeholderPattern: /^(LEFT|RIGHT)$/ } 162 | )({ RIGHT }) 163 | switch (as) { 164 | case 'variableDeclarator': 165 | return types.variableDeclarator(LEFT, right) 166 | case 'assignmentExpression': 167 | return types.assignmentExpression('=', LEFT, right) 168 | default: 169 | throw new Error(`unrecognized template type ${as}`) 170 | } 171 | }, 172 | mode: state.opts.mode || 'remove', 173 | ignoreFilenames, 174 | types, 175 | removeImport: state.opts.removeImport || false, 176 | libraries: (state.opts.additionalLibraries || []).concat('prop-types'), 177 | classNameMatchers, 178 | createReactClassName: state.opts.createReactClassName || 'createReactClass', 179 | } 180 | 181 | if (state.opts.plugins) { 182 | const pluginsState = state 183 | const pluginsVisitors = state.opts.plugins.map(pluginOpts => { 184 | const pluginName = typeof pluginOpts === 'string' ? pluginOpts : pluginOpts[0] 185 | 186 | if (typeof pluginOpts !== 'string') { 187 | pluginsState.opts = { 188 | ...pluginsState.opts, 189 | ...pluginOpts[1], 190 | } 191 | } 192 | 193 | let plugin = require(pluginName) 194 | if (typeof plugin !== 'function') { 195 | plugin = plugin.default 196 | } 197 | 198 | return plugin(api).visitor 199 | }) 200 | 201 | traverse( 202 | programPath.parent, 203 | traverse.visitors.merge(pluginsVisitors), 204 | programPath.scope, 205 | pluginsState, 206 | programPath.parentPath 207 | ) 208 | } 209 | 210 | // On program start, do an explicit traversal up front for this plugin. 211 | programPath.traverse({ 212 | ObjectProperty: { 213 | exit(path) { 214 | const node = path.node 215 | 216 | if (node.computed || node.key.name !== 'propTypes') { 217 | return 218 | } 219 | 220 | const parent = path.findParent(currentNode => { 221 | if (currentNode.type !== 'CallExpression') { 222 | return false 223 | } 224 | 225 | return ( 226 | currentNode.get('callee').node.name === globalOptions.createReactClassName || 227 | (currentNode.get('callee').node.property && 228 | currentNode.get('callee').node.property.name === 'createClass') 229 | ) 230 | }) 231 | 232 | if (parent) { 233 | path.traverse(collectNestedIdentifiers) 234 | removedPaths.add(path) 235 | remove(path, globalOptions, { 236 | type: 'createClass', 237 | }) 238 | } 239 | }, 240 | }, 241 | 242 | // Here to support stage-1 transform-class-properties. 243 | ClassProperty(path) { 244 | const { node, scope } = path 245 | 246 | if (node.key.name === 'propTypes') { 247 | const pathClassDeclaration = scope.path 248 | 249 | if (isReactClass(pathClassDeclaration.get('superClass'), scope, globalOptions)) { 250 | path.traverse(collectNestedIdentifiers) 251 | removedPaths.add(path) 252 | remove(path, globalOptions, { 253 | type: 'class static', 254 | pathClassDeclaration, 255 | }) 256 | } 257 | } 258 | }, 259 | 260 | AssignmentExpression(path) { 261 | const { node, scope } = path 262 | 263 | if ( 264 | node.left.computed || 265 | !node.left.property || 266 | node.left.property.name !== 'propTypes' 267 | ) { 268 | return 269 | } 270 | 271 | const forceRemoval = isAnnotatedForRemoval(path.node.left) 272 | 273 | if (forceRemoval) { 274 | path.traverse(collectNestedIdentifiers) 275 | removedPaths.add(path) 276 | remove(path, globalOptions, { type: 'assign' }) 277 | return 278 | } 279 | 280 | const className = node.left.object.name 281 | const binding = scope.getBinding(className) 282 | 283 | if (!binding) { 284 | return 285 | } 286 | 287 | if (binding.path.isClassDeclaration()) { 288 | const superClass = binding.path.get('superClass') 289 | 290 | if (isReactClass(superClass, scope, globalOptions)) { 291 | path.traverse(collectNestedIdentifiers) 292 | removedPaths.add(path) 293 | remove(path, globalOptions, { type: 'assign' }) 294 | } 295 | } else if (isStatelessComponent(binding.path)) { 296 | path.traverse(collectNestedIdentifiers) 297 | removedPaths.add(path) 298 | remove(path, globalOptions, { type: 'assign' }) 299 | } 300 | }, 301 | }) 302 | 303 | let skippedIdentifiers = 0 304 | const removeNewlyUnusedIdentifiers = { 305 | VariableDeclarator(path) { 306 | // Only consider the top level scope. 307 | if (path.scope.block.type !== 'Program') { 308 | return 309 | } 310 | 311 | if (['ObjectPattern', 'ArrayPattern'].includes(path.node.id.type)) { 312 | // Object or Array destructuring, so we will want to capture all 313 | // the names created by the destructuring. This currently doesn't 314 | // work, but would be good to improve. All of the names for 315 | // ObjectPattern can be collected like: 316 | // 317 | // path.node.id.properties.map(prop => prop.value.name); 318 | return 319 | } 320 | const { name } = path.node.id 321 | 322 | if (!nestedIdentifiers.has(name)) { 323 | return 324 | } 325 | 326 | const { referencePaths } = path.scope.getBinding(name) 327 | 328 | // Count the number of referencePaths that are not in the 329 | // removedPaths Set. We need to do this in order to support the wrap 330 | // option, which doesn't actually remove the references. 331 | const hasRemainingReferencePaths = referencePaths.some(referencePath => { 332 | const found = referencePath.find(path2 => removedPaths.has(path2)) 333 | return !found 334 | }) 335 | 336 | if (hasRemainingReferencePaths) { 337 | // There are still references to this identifier, so we need to 338 | // skip over it for now. 339 | skippedIdentifiers += 1 340 | return 341 | } 342 | 343 | removedPaths.add(path) 344 | nestedIdentifiers.delete(name) 345 | path.get('init').traverse(collectNestedIdentifiers) 346 | remove(path, globalOptions, { type: 'declarator' }) 347 | }, 348 | } 349 | 350 | let lastNestedIdentifiers = new Set() 351 | while ( 352 | !areSetsEqual(nestedIdentifiers, lastNestedIdentifiers) && 353 | nestedIdentifiers.size > 0 && 354 | skippedIdentifiers < nestedIdentifiers.size 355 | ) { 356 | lastNestedIdentifiers = new Set(nestedIdentifiers) 357 | skippedIdentifiers = 0 358 | programPath.scope.crawl() 359 | programPath.traverse(removeNewlyUnusedIdentifiers) 360 | } 361 | 362 | if (globalOptions.removeImport) { 363 | if (globalOptions.mode === 'remove') { 364 | programPath.scope.crawl() 365 | 366 | programPath.traverse({ 367 | ImportDeclaration(path) { 368 | const { source, specifiers } = path.node 369 | 370 | const found = globalOptions.libraries.some(library => { 371 | if (library instanceof RegExp) { 372 | return library.test(source.value) 373 | } 374 | 375 | return source.value === library 376 | }) 377 | 378 | if (!found) { 379 | return 380 | } 381 | 382 | const haveUsedSpecifiers = specifiers.some(specifier => { 383 | const importedIdentifierName = specifier.local.name 384 | const { referencePaths } = path.scope.getBinding(importedIdentifierName) 385 | return referencePaths.length > 0 386 | }) 387 | 388 | if (!haveUsedSpecifiers) { 389 | path.remove() 390 | } 391 | }, 392 | }) 393 | } else { 394 | throw new Error( 395 | 'transform-react-remove-prop-type: removeImport = true and mode != "remove" can not be used at the same time.' 396 | ) 397 | } 398 | } 399 | }, 400 | }, 401 | } 402 | } 403 | -------------------------------------------------------------------------------- /src/isAnnotatedForRemoval.js: -------------------------------------------------------------------------------- 1 | export default function isAnnotatedForRemoval(node) { 2 | const comments = node.trailingComments || [] 3 | 4 | return Boolean(comments.find(({ value }) => value.trim() === 'remove-proptypes')) 5 | } 6 | -------------------------------------------------------------------------------- /src/isStatelessComponent.js: -------------------------------------------------------------------------------- 1 | const traversed = Symbol('traversed') 2 | 3 | function isJSXElementOrReactCreateElement(path) { 4 | let visited = false 5 | 6 | path.traverse({ 7 | CallExpression(path2) { 8 | const callee = path2.get('callee') 9 | 10 | if ( 11 | callee.matchesPattern('React.createElement') || 12 | callee.matchesPattern('React.cloneElement') || 13 | callee.node.name === 'cloneElement' 14 | ) { 15 | visited = true 16 | } 17 | }, 18 | JSXElement() { 19 | visited = true 20 | }, 21 | }) 22 | 23 | return visited 24 | } 25 | 26 | function isReturningJSXElement(path, iteration = 0) { 27 | // Early exit for ArrowFunctionExpressions, there is no ReturnStatement node. 28 | if (path.node.init && path.node.init.body && isJSXElementOrReactCreateElement(path)) { 29 | return true 30 | } 31 | 32 | if (iteration > 20) { 33 | throw new Error('transform-react-remove-prop-type: infinite loop detected.') 34 | } 35 | 36 | let visited = false 37 | 38 | path.traverse({ 39 | ReturnStatement(path2) { 40 | // We have already found what we are looking for. 41 | if (visited) { 42 | return 43 | } 44 | 45 | const argument = path2.get('argument') 46 | 47 | // Nothing is returned 48 | if (!argument.node) { 49 | return 50 | } 51 | 52 | if (isJSXElementOrReactCreateElement(path2)) { 53 | visited = true 54 | return 55 | } 56 | 57 | if (argument.node.type === 'CallExpression') { 58 | const name = argument.get('callee').node.name 59 | const binding = path.scope.getBinding(name) 60 | 61 | if (!binding) { 62 | return 63 | } 64 | 65 | // Prevents infinite traverse loop. 66 | if (binding.path[traversed]) { 67 | return 68 | } 69 | 70 | binding.path[traversed] = true 71 | 72 | if (isReturningJSXElement(binding.path, iteration + 1)) { 73 | visited = true 74 | } 75 | } 76 | }, 77 | ArrowFunctionExpression(path2) { 78 | if (visited) { 79 | return 80 | } 81 | 82 | if (isJSXElementOrReactCreateElement(path2)) { 83 | visited = true 84 | } 85 | }, 86 | }) 87 | 88 | return visited 89 | } 90 | 91 | const VALID_POSSIBLE_STATELESS_COMPONENT_TYPES = ['VariableDeclarator', 'FunctionDeclaration'] 92 | 93 | // Returns `true` if the path represents a function which returns a JSXElement 94 | export default function isStatelessComponent(path) { 95 | if (VALID_POSSIBLE_STATELESS_COMPONENT_TYPES.indexOf(path.node.type) === -1) { 96 | return false 97 | } 98 | 99 | if (isReturningJSXElement(path)) { 100 | return true 101 | } 102 | 103 | return false 104 | } 105 | -------------------------------------------------------------------------------- /src/remove.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-param-reassign */ 2 | 3 | function isInside(scope, regex) { 4 | if (!scope.hub.file.opts) { 5 | return true 6 | } 7 | 8 | const filename = scope.hub.file.opts.filename 9 | 10 | if (!filename) { 11 | return true 12 | } 13 | 14 | if (!regex) { 15 | return false 16 | } 17 | 18 | return regex.test(filename) 19 | } 20 | 21 | // Remove a specific path. 22 | export default function remove(path, globalOptions, options) { 23 | const { 24 | visitedKey, 25 | unsafeWrapTemplate, 26 | wrapTemplate, 27 | mode, 28 | ignoreFilenames, 29 | types, 30 | } = globalOptions 31 | 32 | if (ignoreFilenames && isInside(path.scope, ignoreFilenames)) { 33 | return 34 | } 35 | 36 | // Prevent infinity loop. 37 | if (path.node[visitedKey]) { 38 | return 39 | } 40 | 41 | path.node[visitedKey] = true 42 | 43 | if (mode === 'remove') { 44 | // remove() crash in some conditions. 45 | if (path.parentPath.type === 'ConditionalExpression') { 46 | path.replaceWith(types.unaryExpression('void', types.numericLiteral(0))) 47 | } else { 48 | path.remove() 49 | } 50 | 51 | return 52 | } 53 | 54 | if (mode === 'wrap' || mode === 'unsafe-wrap') { 55 | switch (options.type) { 56 | // This is legacy, we do not optimize it. 57 | case 'createClass': 58 | break 59 | 60 | // Inspired from babel-plugin-transform-class-properties. 61 | case 'class static': { 62 | let ref 63 | let pathClassDeclaration = options.pathClassDeclaration 64 | 65 | if (!pathClassDeclaration.isClassExpression() && pathClassDeclaration.node.id) { 66 | ref = pathClassDeclaration.node.id 67 | } else { 68 | // Class without name not supported 69 | return 70 | } 71 | 72 | const node = types.expressionStatement( 73 | types.assignmentExpression( 74 | '=', 75 | types.memberExpression(ref, path.node.key), 76 | path.node.value 77 | ) 78 | ) 79 | 80 | // We need to append the node at the parent level in this case. 81 | if (pathClassDeclaration.parentPath.isExportDeclaration()) { 82 | pathClassDeclaration = pathClassDeclaration.parentPath 83 | } 84 | pathClassDeclaration.insertAfter(node) 85 | path.remove() 86 | break 87 | } 88 | 89 | case 'assign': 90 | if (mode === 'unsafe-wrap') { 91 | path.replaceWith( 92 | unsafeWrapTemplate({ 93 | NODE: path.node, 94 | }) 95 | ) 96 | } else { 97 | path.replaceWith( 98 | wrapTemplate({ 99 | LEFT: path.node.left, 100 | RIGHT: path.node.right, 101 | }) 102 | ) 103 | } 104 | path.node[visitedKey] = true 105 | break 106 | 107 | case 'declarator': 108 | path.replaceWith( 109 | wrapTemplate( 110 | { 111 | LEFT: path.node.id, 112 | RIGHT: path.node.init, 113 | }, 114 | { as: 'variableDeclarator' } 115 | ) 116 | ) 117 | path.node[visitedKey] = true 118 | break 119 | 120 | default: 121 | break 122 | } 123 | 124 | return 125 | } 126 | 127 | throw new Error(`transform-react-remove-prop-type: unsupported mode ${mode}.`) 128 | } 129 | -------------------------------------------------------------------------------- /test/fixtures.test.js: -------------------------------------------------------------------------------- 1 | // @flow weak 2 | /* eslint-env mocha */ 3 | 4 | import path from 'path' 5 | import fs from 'fs' 6 | import globby from 'globby' 7 | import { assert } from 'chai' 8 | import { transformFileSync } from '@babel/core' 9 | import babelPluginSyntaxJsx from '@babel/plugin-syntax-jsx' 10 | import babelPluginExternalHelpers from '@babel/plugin-external-helpers' 11 | import babelPluginTransformClassProperties from '@babel/plugin-proposal-class-properties' 12 | import babelPluginProposalObjectRestSpread from '@babel/plugin-proposal-object-rest-spread' 13 | import babelPluginTransformReactRemovePropTypes from '../src/index' 14 | import { trim } from './utils' 15 | 16 | const modes = ['options', 'remove-es5', 'wrap-es5', 'remove-es6', 'wrap-es6', 'unsafe-wrap-es6'] 17 | 18 | describe('fixtures', () => { 19 | const fixturesDir = path.join(__dirname, 'fixtures') 20 | 21 | fs.readdirSync(fixturesDir).forEach(caseName => { 22 | describe(`should work with ${caseName.split('-').join(' ')}`, () => { 23 | const fixtureDir = path.join(fixturesDir, caseName) 24 | 25 | // Only run a specific test 26 | // if (caseName !== 'const-in-anonymous-validator') { 27 | // return 28 | // } 29 | 30 | modes.forEach(mode => { 31 | let expected 32 | let options = {} 33 | 34 | const optionsPaths = globby.sync(path.join(fixtureDir, 'options.{js,json}')) 35 | 36 | optionsPaths.forEach(optionsPath => { 37 | options = require(optionsPath) // eslint-disable-line global-require, import/no-dynamic-require 38 | }) 39 | 40 | const filename = mode === 'options' ? 'expected.js' : `expected-${mode}.js` 41 | 42 | try { 43 | expected = fs.readFileSync(path.join(fixtureDir, filename)) 44 | expected = expected.toString() 45 | } catch (error) { 46 | // Only run the check if the expect file is or have an option provided. 47 | if (!options.throws) { 48 | return 49 | } 50 | } 51 | 52 | it(mode, () => { 53 | let babelConfig 54 | 55 | switch (mode) { 56 | case 'remove-es5': 57 | babelConfig = { 58 | plugins: [ 59 | babelPluginExternalHelpers, 60 | babelPluginProposalObjectRestSpread, 61 | [ 62 | babelPluginTransformReactRemovePropTypes, 63 | { 64 | ...options, 65 | mode: 'remove', 66 | }, 67 | ], 68 | ], 69 | } 70 | break 71 | 72 | case 'wrap-es5': 73 | babelConfig = { 74 | plugins: [ 75 | babelPluginExternalHelpers, 76 | babelPluginProposalObjectRestSpread, 77 | [ 78 | babelPluginTransformReactRemovePropTypes, 79 | { 80 | ...options, 81 | mode: 'wrap', 82 | }, 83 | ], 84 | ], 85 | } 86 | break 87 | 88 | case 'remove-es6': 89 | babelConfig = { 90 | babelrc: false, 91 | plugins: [ 92 | babelPluginExternalHelpers, 93 | babelPluginSyntaxJsx, 94 | babelPluginTransformClassProperties, 95 | babelPluginProposalObjectRestSpread, 96 | [ 97 | babelPluginTransformReactRemovePropTypes, 98 | { 99 | ...options, 100 | mode: 'remove', 101 | }, 102 | ], 103 | ], 104 | } 105 | break 106 | 107 | case 'wrap-es6': 108 | babelConfig = { 109 | babelrc: false, 110 | plugins: [ 111 | babelPluginExternalHelpers, 112 | babelPluginSyntaxJsx, 113 | babelPluginTransformClassProperties, 114 | babelPluginProposalObjectRestSpread, 115 | [ 116 | babelPluginTransformReactRemovePropTypes, 117 | { 118 | ...options, 119 | mode: 'wrap', 120 | }, 121 | ], 122 | ], 123 | } 124 | break 125 | 126 | case 'unsafe-wrap-es6': 127 | babelConfig = { 128 | babelrc: false, 129 | plugins: [ 130 | babelPluginExternalHelpers, 131 | babelPluginSyntaxJsx, 132 | babelPluginTransformClassProperties, 133 | babelPluginProposalObjectRestSpread, 134 | [ 135 | babelPluginTransformReactRemovePropTypes, 136 | { 137 | ...options, 138 | mode: 'unsafe-wrap', 139 | }, 140 | ], 141 | ], 142 | } 143 | break 144 | 145 | default: 146 | babelConfig = { 147 | plugins: [ 148 | babelPluginExternalHelpers, 149 | babelPluginProposalObjectRestSpread, 150 | [babelPluginTransformReactRemovePropTypes, options], 151 | ], 152 | } 153 | } 154 | 155 | try { 156 | const actual = transformFileSync(path.join(fixtureDir, 'actual.js'), babelConfig).code 157 | // Write the output 158 | // fs.writeFileSync(path.join(fixtureDir, filename), `${actual}\n`) 159 | assert.strictEqual(trim(actual), trim(expected)) 160 | } catch (err) { 161 | if (options.throws) { 162 | assert.strictEqual( 163 | err.message.indexOf(options.throws) > 0, 164 | true, 165 | `Expected to throw: ${options.throws}. Have: ${err.message}` 166 | ) 167 | } else { 168 | throw err 169 | } 170 | } 171 | }) 172 | }) 173 | }) 174 | }) 175 | }) 176 | -------------------------------------------------------------------------------- /test/fixtures/additional-libraries-regexp/actual.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import PropTypes from 'prop-types' 3 | import CustomPropTypes from './custom-prop-types' 4 | 5 | export default class Greeting extends Component { 6 | constructor (props, context) { 7 | super(props, context) 8 | const appName = context.store.getState().appName 9 | this.state = { 10 | appName: appName 11 | } 12 | } 13 | 14 | render () { 15 | return

Welcome {this.props.name} and {this.props.friends.join(', ')} to {this.state.appName}

; 16 | } 17 | } 18 | 19 | Greeting.propTypes = { 20 | name: PropTypes.string.isRequired, 21 | friends: CustomPropTypes.customValidator 22 | } 23 | -------------------------------------------------------------------------------- /test/fixtures/additional-libraries-regexp/custom-prop-types.js: -------------------------------------------------------------------------------- 1 | const customValidator = (props, propName, componentName) => { 2 | } 3 | 4 | export default { 5 | customValidator 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/additional-libraries-regexp/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireWildcard(require("react")); 9 | 10 | var Greeting = 11 | /*#__PURE__*/ 12 | function (_Component) { 13 | babelHelpers.inherits(Greeting, _Component); 14 | 15 | function Greeting(props, context) { 16 | var _this; 17 | 18 | babelHelpers.classCallCheck(this, Greeting); 19 | _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Greeting).call(this, props, context)); 20 | var appName = context.store.getState().appName; 21 | _this.state = { 22 | appName: appName 23 | }; 24 | return _this; 25 | } 26 | 27 | babelHelpers.createClass(Greeting, [{ 28 | key: "render", 29 | value: function render() { 30 | return _react.default.createElement("h1", null, "Welcome ", this.props.name, " and ", this.props.friends.join(', '), " to ", this.state.appName); 31 | } 32 | }]); 33 | return Greeting; 34 | }(_react.Component); 35 | 36 | exports.default = Greeting; 37 | -------------------------------------------------------------------------------- /test/fixtures/additional-libraries-regexp/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | export default class Greeting extends Component { 3 | constructor(props, context) { 4 | super(props, context); 5 | const appName = context.store.getState().appName; 6 | this.state = { 7 | appName: appName 8 | }; 9 | } 10 | 11 | render() { 12 | return

Welcome {this.props.name} and {this.props.friends.join(', ')} to {this.state.appName}

; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /test/fixtures/additional-libraries-regexp/options.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | additionalLibraries: [/\/custom-prop-types$/], 3 | removeImport: true 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/additional-libraries/actual.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import PropTypes from 'prop-types' 3 | import ImmutablePropTypes from 'react-immutable-proptypes' 4 | 5 | export default class Greeting extends Component { 6 | constructor (props, context) { 7 | super(props, context) 8 | const appName = context.store.getState().appName 9 | this.state = { 10 | appName: appName 11 | } 12 | } 13 | 14 | render () { 15 | return

Welcome {this.props.name} and {this.props.friends.join(', ')} to {this.state.appName}

; 16 | } 17 | } 18 | 19 | Greeting.propTypes = { 20 | name: PropTypes.string.isRequired, 21 | friends: ImmutablePropTypes.list.isRequired, 22 | } 23 | -------------------------------------------------------------------------------- /test/fixtures/additional-libraries/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireWildcard(require("react")); 9 | 10 | var Greeting = 11 | /*#__PURE__*/ 12 | function (_Component) { 13 | babelHelpers.inherits(Greeting, _Component); 14 | 15 | function Greeting(props, context) { 16 | var _this; 17 | 18 | babelHelpers.classCallCheck(this, Greeting); 19 | _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Greeting).call(this, props, context)); 20 | var appName = context.store.getState().appName; 21 | _this.state = { 22 | appName: appName 23 | }; 24 | return _this; 25 | } 26 | 27 | babelHelpers.createClass(Greeting, [{ 28 | key: "render", 29 | value: function render() { 30 | return _react.default.createElement("h1", null, "Welcome ", this.props.name, " and ", this.props.friends.join(', '), " to ", this.state.appName); 31 | } 32 | }]); 33 | return Greeting; 34 | }(_react.Component); 35 | 36 | exports.default = Greeting; 37 | -------------------------------------------------------------------------------- /test/fixtures/additional-libraries/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | export default class Greeting extends Component { 3 | constructor(props, context) { 4 | super(props, context); 5 | const appName = context.store.getState().appName; 6 | this.state = { 7 | appName: appName 8 | }; 9 | } 10 | 11 | render() { 12 | return

Welcome {this.props.name} and {this.props.friends.join(', ')} to {this.state.appName}

; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /test/fixtures/additional-libraries/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "additionalLibraries": ["react-immutable-proptypes"], 3 | "removeImport": true 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/bugfix-169/actual.js: -------------------------------------------------------------------------------- 1 | class Test extends React.Component { 2 | static propTypes = { 3 | columns: PropTypes.shape({ 4 | [constants.TEST]: STRING_PROP_TYPE, 5 | }), 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/bugfix-169/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | class Test extends React.Component {} 2 | -------------------------------------------------------------------------------- /test/fixtures/bugfix-175/actual.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const sharedPropType = PropTypes.number; 5 | 6 | export default class Foo extends React.Component { 7 | static propTypes = { 8 | bar: sharedPropType, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/bugfix-175/expected-unsafe-wrap-es6.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | const sharedPropType = process.env.NODE_ENV !== "production" ? PropTypes.number : {}; 4 | export default class Foo extends React.Component {} 5 | process.env.NODE_ENV !== "production" ? Foo.propTypes = { 6 | bar: sharedPropType 7 | } : void 0; 8 | -------------------------------------------------------------------------------- /test/fixtures/bugfix-assignment/actual.js: -------------------------------------------------------------------------------- 1 | var App = { 2 | init: function(assets) { 3 | assets = assets || {}; 4 | if (assets.templates) { 5 | TemplateStore.init(assets.templates); 6 | } 7 | }, 8 | }; 9 | 10 | const FormattedPlural = () =>
; 11 | 12 | process.env.NODE_ENV !== 'production' ? FormattedPlural.propTypes = { 13 | value: PropTypes.any.isRequired, 14 | } : void 0; 15 | -------------------------------------------------------------------------------- /test/fixtures/bugfix-assignment/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | var App = { 2 | init: function (assets) { 3 | assets = assets || {}; 4 | 5 | if (assets.templates) { 6 | TemplateStore.init(assets.templates); 7 | } 8 | } 9 | }; 10 | 11 | const FormattedPlural = () =>
; 12 | 13 | process.env.NODE_ENV !== 'production' ? void 0 : void 0; 14 | -------------------------------------------------------------------------------- /test/fixtures/class-comment-annotation/actual.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | import ParentComponent from './Parent' 4 | 5 | export default class Foo extends ParentComponent { 6 | render () {} 7 | } 8 | 9 | Foo.propTypes /* remove-proptypes */ = { 10 | bar: PropTypes.string.isRequired, 11 | } 12 | -------------------------------------------------------------------------------- /test/fixtures/class-comment-annotation/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireDefault(require("react")); 9 | 10 | var _propTypes = babelHelpers.interopRequireDefault(require("prop-types")); 11 | 12 | var _Parent = babelHelpers.interopRequireDefault(require("./Parent")); 13 | 14 | var Foo = 15 | /*#__PURE__*/ 16 | function (_ParentComponent) { 17 | babelHelpers.inherits(Foo, _ParentComponent); 18 | 19 | function Foo() { 20 | babelHelpers.classCallCheck(this, Foo); 21 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).apply(this, arguments)); 22 | } 23 | 24 | babelHelpers.createClass(Foo, [{ 25 | key: "render", 26 | value: function render() {} 27 | }]); 28 | return Foo; 29 | }(_Parent.default); 30 | 31 | exports.default = Foo; 32 | -------------------------------------------------------------------------------- /test/fixtures/class-comment-annotation/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import ParentComponent from './Parent'; 4 | export default class Foo extends ParentComponent { 5 | render() {} 6 | 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/class-name-matchers-no-match/actual.js: -------------------------------------------------------------------------------- 1 | import BaseComponent from 'components/base' 2 | 3 | class Foo extends BaseComponent { 4 | render() {} 5 | } 6 | 7 | Foo.propTypes = { 8 | bar: PropTypes.string, 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/class-name-matchers-no-match/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var _base = babelHelpers.interopRequireDefault(require("components/base")); 4 | 5 | var Foo = 6 | /*#__PURE__*/ 7 | function (_BaseComponent) { 8 | babelHelpers.inherits(Foo, _BaseComponent); 9 | 10 | function Foo() { 11 | babelHelpers.classCallCheck(this, Foo); 12 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).apply(this, arguments)); 13 | } 14 | 15 | babelHelpers.createClass(Foo, [{ 16 | key: "render", 17 | value: function render() {} 18 | }]); 19 | return Foo; 20 | }(_base.default); 21 | 22 | Foo.propTypes = { 23 | bar: PropTypes.string 24 | }; 25 | -------------------------------------------------------------------------------- /test/fixtures/class-name-matchers-no-match/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | import BaseComponent from 'components/base'; 2 | 3 | class Foo extends BaseComponent { 4 | render() {} 5 | 6 | } 7 | 8 | Foo.propTypes = { 9 | bar: PropTypes.string 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/class-name-matchers/actual.js: -------------------------------------------------------------------------------- 1 | import BaseComponent from 'components/base' 2 | 3 | class Foo extends BaseComponent { 4 | render() {} 5 | } 6 | 7 | Foo.propTypes = { 8 | bar: PropTypes.string, 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/class-name-matchers/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var _base = babelHelpers.interopRequireDefault(require("components/base")); 4 | 5 | var Foo = 6 | /*#__PURE__*/ 7 | function (_BaseComponent) { 8 | babelHelpers.inherits(Foo, _BaseComponent); 9 | 10 | function Foo() { 11 | babelHelpers.classCallCheck(this, Foo); 12 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).apply(this, arguments)); 13 | } 14 | 15 | babelHelpers.createClass(Foo, [{ 16 | key: "render", 17 | value: function render() {} 18 | }]); 19 | return Foo; 20 | }(_base.default); 21 | 22 | Foo.propTypes = process.env.NODE_ENV !== "production" ? { 23 | bar: PropTypes.string 24 | } : {}; 25 | -------------------------------------------------------------------------------- /test/fixtures/class-name-matchers/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | import BaseComponent from 'components/base'; 2 | 3 | class Foo extends BaseComponent { 4 | render() {} 5 | 6 | } 7 | 8 | Foo.propTypes = process.env.NODE_ENV !== "production" ? { 9 | bar: PropTypes.string 10 | } : {}; 11 | -------------------------------------------------------------------------------- /test/fixtures/class-name-matchers/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "classNameMatchers": ["BaseComponent"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/const-in-anonymous-validator/actual.js: -------------------------------------------------------------------------------- 1 | import React, {PropTypes} from 'react'; 2 | 3 | const Component = () => ( 4 |
5 | ); 6 | 7 | const referencedPropTypes = { 8 | variant3: () => { 9 | const willBeWrapped = 1; 10 | return null; 11 | } 12 | } 13 | 14 | Component.propTypes = { 15 | variant1: props => { 16 | const variants = [null]; 17 | return variantſ[0]; 18 | }, 19 | variant2: chainPropTypes( 20 | PropTypes.oneOf(['foo']), 21 | props => { 22 | const deprecatedVariants = [ 23 | 'display4', 24 | 'display3', 25 | 'display2', 26 | 'display1', 27 | 'headline', 28 | 'title', 29 | 'subheading', 30 | ]; 31 | 32 | return null; 33 | }, 34 | ), 35 | ...referencedPropTypes, 36 | }; 37 | 38 | export default Component; 39 | -------------------------------------------------------------------------------- /test/fixtures/const-in-anonymous-validator/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireWildcard(require("react")); 9 | 10 | var Component = function Component() { 11 | return _react.default.createElement("div", null); 12 | }; 13 | 14 | var _default = Component; 15 | exports.default = _default; 16 | -------------------------------------------------------------------------------- /test/fixtures/const-in-anonymous-validator/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | 3 | const Component = () =>
; 4 | 5 | export default Component; 6 | -------------------------------------------------------------------------------- /test/fixtures/const-in-anonymous-validator/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireWildcard(require("react")); 9 | 10 | var Component = function Component() { 11 | return _react.default.createElement("div", null); 12 | }; 13 | 14 | var referencedPropTypes = process.env.NODE_ENV !== "production" ? { 15 | variant3: function variant3() { 16 | var willBeWrapped = 1; 17 | return null; 18 | } 19 | } : {}; 20 | Component.propTypes = process.env.NODE_ENV !== "production" ? babelHelpers.objectSpread({ 21 | variant1: function variant1(props) { 22 | var variants = [null]; 23 | return variantſ[0]; 24 | }, 25 | variant2: chainPropTypes(_react.PropTypes.oneOf(['foo']), function (props) { 26 | var deprecatedVariants = ['display4', 'display3', 'display2', 'display1', 'headline', 'title', 'subheading']; 27 | return null; 28 | }) 29 | }, referencedPropTypes) : {}; 30 | var _default = Component; 31 | exports.default = _default; 32 | -------------------------------------------------------------------------------- /test/fixtures/const-in-anonymous-validator/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | 3 | const Component = () =>
; 4 | 5 | const referencedPropTypes = process.env.NODE_ENV !== "production" ? { 6 | variant3: () => { 7 | const willBeWrapped = 1; 8 | return null; 9 | } 10 | } : {}; 11 | Component.propTypes = process.env.NODE_ENV !== "production" ? babelHelpers.objectSpread({ 12 | variant1: props => { 13 | const variants = [null]; 14 | return variantſ[0]; 15 | }, 16 | variant2: chainPropTypes(PropTypes.oneOf(['foo']), props => { 17 | const deprecatedVariants = ['display4', 'display3', 'display2', 'display1', 'headline', 'title', 'subheading']; 18 | return null; 19 | }) 20 | }, referencedPropTypes) : {}; 21 | export default Component; 22 | -------------------------------------------------------------------------------- /test/fixtures/create-class/actual.js: -------------------------------------------------------------------------------- 1 | var _react2 = require('react'); 2 | var PropTypes = require('prop-types'); 3 | 4 | // react >= 15.6 5 | var Class1 = _react2.default.createClass({ 6 | displayName: 'Class1', 7 | propTypes: { 8 | foo: PropTypes.string, 9 | }, 10 | }); 11 | 12 | // react < 15.6 13 | var Class2 = _react2.default.createClass({ 14 | displayName: 'Class2', 15 | propTypes: { 16 | foo: _react2.default.PropTypes.string, 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /test/fixtures/create-class/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | var _react2 = require('react'); 2 | 3 | // react >= 15.6 4 | var Class1 = _react2.default.createClass({ 5 | displayName: 'Class1' 6 | }); // react < 15.6 7 | 8 | 9 | var Class2 = _react2.default.createClass({ 10 | displayName: 'Class2' 11 | }); 12 | -------------------------------------------------------------------------------- /test/fixtures/dont-remove-used-import/actual.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | export default class Greeting extends Component { 5 | constructor (props, context) { 6 | super(props, context) 7 | const appName = context.store.getState().appName 8 | this.state = { 9 | appName: appName 10 | } 11 | } 12 | 13 | render () { 14 | return

Welcome {this.props.name} to {this.state.appName}

; 15 | } 16 | } 17 | 18 | Greeting.propTypes = { 19 | name: PropTypes.string.isRequired 20 | } 21 | 22 | Greeting.contextTypes = { 23 | store: PropTypes.object 24 | } -------------------------------------------------------------------------------- /test/fixtures/dont-remove-used-import/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireWildcard(require("react")); 9 | 10 | var _propTypes = babelHelpers.interopRequireDefault(require("prop-types")); 11 | 12 | var Greeting = 13 | /*#__PURE__*/ 14 | function (_Component) { 15 | babelHelpers.inherits(Greeting, _Component); 16 | 17 | function Greeting(props, context) { 18 | var _this; 19 | 20 | babelHelpers.classCallCheck(this, Greeting); 21 | _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Greeting).call(this, props, context)); 22 | var appName = context.store.getState().appName; 23 | _this.state = { 24 | appName: appName 25 | }; 26 | return _this; 27 | } 28 | 29 | babelHelpers.createClass(Greeting, [{ 30 | key: "render", 31 | value: function render() { 32 | return _react.default.createElement("h1", null, "Welcome ", this.props.name, " to ", this.state.appName); 33 | } 34 | }]); 35 | return Greeting; 36 | }(_react.Component); 37 | 38 | exports.default = Greeting; 39 | Greeting.contextTypes = { 40 | store: _propTypes.default.object 41 | }; 42 | -------------------------------------------------------------------------------- /test/fixtures/dont-remove-used-import/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | export default class Greeting extends Component { 4 | constructor(props, context) { 5 | super(props, context); 6 | const appName = context.store.getState().appName; 7 | this.state = { 8 | appName: appName 9 | }; 10 | } 11 | 12 | render() { 13 | return

Welcome {this.props.name} to {this.state.appName}

; 14 | } 15 | 16 | } 17 | Greeting.contextTypes = { 18 | store: PropTypes.object 19 | }; 20 | -------------------------------------------------------------------------------- /test/fixtures/dont-remove-used-import/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "removeImport": true 3 | } -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property-variable-export/actual.js: -------------------------------------------------------------------------------- 1 | export const propTypes = { 2 | foo: PropTypes.string 3 | }; 4 | 5 | class Foo extends React.Component { 6 | render() {} 7 | } 8 | 9 | Foo.propTypes = propTypes; 10 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property-variable-export/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.propTypes = void 0; 7 | var propTypes = { 8 | foo: PropTypes.string 9 | }; 10 | exports.propTypes = propTypes; 11 | 12 | var Foo = 13 | /*#__PURE__*/ 14 | function (_React$Component) { 15 | babelHelpers.inherits(Foo, _React$Component); 16 | 17 | function Foo() { 18 | babelHelpers.classCallCheck(this, Foo); 19 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).apply(this, arguments)); 20 | } 21 | 22 | babelHelpers.createClass(Foo, [{ 23 | key: "render", 24 | value: function render() {} 25 | }]); 26 | return Foo; 27 | }(React.Component); 28 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property-variable-export/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | export const propTypes = { 2 | foo: PropTypes.string 3 | }; 4 | 5 | class Foo extends React.Component { 6 | render() {} 7 | 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property-variable-export/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.propTypes = void 0; 7 | var propTypes = { 8 | foo: PropTypes.string 9 | }; 10 | exports.propTypes = propTypes; 11 | 12 | var Foo = 13 | /*#__PURE__*/ 14 | function (_React$Component) { 15 | babelHelpers.inherits(Foo, _React$Component); 16 | 17 | function Foo() { 18 | babelHelpers.classCallCheck(this, Foo); 19 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).apply(this, arguments)); 20 | } 21 | 22 | babelHelpers.createClass(Foo, [{ 23 | key: "render", 24 | value: function render() {} 25 | }]); 26 | return Foo; 27 | }(React.Component); 28 | 29 | Foo.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; 30 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property-variable-export/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | export const propTypes = { 2 | foo: PropTypes.string 3 | }; 4 | 5 | class Foo extends React.Component { 6 | render() {} 7 | 8 | } 9 | 10 | Foo.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; 11 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property-variable/actual.js: -------------------------------------------------------------------------------- 1 | const propTypes = { 2 | foo: PropTypes.string 3 | }; 4 | 5 | class Foo extends React.Component { 6 | render() {} 7 | } 8 | 9 | Foo.propTypes = propTypes; 10 | 11 | class Getter extends React.Component { 12 | get foo() { 13 | return { foo: PropTypes.string }; 14 | } 15 | 16 | render() {} 17 | } 18 | 19 | Getter.propTypes = Getter.foo; 20 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property-variable/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Foo = 4 | /*#__PURE__*/ 5 | function (_React$Component) { 6 | babelHelpers.inherits(Foo, _React$Component); 7 | 8 | function Foo() { 9 | babelHelpers.classCallCheck(this, Foo); 10 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).apply(this, arguments)); 11 | } 12 | 13 | babelHelpers.createClass(Foo, [{ 14 | key: "render", 15 | value: function render() {} 16 | }]); 17 | return Foo; 18 | }(React.Component); 19 | 20 | var Getter = 21 | /*#__PURE__*/ 22 | function (_React$Component2) { 23 | babelHelpers.inherits(Getter, _React$Component2); 24 | 25 | function Getter() { 26 | babelHelpers.classCallCheck(this, Getter); 27 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Getter).apply(this, arguments)); 28 | } 29 | 30 | babelHelpers.createClass(Getter, [{ 31 | key: "render", 32 | value: function render() {} 33 | }, { 34 | key: "foo", 35 | get: function get() { 36 | return { 37 | foo: PropTypes.string 38 | }; 39 | } 40 | }]); 41 | return Getter; 42 | }(React.Component); 43 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property-variable/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | class Foo extends React.Component { 2 | render() {} 3 | 4 | } 5 | 6 | class Getter extends React.Component { 7 | get foo() { 8 | return { 9 | foo: PropTypes.string 10 | }; 11 | } 12 | 13 | render() {} 14 | 15 | } 16 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property-variable/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var propTypes = process.env.NODE_ENV !== "production" ? { 4 | foo: PropTypes.string 5 | } : {}; 6 | 7 | var Foo = 8 | /*#__PURE__*/ 9 | function (_React$Component) { 10 | babelHelpers.inherits(Foo, _React$Component); 11 | 12 | function Foo() { 13 | babelHelpers.classCallCheck(this, Foo); 14 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).apply(this, arguments)); 15 | } 16 | 17 | babelHelpers.createClass(Foo, [{ 18 | key: "render", 19 | value: function render() {} 20 | }]); 21 | return Foo; 22 | }(React.Component); 23 | 24 | Foo.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; 25 | 26 | var Getter = 27 | /*#__PURE__*/ 28 | function (_React$Component2) { 29 | babelHelpers.inherits(Getter, _React$Component2); 30 | 31 | function Getter() { 32 | babelHelpers.classCallCheck(this, Getter); 33 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Getter).apply(this, arguments)); 34 | } 35 | 36 | babelHelpers.createClass(Getter, [{ 37 | key: "render", 38 | value: function render() {} 39 | }, { 40 | key: "foo", 41 | get: function get() { 42 | return { 43 | foo: PropTypes.string 44 | }; 45 | } 46 | }]); 47 | return Getter; 48 | }(React.Component); 49 | 50 | Getter.propTypes = process.env.NODE_ENV !== "production" ? Getter.foo : {}; 51 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property-variable/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | const propTypes = process.env.NODE_ENV !== "production" ? { 2 | foo: PropTypes.string 3 | } : {}; 4 | 5 | class Foo extends React.Component { 6 | render() {} 7 | 8 | } 9 | 10 | Foo.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; 11 | 12 | class Getter extends React.Component { 13 | get foo() { 14 | return { 15 | foo: PropTypes.string 16 | }; 17 | } 18 | 19 | render() {} 20 | 21 | } 22 | 23 | Getter.propTypes = process.env.NODE_ENV !== "production" ? Getter.foo : {}; 24 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property/actual.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends React.Component { 2 | render() {} 3 | } 4 | 5 | Foo1.propTypes = { 6 | bar1: PropTypes.string, 7 | }; 8 | 9 | class Foo2 extends React.PureComponent { 10 | render() {} 11 | } 12 | 13 | Foo2.propTypes = { 14 | bar2: PropTypes.string, 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Foo1 = 4 | /*#__PURE__*/ 5 | function (_React$Component) { 6 | babelHelpers.inherits(Foo1, _React$Component); 7 | 8 | function Foo1() { 9 | babelHelpers.classCallCheck(this, Foo1); 10 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo1).apply(this, arguments)); 11 | } 12 | 13 | babelHelpers.createClass(Foo1, [{ 14 | key: "render", 15 | value: function render() {} 16 | }]); 17 | return Foo1; 18 | }(React.Component); 19 | 20 | var Foo2 = 21 | /*#__PURE__*/ 22 | function (_React$PureComponent) { 23 | babelHelpers.inherits(Foo2, _React$PureComponent); 24 | 25 | function Foo2() { 26 | babelHelpers.classCallCheck(this, Foo2); 27 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo2).apply(this, arguments)); 28 | } 29 | 30 | babelHelpers.createClass(Foo2, [{ 31 | key: "render", 32 | value: function render() {} 33 | }]); 34 | return Foo2; 35 | }(React.PureComponent); 36 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends React.Component { 2 | render() {} 3 | 4 | } 5 | 6 | class Foo2 extends React.PureComponent { 7 | render() {} 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Foo1 = 4 | /*#__PURE__*/ 5 | function (_React$Component) { 6 | babelHelpers.inherits(Foo1, _React$Component); 7 | 8 | function Foo1() { 9 | babelHelpers.classCallCheck(this, Foo1); 10 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo1).apply(this, arguments)); 11 | } 12 | 13 | babelHelpers.createClass(Foo1, [{ 14 | key: "render", 15 | value: function render() {} 16 | }]); 17 | return Foo1; 18 | }(React.Component); 19 | 20 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 21 | bar1: PropTypes.string 22 | } : {}; 23 | 24 | var Foo2 = 25 | /*#__PURE__*/ 26 | function (_React$PureComponent) { 27 | babelHelpers.inherits(Foo2, _React$PureComponent); 28 | 29 | function Foo2() { 30 | babelHelpers.classCallCheck(this, Foo2); 31 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo2).apply(this, arguments)); 32 | } 33 | 34 | babelHelpers.createClass(Foo2, [{ 35 | key: "render", 36 | value: function render() {} 37 | }]); 38 | return Foo2; 39 | }(React.PureComponent); 40 | 41 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 42 | bar2: PropTypes.string 43 | } : {}; 44 | -------------------------------------------------------------------------------- /test/fixtures/es-class-assign-property/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends React.Component { 2 | render() {} 3 | 4 | } 5 | 6 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 7 | bar1: PropTypes.string 8 | } : {}; 9 | 10 | class Foo2 extends React.PureComponent { 11 | render() {} 12 | 13 | } 14 | 15 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 16 | bar2: PropTypes.string 17 | } : {}; 18 | -------------------------------------------------------------------------------- /test/fixtures/es-class-extend-component/actual.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends Component { 2 | static propTypes = { 3 | foo1: PropTypes.string, 4 | }; 5 | 6 | render() {} 7 | } 8 | 9 | class Foo2 extends Component { 10 | render() {} 11 | } 12 | 13 | Foo2.propTypes = { 14 | foo2: PropTypes.string, 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/es-class-extend-component/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Foo1 = 4 | /*#__PURE__*/ 5 | function (_Component) { 6 | babelHelpers.inherits(Foo1, _Component); 7 | 8 | function Foo1() { 9 | babelHelpers.classCallCheck(this, Foo1); 10 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo1).apply(this, arguments)); 11 | } 12 | 13 | babelHelpers.createClass(Foo1, [{ 14 | key: "render", 15 | value: function render() {} 16 | }]); 17 | return Foo1; 18 | }(Component); 19 | 20 | var Foo2 = 21 | /*#__PURE__*/ 22 | function (_Component2) { 23 | babelHelpers.inherits(Foo2, _Component2); 24 | 25 | function Foo2() { 26 | babelHelpers.classCallCheck(this, Foo2); 27 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo2).apply(this, arguments)); 28 | } 29 | 30 | babelHelpers.createClass(Foo2, [{ 31 | key: "render", 32 | value: function render() {} 33 | }]); 34 | return Foo2; 35 | }(Component); 36 | -------------------------------------------------------------------------------- /test/fixtures/es-class-extend-component/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends Component { 2 | render() {} 3 | 4 | } 5 | 6 | class Foo2 extends Component { 7 | render() {} 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/es-class-extend-component/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Foo1 = 4 | /*#__PURE__*/ 5 | function (_Component) { 6 | babelHelpers.inherits(Foo1, _Component); 7 | 8 | function Foo1() { 9 | babelHelpers.classCallCheck(this, Foo1); 10 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo1).apply(this, arguments)); 11 | } 12 | 13 | babelHelpers.createClass(Foo1, [{ 14 | key: "render", 15 | value: function render() {} 16 | }]); 17 | return Foo1; 18 | }(Component); 19 | 20 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 21 | foo1: PropTypes.string 22 | } : {}; 23 | 24 | var Foo2 = 25 | /*#__PURE__*/ 26 | function (_Component2) { 27 | babelHelpers.inherits(Foo2, _Component2); 28 | 29 | function Foo2() { 30 | babelHelpers.classCallCheck(this, Foo2); 31 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo2).apply(this, arguments)); 32 | } 33 | 34 | babelHelpers.createClass(Foo2, [{ 35 | key: "render", 36 | value: function render() {} 37 | }]); 38 | return Foo2; 39 | }(Component); 40 | 41 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 42 | foo2: PropTypes.string 43 | } : {}; 44 | -------------------------------------------------------------------------------- /test/fixtures/es-class-extend-component/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends Component { 2 | render() {} 3 | 4 | } 5 | 6 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 7 | foo1: PropTypes.string 8 | } : {}; 9 | 10 | class Foo2 extends Component { 11 | render() {} 12 | 13 | } 14 | 15 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 16 | foo2: PropTypes.string 17 | } : {}; 18 | -------------------------------------------------------------------------------- /test/fixtures/es-class-extend-deopt/actual.js: -------------------------------------------------------------------------------- 1 | import BaseComponent from 'components/base'; 2 | 3 | class Foo extends BaseComponent { 4 | static propTypes = { 5 | foo: PropTypes.string.isRequired, 6 | }; 7 | render() { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/es-class-extend-deopt/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import BaseComponent from 'components/base'; 2 | 3 | class Foo extends BaseComponent { 4 | render() {} 5 | 6 | } 7 | 8 | babelHelpers.defineProperty(Foo, "propTypes", { 9 | foo: PropTypes.string.isRequired 10 | }); 11 | -------------------------------------------------------------------------------- /test/fixtures/es-class-extend-deopt/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | import BaseComponent from 'components/base'; 2 | 3 | class Foo extends BaseComponent { 4 | render() {} 5 | 6 | } 7 | 8 | babelHelpers.defineProperty(Foo, "propTypes", { 9 | foo: PropTypes.string.isRequired 10 | }); 11 | -------------------------------------------------------------------------------- /test/fixtures/es-class-extend-global-base-component/actual.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends GlobalComponent { 2 | static propTypes = { 3 | foo1: PropTypes.string 4 | }; 5 | render() {} 6 | } 7 | 8 | class Foo2 extends GlobalComponent { 9 | render() {} 10 | } 11 | 12 | Foo2.propTypes = { 13 | foo2: PropTypes.string 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/es-class-extend-global-base-component/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends GlobalComponent { 2 | render() {} 3 | 4 | } 5 | 6 | babelHelpers.defineProperty(Foo1, "propTypes", { 7 | foo1: PropTypes.string 8 | }); 9 | 10 | class Foo2 extends GlobalComponent { 11 | render() {} 12 | 13 | } 14 | 15 | Foo2.propTypes = { 16 | foo2: PropTypes.string 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/es-class-inheritance/actual.js: -------------------------------------------------------------------------------- 1 | class PureRenderComponent extends Component { 2 | } 3 | 4 | class Foo1 extends PureRenderComponent { 5 | static propTypes = { 6 | foo1: PropTypes.string.isRequired, 7 | }; 8 | render() { 9 | } 10 | } 11 | 12 | class Foo2 extends PureRenderComponent { 13 | render() { 14 | } 15 | } 16 | 17 | Foo2.propTypes = { 18 | foo2: PropTypes.string.isRequired, 19 | }; 20 | 21 | // With no inheritance 22 | export class Foo3 { 23 | static propTypes = { 24 | foo3: PropTypes.string, 25 | }; 26 | 27 | render() {} 28 | } 29 | -------------------------------------------------------------------------------- /test/fixtures/es-class-inheritance/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.Foo3 = void 0; 7 | 8 | var PureRenderComponent = 9 | /*#__PURE__*/ 10 | function (_Component) { 11 | babelHelpers.inherits(PureRenderComponent, _Component); 12 | 13 | function PureRenderComponent() { 14 | babelHelpers.classCallCheck(this, PureRenderComponent); 15 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(PureRenderComponent).apply(this, arguments)); 16 | } 17 | 18 | return PureRenderComponent; 19 | }(Component); 20 | 21 | var Foo1 = 22 | /*#__PURE__*/ 23 | function (_PureRenderComponent) { 24 | babelHelpers.inherits(Foo1, _PureRenderComponent); 25 | 26 | function Foo1() { 27 | babelHelpers.classCallCheck(this, Foo1); 28 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo1).apply(this, arguments)); 29 | } 30 | 31 | babelHelpers.createClass(Foo1, [{ 32 | key: "render", 33 | value: function render() {} 34 | }]); 35 | return Foo1; 36 | }(PureRenderComponent); 37 | 38 | var Foo2 = 39 | /*#__PURE__*/ 40 | function (_PureRenderComponent2) { 41 | babelHelpers.inherits(Foo2, _PureRenderComponent2); 42 | 43 | function Foo2() { 44 | babelHelpers.classCallCheck(this, Foo2); 45 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo2).apply(this, arguments)); 46 | } 47 | 48 | babelHelpers.createClass(Foo2, [{ 49 | key: "render", 50 | value: function render() {} 51 | }]); 52 | return Foo2; 53 | }(PureRenderComponent); 54 | 55 | // With no inheritance 56 | var Foo3 = 57 | /*#__PURE__*/ 58 | function () { 59 | function Foo3() { 60 | babelHelpers.classCallCheck(this, Foo3); 61 | } 62 | 63 | babelHelpers.createClass(Foo3, [{ 64 | key: "render", 65 | value: function render() {} 66 | }]); 67 | return Foo3; 68 | }(); 69 | 70 | exports.Foo3 = Foo3; 71 | babelHelpers.defineProperty(Foo3, "propTypes", { 72 | foo3: PropTypes.string 73 | }); 74 | -------------------------------------------------------------------------------- /test/fixtures/es-class-inheritance/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | class PureRenderComponent extends Component {} 2 | 3 | class Foo1 extends PureRenderComponent { 4 | render() {} 5 | 6 | } 7 | 8 | class Foo2 extends PureRenderComponent { 9 | render() {} 10 | 11 | } 12 | 13 | // With no inheritance 14 | export class Foo3 { 15 | render() {} 16 | 17 | } 18 | babelHelpers.defineProperty(Foo3, "propTypes", { 19 | foo3: PropTypes.string 20 | }); 21 | -------------------------------------------------------------------------------- /test/fixtures/es-class-inheritance/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.Foo3 = void 0; 7 | 8 | var PureRenderComponent = 9 | /*#__PURE__*/ 10 | function (_Component) { 11 | babelHelpers.inherits(PureRenderComponent, _Component); 12 | 13 | function PureRenderComponent() { 14 | babelHelpers.classCallCheck(this, PureRenderComponent); 15 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(PureRenderComponent).apply(this, arguments)); 16 | } 17 | 18 | return PureRenderComponent; 19 | }(Component); 20 | 21 | var Foo1 = 22 | /*#__PURE__*/ 23 | function (_PureRenderComponent) { 24 | babelHelpers.inherits(Foo1, _PureRenderComponent); 25 | 26 | function Foo1() { 27 | babelHelpers.classCallCheck(this, Foo1); 28 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo1).apply(this, arguments)); 29 | } 30 | 31 | babelHelpers.createClass(Foo1, [{ 32 | key: "render", 33 | value: function render() {} 34 | }]); 35 | return Foo1; 36 | }(PureRenderComponent); 37 | 38 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 39 | foo1: PropTypes.string.isRequired 40 | } : {}; 41 | 42 | var Foo2 = 43 | /*#__PURE__*/ 44 | function (_PureRenderComponent2) { 45 | babelHelpers.inherits(Foo2, _PureRenderComponent2); 46 | 47 | function Foo2() { 48 | babelHelpers.classCallCheck(this, Foo2); 49 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo2).apply(this, arguments)); 50 | } 51 | 52 | babelHelpers.createClass(Foo2, [{ 53 | key: "render", 54 | value: function render() {} 55 | }]); 56 | return Foo2; 57 | }(PureRenderComponent); 58 | 59 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 60 | foo2: PropTypes.string.isRequired 61 | } : {}; // With no inheritance 62 | 63 | var Foo3 = 64 | /*#__PURE__*/ 65 | function () { 66 | function Foo3() { 67 | babelHelpers.classCallCheck(this, Foo3); 68 | } 69 | 70 | babelHelpers.createClass(Foo3, [{ 71 | key: "render", 72 | value: function render() {} 73 | }]); 74 | return Foo3; 75 | }(); 76 | 77 | exports.Foo3 = Foo3; 78 | babelHelpers.defineProperty(Foo3, "propTypes", { 79 | foo3: PropTypes.string 80 | }); 81 | -------------------------------------------------------------------------------- /test/fixtures/es-class-inheritance/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | class PureRenderComponent extends Component {} 2 | 3 | class Foo1 extends PureRenderComponent { 4 | render() {} 5 | 6 | } 7 | 8 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 9 | foo1: PropTypes.string.isRequired 10 | } : {}; 11 | 12 | class Foo2 extends PureRenderComponent { 13 | render() {} 14 | 15 | } 16 | 17 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 18 | foo2: PropTypes.string.isRequired 19 | } : {}; // With no inheritance 20 | 21 | export class Foo3 { 22 | render() {} 23 | 24 | } 25 | babelHelpers.defineProperty(Foo3, "propTypes", { 26 | foo3: PropTypes.string 27 | }); 28 | -------------------------------------------------------------------------------- /test/fixtures/es-class-no-name/actual.js: -------------------------------------------------------------------------------- 1 | export default class extends React.Component { 2 | static propTypes = { 3 | foo: PropTypes.string, 4 | }; 5 | 6 | render() {} 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/es-class-no-name/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _default = 9 | /*#__PURE__*/ 10 | function (_React$Component) { 11 | babelHelpers.inherits(_default, _React$Component); 12 | 13 | function _default() { 14 | babelHelpers.classCallCheck(this, _default); 15 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(_default).apply(this, arguments)); 16 | } 17 | 18 | babelHelpers.createClass(_default, [{ 19 | key: "render", 20 | value: function render() {} 21 | }]); 22 | return _default; 23 | }(React.Component); 24 | 25 | exports.default = _default; 26 | -------------------------------------------------------------------------------- /test/fixtures/es-class-no-name/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | export default class extends React.Component { 2 | render() {} 3 | 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/es-class-no-name/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _default = 9 | /*#__PURE__*/ 10 | function (_React$Component) { 11 | babelHelpers.inherits(_default, _React$Component); 12 | 13 | function _default() { 14 | babelHelpers.classCallCheck(this, _default); 15 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(_default).apply(this, arguments)); 16 | } 17 | 18 | babelHelpers.createClass(_default, [{ 19 | key: "render", 20 | value: function render() {} 21 | }]); 22 | return _default; 23 | }(React.Component); 24 | 25 | exports.default = _default; 26 | babelHelpers.defineProperty(_default, "propTypes", { 27 | foo: PropTypes.string 28 | }); 29 | -------------------------------------------------------------------------------- /test/fixtures/es-class-no-name/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | export default class _class extends React.Component { 2 | render() {} 3 | 4 | } 5 | babelHelpers.defineProperty(_class, "propTypes", { 6 | foo: PropTypes.string 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/es-class-static-property/actual.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends React.Component { 2 | static propTypes = { 3 | bar1: PropTypes.string, 4 | }; 5 | 6 | render() {} 7 | } 8 | 9 | export default class Foo2 extends React.Component { 10 | static propTypes = { 11 | bar2: PropTypes.string, 12 | }; 13 | 14 | render() {} 15 | } 16 | -------------------------------------------------------------------------------- /test/fixtures/es-class-static-property/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var Foo1 = 9 | /*#__PURE__*/ 10 | function (_React$Component) { 11 | babelHelpers.inherits(Foo1, _React$Component); 12 | 13 | function Foo1() { 14 | babelHelpers.classCallCheck(this, Foo1); 15 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo1).apply(this, arguments)); 16 | } 17 | 18 | babelHelpers.createClass(Foo1, [{ 19 | key: "render", 20 | value: function render() {} 21 | }]); 22 | return Foo1; 23 | }(React.Component); 24 | 25 | var Foo2 = 26 | /*#__PURE__*/ 27 | function (_React$Component2) { 28 | babelHelpers.inherits(Foo2, _React$Component2); 29 | 30 | function Foo2() { 31 | babelHelpers.classCallCheck(this, Foo2); 32 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo2).apply(this, arguments)); 33 | } 34 | 35 | babelHelpers.createClass(Foo2, [{ 36 | key: "render", 37 | value: function render() {} 38 | }]); 39 | return Foo2; 40 | }(React.Component); 41 | 42 | exports.default = Foo2; 43 | -------------------------------------------------------------------------------- /test/fixtures/es-class-static-property/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends React.Component { 2 | render() {} 3 | 4 | } 5 | 6 | export default class Foo2 extends React.Component { 7 | render() {} 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/es-class-static-property/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var Foo1 = 9 | /*#__PURE__*/ 10 | function (_React$Component) { 11 | babelHelpers.inherits(Foo1, _React$Component); 12 | 13 | function Foo1() { 14 | babelHelpers.classCallCheck(this, Foo1); 15 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo1).apply(this, arguments)); 16 | } 17 | 18 | babelHelpers.createClass(Foo1, [{ 19 | key: "render", 20 | value: function render() {} 21 | }]); 22 | return Foo1; 23 | }(React.Component); 24 | 25 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 26 | bar1: PropTypes.string 27 | } : {}; 28 | 29 | var Foo2 = 30 | /*#__PURE__*/ 31 | function (_React$Component2) { 32 | babelHelpers.inherits(Foo2, _React$Component2); 33 | 34 | function Foo2() { 35 | babelHelpers.classCallCheck(this, Foo2); 36 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo2).apply(this, arguments)); 37 | } 38 | 39 | babelHelpers.createClass(Foo2, [{ 40 | key: "render", 41 | value: function render() {} 42 | }]); 43 | return Foo2; 44 | }(React.Component); 45 | 46 | exports.default = Foo2; 47 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 48 | bar2: PropTypes.string 49 | } : {}; 50 | -------------------------------------------------------------------------------- /test/fixtures/es-class-static-property/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends React.Component { 2 | render() {} 3 | 4 | } 5 | 6 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 7 | bar1: PropTypes.string 8 | } : {}; 9 | export default class Foo2 extends React.Component { 10 | render() {} 11 | 12 | } 13 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 14 | bar2: PropTypes.string 15 | } : {}; 16 | -------------------------------------------------------------------------------- /test/fixtures/flow/actual.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends Component { 2 | props: { 3 | bar1?: string, 4 | }; 5 | render() {} 6 | } 7 | 8 | export type Props2 = { 9 | bar2?: string 10 | } 11 | 12 | class Foo2 extends Component { 13 | props: Props2; 14 | render() {} 15 | } 16 | 17 | type Props3 = { 18 | bar3?: string, 19 | } 20 | 21 | function Foo3(props: Props3) { 22 | return
; 23 | } 24 | -------------------------------------------------------------------------------- /test/fixtures/flow/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Foo1 = 4 | /*#__PURE__*/ 5 | function (_Component) { 6 | babelHelpers.inherits(Foo1, _Component); 7 | 8 | function Foo1() { 9 | babelHelpers.classCallCheck(this, Foo1); 10 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo1).apply(this, arguments)); 11 | } 12 | 13 | babelHelpers.createClass(Foo1, [{ 14 | key: "render", 15 | value: function render() {} 16 | }]); 17 | return Foo1; 18 | }(Component); 19 | 20 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 21 | bar1: require("prop-types").string 22 | } : {}; 23 | var babelPluginFlowReactPropTypes_proptype_Props2 = { 24 | bar2: require("prop-types").string 25 | }; 26 | 27 | var Foo2 = 28 | /*#__PURE__*/ 29 | function (_Component2) { 30 | babelHelpers.inherits(Foo2, _Component2); 31 | 32 | function Foo2() { 33 | babelHelpers.classCallCheck(this, Foo2); 34 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo2).apply(this, arguments)); 35 | } 36 | 37 | babelHelpers.createClass(Foo2, [{ 38 | key: "render", 39 | value: function render() {} 40 | }]); 41 | return Foo2; 42 | }(Component); 43 | 44 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 45 | bar2: require("prop-types").string 46 | } : {}; 47 | 48 | function Foo3(props) { 49 | return React.createElement("div", null); 50 | } 51 | 52 | Foo3.propTypes = process.env.NODE_ENV !== "production" ? { 53 | bar3: require("prop-types").string 54 | } : {}; 55 | -------------------------------------------------------------------------------- /test/fixtures/flow/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | ["babel-plugin-flow-react-proptypes", { 4 | "omitRuntimeTypeExport": true 5 | }], 6 | "@babel/plugin-transform-flow-strip-types" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/ignore-filenames/actual.js: -------------------------------------------------------------------------------- 1 | import { SomeComponent } from './SomeComponent'; 2 | 3 | const propTypes = { 4 | value: SomeComponent.propTypes.value, 5 | }; 6 | 7 | export function AnotherComponent(props) { 8 | return ; 9 | } 10 | 11 | AnotherComponent.propTypes = propTypes; 12 | -------------------------------------------------------------------------------- /test/fixtures/ignore-filenames/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import { SomeComponent } from './SomeComponent'; 2 | const propTypes = { 3 | value: SomeComponent.propTypes.value 4 | }; 5 | export function AnotherComponent(props) { 6 | return ; 7 | } 8 | AnotherComponent.propTypes = propTypes; 9 | -------------------------------------------------------------------------------- /test/fixtures/ignore-filenames/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignoreFilenames": ["fixtures/ignore-filenames"] 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/issue-106/actual.js: -------------------------------------------------------------------------------- 1 | import React, { Component, createElement } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | class RouteNode extends Component { 5 | render() { 6 | const { previousRoute, route } = this.state; 7 | return createElement(RouteSegment, Object.assign({}, this.props, route, previousRoute)); 8 | } 9 | } 10 | 11 | const storeName = 'storeName'; 12 | 13 | RouteNode.wrappedComponent.propTypes /* remove-proptypes */ = { 14 | [storeName]: PropTypes.object.isRequired, 15 | }; 16 | 17 | class BaseLink extends Component { 18 | render() { 19 | return React.createElement('a', { href, className, onClick }, this.props.children); 20 | } 21 | } 22 | 23 | BaseLink.propTypes = { 24 | routeOptions: PropTypes.object, 25 | [storeName]: PropTypes.object, 26 | route: PropTypes.object, 27 | ['previousRoute']: PropTypes.object, 28 | }; 29 | -------------------------------------------------------------------------------- /test/fixtures/issue-106/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | import React, { Component, createElement } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | class RouteNode extends Component { 5 | render() { 6 | const { 7 | previousRoute, 8 | route 9 | } = this.state; 10 | return createElement(RouteSegment, Object.assign({}, this.props, route, previousRoute)); 11 | } 12 | 13 | } 14 | 15 | const storeName = 'storeName'; 16 | RouteNode.wrappedComponent.propTypes 17 | /* remove-proptypes */ 18 | = process.env.NODE_ENV !== "production" ? { 19 | [storeName]: PropTypes.object.isRequired 20 | } : {}; 21 | 22 | class BaseLink extends Component { 23 | render() { 24 | return React.createElement('a', { 25 | href, 26 | className, 27 | onClick 28 | }, this.props.children); 29 | } 30 | 31 | } 32 | 33 | BaseLink.propTypes = process.env.NODE_ENV !== "production" ? { 34 | routeOptions: PropTypes.object, 35 | [storeName]: PropTypes.object, 36 | route: PropTypes.object, 37 | ['previousRoute']: PropTypes.object 38 | } : {}; 39 | -------------------------------------------------------------------------------- /test/fixtures/not-react-assign-property/actual.js: -------------------------------------------------------------------------------- 1 | var foo = {}; 2 | foo.propTypes = { 3 | foo: PropTypes.string, 4 | }; 5 | -------------------------------------------------------------------------------- /test/fixtures/not-react-assign-property/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | var foo = {}; 2 | foo.propTypes = { 3 | foo: PropTypes.string 4 | }; 5 | -------------------------------------------------------------------------------- /test/fixtures/not-react-assign-property/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | var foo = {}; 2 | foo.propTypes = { 3 | foo: PropTypes.string 4 | }; 5 | -------------------------------------------------------------------------------- /test/fixtures/not-react/actual.js: -------------------------------------------------------------------------------- 1 | var foo = { 2 | propTypes: { 3 | foo: 'bar', 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/not-react/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | var foo = { 2 | propTypes: { 3 | foo: 'bar' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/react-create-class-custom-name-no-property-name/actual.js: -------------------------------------------------------------------------------- 1 | var { createClass } = require('./notReact') 2 | var PropTypes = require('prop-types') 3 | 4 | var Class1 = createClass({ 5 | displayName: 'Class1', 6 | propTypes: { 7 | foo: PropTypes.string, 8 | }, 9 | }) 10 | -------------------------------------------------------------------------------- /test/fixtures/react-create-class-custom-name-no-property-name/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | var { 2 | createClass 3 | } = require('./notReact'); 4 | 5 | var Class1 = createClass({ 6 | displayName: 'Class1' 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/react-create-class-custom-name-no-property-name/notReact.js: -------------------------------------------------------------------------------- 1 | var createClass = a => a; 2 | 3 | module.exports { 4 | createClass 5 | } -------------------------------------------------------------------------------- /test/fixtures/react-create-class-custom-name-no-property-name/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "createReactClassName": "createClass" 3 | } -------------------------------------------------------------------------------- /test/fixtures/react-create-class-custom-name/actual.js: -------------------------------------------------------------------------------- 1 | var createSomethingReallySpecial = require('create-react-class'); 2 | var PropTypes = require('prop-types'); 3 | 4 | createSomethingReallySpecial({ 5 | propTypes: { 6 | foo: PropTypes.string, 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /test/fixtures/react-create-class-custom-name/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | var createSomethingReallySpecial = require('create-react-class'); 2 | 3 | createSomethingReallySpecial({}); 4 | -------------------------------------------------------------------------------- /test/fixtures/react-create-class-custom-name/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "createReactClassName": "createSomethingReallySpecial" 3 | } -------------------------------------------------------------------------------- /test/fixtures/react-create-class/actual.js: -------------------------------------------------------------------------------- 1 | var createReactClass = require('create-react-class'); 2 | var PropTypes = require('prop-types'); 3 | 4 | createReactClass({ 5 | propTypes: { 6 | foo: PropTypes.string, 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /test/fixtures/react-create-class/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | var createReactClass = require('create-react-class'); 2 | 3 | createReactClass({}); 4 | -------------------------------------------------------------------------------- /test/fixtures/recursive/actual.js: -------------------------------------------------------------------------------- 1 | import { cloneElement } from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | export default function Composer(props) { 5 | return renderRecursive(props.children, props.components) 6 | } 7 | 8 | Composer.propTypes = { 9 | children: PropTypes.func.isRequired, 10 | components: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.element, PropTypes.func])) 11 | .isRequired, 12 | } 13 | 14 | function renderRecursive(render, remaining, results) { 15 | results = results || [] 16 | if (!remaining[0]) { 17 | return render(results) 18 | } 19 | 20 | function nextRender(value) { 21 | return renderRecursive(render, remaining.slice(1), results.concat([value])) 22 | } 23 | 24 | return typeof remaining[0] === 'function' 25 | ? remaining[0]({ results, render: nextRender }) 26 | : cloneElement(remaining[0], { children: nextRender }) 27 | } 28 | -------------------------------------------------------------------------------- /test/fixtures/recursive/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import { cloneElement } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | export default function Composer(props) { 4 | return renderRecursive(props.children, props.components); 5 | } 6 | 7 | function renderRecursive(render, remaining, results) { 8 | results = results || []; 9 | 10 | if (!remaining[0]) { 11 | return render(results); 12 | } 13 | 14 | function nextRender(value) { 15 | return renderRecursive(render, remaining.slice(1), results.concat([value])); 16 | } 17 | 18 | return typeof remaining[0] === 'function' ? remaining[0]({ 19 | results, 20 | render: nextRender 21 | }) : cloneElement(remaining[0], { 22 | children: nextRender 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /test/fixtures/remove-import-proptypes/actual.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | class Greeting extends Component { 5 | render() { 6 | return

Hello, {this.props.name}

; 7 | } 8 | } 9 | 10 | Greeting.propTypes = { 11 | name: PropTypes.string 12 | }; -------------------------------------------------------------------------------- /test/fixtures/remove-import-proptypes/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var _react = babelHelpers.interopRequireWildcard(require("react")); 4 | 5 | var Greeting = 6 | /*#__PURE__*/ 7 | function (_Component) { 8 | babelHelpers.inherits(Greeting, _Component); 9 | 10 | function Greeting() { 11 | babelHelpers.classCallCheck(this, Greeting); 12 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Greeting).apply(this, arguments)); 13 | } 14 | 15 | babelHelpers.createClass(Greeting, [{ 16 | key: "render", 17 | value: function render() { 18 | return _react.default.createElement("h1", null, "Hello, ", this.props.name); 19 | } 20 | }]); 21 | return Greeting; 22 | }(_react.Component); 23 | -------------------------------------------------------------------------------- /test/fixtures/remove-import-proptypes/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | class Greeting extends Component { 4 | render() { 5 | return

Hello, {this.props.name}

; 6 | } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/remove-import-proptypes/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "removeImport": true 3 | } -------------------------------------------------------------------------------- /test/fixtures/shared-prop-type-variable/actual.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {omit} from 'underscore'; 3 | 4 | import Bar from './bar'; 5 | 6 | const {PropTypes} = React; 7 | 8 | const propTypes = { 9 | foo: PropTypes.any, 10 | }; 11 | 12 | export default function Foo(props) { 13 | const barProps = omit(props, Object.keys(propTypes)); 14 | return ; 15 | } 16 | 17 | Foo.propTypes = propTypes; 18 | -------------------------------------------------------------------------------- /test/fixtures/shared-prop-type-variable/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = Foo; 7 | 8 | var _react = babelHelpers.interopRequireDefault(require("react")); 9 | 10 | var _underscore = require("underscore"); 11 | 12 | var _bar = babelHelpers.interopRequireDefault(require("./bar")); 13 | 14 | var PropTypes = _react.default.PropTypes; 15 | var propTypes = { 16 | foo: PropTypes.any 17 | }; 18 | 19 | function Foo(props) { 20 | var barProps = (0, _underscore.omit)(props, Object.keys(propTypes)); 21 | return _react.default.createElement(_bar.default, barProps); 22 | } 23 | -------------------------------------------------------------------------------- /test/fixtures/shared-prop-type-variable/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { omit } from 'underscore'; 3 | import Bar from './bar'; 4 | const { 5 | PropTypes 6 | } = React; 7 | const propTypes = { 8 | foo: PropTypes.any 9 | }; 10 | export default function Foo(props) { 11 | const barProps = omit(props, Object.keys(propTypes)); 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/shared-prop-type-variable/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = Foo; 7 | 8 | var _react = babelHelpers.interopRequireDefault(require("react")); 9 | 10 | var _underscore = require("underscore"); 11 | 12 | var _bar = babelHelpers.interopRequireDefault(require("./bar")); 13 | 14 | var PropTypes = _react.default.PropTypes; 15 | var propTypes = { 16 | foo: PropTypes.any 17 | }; 18 | 19 | function Foo(props) { 20 | var barProps = (0, _underscore.omit)(props, Object.keys(propTypes)); 21 | return _react.default.createElement(_bar.default, barProps); 22 | } 23 | 24 | Foo.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; 25 | -------------------------------------------------------------------------------- /test/fixtures/shared-prop-type-variable/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { omit } from 'underscore'; 3 | import Bar from './bar'; 4 | const { 5 | PropTypes 6 | } = React; 7 | const propTypes = { 8 | foo: PropTypes.any 9 | }; 10 | export default function Foo(props) { 11 | const barProps = omit(props, Object.keys(propTypes)); 12 | return ; 13 | } 14 | Foo.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; 15 | -------------------------------------------------------------------------------- /test/fixtures/stateless-arrow-return-function/actual.js: -------------------------------------------------------------------------------- 1 | import React, {PropTypes} from 'react'; 2 | import map from 'lodash/map'; 3 | 4 | var Message = ({mapList}) => { 5 | return map(mapList, (index) => { 6 | return
7 | }); 8 | }; 9 | 10 | Message.propTypes = { 11 | mapList: PropTypes.array.isRequired, 12 | }; 13 | 14 | export default Message; 15 | -------------------------------------------------------------------------------- /test/fixtures/stateless-arrow-return-function/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireWildcard(require("react")); 9 | 10 | var _map = babelHelpers.interopRequireDefault(require("lodash/map")); 11 | 12 | var Message = function Message(_ref) { 13 | var mapList = _ref.mapList; 14 | return (0, _map.default)(mapList, function (index) { 15 | return _react.default.createElement("div", null); 16 | }); 17 | }; 18 | 19 | var _default = Message; 20 | exports.default = _default; 21 | -------------------------------------------------------------------------------- /test/fixtures/stateless-arrow-return-function/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import map from 'lodash/map'; 3 | 4 | var Message = ({ 5 | mapList 6 | }) => { 7 | return map(mapList, index => { 8 | return
; 9 | }); 10 | }; 11 | 12 | export default Message; 13 | -------------------------------------------------------------------------------- /test/fixtures/stateless-arrow-return-function/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireWildcard(require("react")); 9 | 10 | var _map = babelHelpers.interopRequireDefault(require("lodash/map")); 11 | 12 | var Message = function Message(_ref) { 13 | var mapList = _ref.mapList; 14 | return (0, _map.default)(mapList, function (index) { 15 | return _react.default.createElement("div", null); 16 | }); 17 | }; 18 | 19 | Message.propTypes = process.env.NODE_ENV !== "production" ? { 20 | mapList: _react.PropTypes.array.isRequired 21 | } : {}; 22 | var _default = Message; 23 | exports.default = _default; 24 | -------------------------------------------------------------------------------- /test/fixtures/stateless-arrow-return-function/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import map from 'lodash/map'; 3 | 4 | var Message = ({ 5 | mapList 6 | }) => { 7 | return map(mapList, index => { 8 | return
; 9 | }); 10 | }; 11 | 12 | Message.propTypes = process.env.NODE_ENV !== "production" ? { 13 | mapList: PropTypes.array.isRequired 14 | } : {}; 15 | export default Message; 16 | -------------------------------------------------------------------------------- /test/fixtures/stateless-force-removal/actual.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | 3 | var Message = ({isFetching, isSuccess, isFailure, errorMsg}) => { 4 | let messageType; 5 | let messageTxt; 6 | if (isFetching) { 7 | messageType = 'warning'; 8 | messageTxt = 'Pending call...'; 9 | } else if (isSuccess) { 10 | messageType = 'success'; 11 | messageTxt = 'Repo pushed successfully'; 12 | } else if (isFailure) { 13 | messageType = 'danger'; 14 | messageTxt = 'Something wrong occured'; 15 | } 16 | 17 | if (messageTxt === null) { 18 | return; 19 | } 20 | 21 | return
{messageTxt}
; 22 | }; 23 | 24 | Message.propTypes /* remove-proptypes */ = { 25 | isFetching: PropTypes.bool.isRequired, 26 | isSuccess: PropTypes.bool.isRequired, 27 | isFailure: PropTypes.bool.isRequired, 28 | errorMsg: PropTypes.string.isRequired 29 | }; 30 | 31 | export default Message; 32 | -------------------------------------------------------------------------------- /test/fixtures/stateless-force-removal/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | 3 | var Message = ({ 4 | isFetching, 5 | isSuccess, 6 | isFailure, 7 | errorMsg 8 | }) => { 9 | let messageType; 10 | let messageTxt; 11 | 12 | if (isFetching) { 13 | messageType = 'warning'; 14 | messageTxt = 'Pending call...'; 15 | } else if (isSuccess) { 16 | messageType = 'success'; 17 | messageTxt = 'Repo pushed successfully'; 18 | } else if (isFailure) { 19 | messageType = 'danger'; 20 | messageTxt = 'Something wrong occured'; 21 | } 22 | 23 | if (messageTxt === null) { 24 | return; 25 | } 26 | 27 | return
{messageTxt}
; 28 | }; 29 | 30 | export default Message; 31 | -------------------------------------------------------------------------------- /test/fixtures/stateless-functional-components/actual.js: -------------------------------------------------------------------------------- 1 | const Foo1 = () => ( 2 |
3 | ); 4 | 5 | Foo1.propTypes = { 6 | foo: PropTypes.string 7 | }; 8 | 9 | const Foo2 = () => { 10 | return
; 11 | }; 12 | 13 | Foo2.propTypes = { 14 | foo: PropTypes.string 15 | }; 16 | 17 | const Foo3 = function() { 18 | switch(true) { 19 | case true: 20 | if (true) { 21 | return
; 22 | } else { 23 | return ; 24 | } 25 | break; 26 | } 27 | }; 28 | 29 | Foo3.propTypes = { 30 | foo: PropTypes.string 31 | }; 32 | 33 | function Foo4() { 34 | return
; 35 | } 36 | 37 | Foo4.propTypes = { 38 | foo: PropTypes.string 39 | }; 40 | 41 | function Foo5() { 42 | const bar5 = function() { 43 | return
; 44 | } 45 | 46 | return bar5(); 47 | } 48 | 49 | Foo5.propTypes = { 50 | foo: PropTypes.string 51 | }; 52 | 53 | function Foo6() { 54 | var result = bar6(); 55 | 56 | return result; 57 | 58 | function bar6() { 59 | return
; 60 | } 61 | } 62 | 63 | Foo6.propTypes = { 64 | foo: PropTypes.string 65 | }; 66 | 67 | function Foo7() { 68 | const shallow = { 69 | shallowMember() { 70 | return
; 71 | } 72 | }; 73 | return shallow.shallowMember(); 74 | } 75 | 76 | Foo7.propTypes = { 77 | foo: PropTypes.string 78 | }; 79 | 80 | function Foo8() { 81 | const obj = { 82 | deep: { 83 | member() { 84 | return
; 85 | } 86 | } 87 | }; 88 | return obj.deep.member(); 89 | } 90 | 91 | Foo8.propTypes = { 92 | foo: PropTypes.string 93 | }; 94 | 95 | const Foo9 = () => ( 96 | React.createElement("div", null) 97 | ); 98 | 99 | Foo9.propTypes = { 100 | foo: PropTypes.string 101 | }; 102 | 103 | const Foo10 = () => { 104 | return React.createElement("div", null); 105 | }; 106 | 107 | Foo10.propTypes = { 108 | foo: PropTypes.string 109 | }; 110 | 111 | const Foo11 = () => ( 112 | true &&
113 | ); 114 | 115 | Foo11.propTypes = { 116 | foo: PropTypes.string 117 | }; 118 | 119 | function Foo12(props) { 120 | return React.cloneElement(props.children); 121 | } 122 | 123 | Foo12.propTypes = { 124 | foo: PropTypes.string, 125 | }; 126 | 127 | const Foo13 = React.memo(() => ( 128 | true &&
129 | )); 130 | 131 | Foo13.propTypes = { 132 | foo: PropTypes.string 133 | }; 134 | -------------------------------------------------------------------------------- /test/fixtures/stateless-functional-components/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Foo1 = function Foo1() { 4 | return React.createElement("div", null); 5 | }; 6 | 7 | var Foo2 = function Foo2() { 8 | return React.createElement("div", null); 9 | }; 10 | 11 | var Foo3 = function Foo3() { 12 | switch (true) { 13 | case true: 14 | if (true) { 15 | return React.createElement("div", null); 16 | } else { 17 | return React.createElement("span", null); 18 | } 19 | 20 | break; 21 | } 22 | }; 23 | 24 | function Foo4() { 25 | return React.createElement("div", null); 26 | } 27 | 28 | function Foo5() { 29 | var bar5 = function bar5() { 30 | return React.createElement("div", null); 31 | }; 32 | 33 | return bar5(); 34 | } 35 | 36 | function Foo6() { 37 | var result = bar6(); 38 | return result; 39 | 40 | function bar6() { 41 | return React.createElement("div", null); 42 | } 43 | } 44 | 45 | function Foo7() { 46 | var shallow = { 47 | shallowMember: function shallowMember() { 48 | return React.createElement("div", null); 49 | } 50 | }; 51 | return shallow.shallowMember(); 52 | } 53 | 54 | function Foo8() { 55 | var obj = { 56 | deep: { 57 | member: function member() { 58 | return React.createElement("div", null); 59 | } 60 | } 61 | }; 62 | return obj.deep.member(); 63 | } 64 | 65 | var Foo9 = function Foo9() { 66 | return React.createElement("div", null); 67 | }; 68 | 69 | var Foo10 = function Foo10() { 70 | return React.createElement("div", null); 71 | }; 72 | 73 | var Foo11 = function Foo11() { 74 | return true && React.createElement("div", null); 75 | }; 76 | 77 | function Foo12(props) { 78 | return React.cloneElement(props.children); 79 | } 80 | 81 | var Foo13 = React.memo(function () { 82 | return true && React.createElement("div", null); 83 | }); 84 | -------------------------------------------------------------------------------- /test/fixtures/stateless-functional-components/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | const Foo1 = () =>
; 2 | 3 | const Foo2 = () => { 4 | return
; 5 | }; 6 | 7 | const Foo3 = function () { 8 | switch (true) { 9 | case true: 10 | if (true) { 11 | return
; 12 | } else { 13 | return ; 14 | } 15 | 16 | break; 17 | } 18 | }; 19 | 20 | function Foo4() { 21 | return
; 22 | } 23 | 24 | function Foo5() { 25 | const bar5 = function () { 26 | return
; 27 | }; 28 | 29 | return bar5(); 30 | } 31 | 32 | function Foo6() { 33 | var result = bar6(); 34 | return result; 35 | 36 | function bar6() { 37 | return
; 38 | } 39 | } 40 | 41 | function Foo7() { 42 | const shallow = { 43 | shallowMember() { 44 | return
; 45 | } 46 | 47 | }; 48 | return shallow.shallowMember(); 49 | } 50 | 51 | function Foo8() { 52 | const obj = { 53 | deep: { 54 | member() { 55 | return
; 56 | } 57 | 58 | } 59 | }; 60 | return obj.deep.member(); 61 | } 62 | 63 | const Foo9 = () => React.createElement("div", null); 64 | 65 | const Foo10 = () => { 66 | return React.createElement("div", null); 67 | }; 68 | 69 | const Foo11 = () => true &&
; 70 | 71 | function Foo12(props) { 72 | return React.cloneElement(props.children); 73 | } 74 | 75 | const Foo13 = React.memo(() => true &&
); 76 | -------------------------------------------------------------------------------- /test/fixtures/stateless-functional-components/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Foo1 = function Foo1() { 4 | return React.createElement("div", null); 5 | }; 6 | 7 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 8 | foo: PropTypes.string 9 | } : {}; 10 | 11 | var Foo2 = function Foo2() { 12 | return React.createElement("div", null); 13 | }; 14 | 15 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 16 | foo: PropTypes.string 17 | } : {}; 18 | 19 | var Foo3 = function Foo3() { 20 | switch (true) { 21 | case true: 22 | if (true) { 23 | return React.createElement("div", null); 24 | } else { 25 | return React.createElement("span", null); 26 | } 27 | 28 | break; 29 | } 30 | }; 31 | 32 | Foo3.propTypes = process.env.NODE_ENV !== "production" ? { 33 | foo: PropTypes.string 34 | } : {}; 35 | 36 | function Foo4() { 37 | return React.createElement("div", null); 38 | } 39 | 40 | Foo4.propTypes = process.env.NODE_ENV !== "production" ? { 41 | foo: PropTypes.string 42 | } : {}; 43 | 44 | function Foo5() { 45 | var bar5 = function bar5() { 46 | return React.createElement("div", null); 47 | }; 48 | 49 | return bar5(); 50 | } 51 | 52 | Foo5.propTypes = process.env.NODE_ENV !== "production" ? { 53 | foo: PropTypes.string 54 | } : {}; 55 | 56 | function Foo6() { 57 | var result = bar6(); 58 | return result; 59 | 60 | function bar6() { 61 | return React.createElement("div", null); 62 | } 63 | } 64 | 65 | Foo6.propTypes = process.env.NODE_ENV !== "production" ? { 66 | foo: PropTypes.string 67 | } : {}; 68 | 69 | function Foo7() { 70 | var shallow = { 71 | shallowMember: function shallowMember() { 72 | return React.createElement("div", null); 73 | } 74 | }; 75 | return shallow.shallowMember(); 76 | } 77 | 78 | Foo7.propTypes = process.env.NODE_ENV !== "production" ? { 79 | foo: PropTypes.string 80 | } : {}; 81 | 82 | function Foo8() { 83 | var obj = { 84 | deep: { 85 | member: function member() { 86 | return React.createElement("div", null); 87 | } 88 | } 89 | }; 90 | return obj.deep.member(); 91 | } 92 | 93 | Foo8.propTypes = process.env.NODE_ENV !== "production" ? { 94 | foo: PropTypes.string 95 | } : {}; 96 | 97 | var Foo9 = function Foo9() { 98 | return React.createElement("div", null); 99 | }; 100 | 101 | Foo9.propTypes = process.env.NODE_ENV !== "production" ? { 102 | foo: PropTypes.string 103 | } : {}; 104 | 105 | var Foo10 = function Foo10() { 106 | return React.createElement("div", null); 107 | }; 108 | 109 | Foo10.propTypes = process.env.NODE_ENV !== "production" ? { 110 | foo: PropTypes.string 111 | } : {}; 112 | 113 | var Foo11 = function Foo11() { 114 | return true && React.createElement("div", null); 115 | }; 116 | 117 | Foo11.propTypes = process.env.NODE_ENV !== "production" ? { 118 | foo: PropTypes.string 119 | } : {}; 120 | 121 | function Foo12(props) { 122 | return React.cloneElement(props.children); 123 | } 124 | 125 | Foo12.propTypes = process.env.NODE_ENV !== "production" ? { 126 | foo: PropTypes.string 127 | } : {}; 128 | var Foo13 = React.memo(function () { 129 | return true && React.createElement("div", null); 130 | }); 131 | Foo13.propTypes = process.env.NODE_ENV !== "production" ? { 132 | foo: PropTypes.string 133 | } : {}; 134 | -------------------------------------------------------------------------------- /test/fixtures/stateless-functional-components/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | const Foo1 = () =>
; 2 | 3 | Foo1.propTypes = process.env.NODE_ENV !== "production" ? { 4 | foo: PropTypes.string 5 | } : {}; 6 | 7 | const Foo2 = () => { 8 | return
; 9 | }; 10 | 11 | Foo2.propTypes = process.env.NODE_ENV !== "production" ? { 12 | foo: PropTypes.string 13 | } : {}; 14 | 15 | const Foo3 = function () { 16 | switch (true) { 17 | case true: 18 | if (true) { 19 | return
; 20 | } else { 21 | return ; 22 | } 23 | 24 | break; 25 | } 26 | }; 27 | 28 | Foo3.propTypes = process.env.NODE_ENV !== "production" ? { 29 | foo: PropTypes.string 30 | } : {}; 31 | 32 | function Foo4() { 33 | return
; 34 | } 35 | 36 | Foo4.propTypes = process.env.NODE_ENV !== "production" ? { 37 | foo: PropTypes.string 38 | } : {}; 39 | 40 | function Foo5() { 41 | const bar5 = function () { 42 | return
; 43 | }; 44 | 45 | return bar5(); 46 | } 47 | 48 | Foo5.propTypes = process.env.NODE_ENV !== "production" ? { 49 | foo: PropTypes.string 50 | } : {}; 51 | 52 | function Foo6() { 53 | var result = bar6(); 54 | return result; 55 | 56 | function bar6() { 57 | return
; 58 | } 59 | } 60 | 61 | Foo6.propTypes = process.env.NODE_ENV !== "production" ? { 62 | foo: PropTypes.string 63 | } : {}; 64 | 65 | function Foo7() { 66 | const shallow = { 67 | shallowMember() { 68 | return
; 69 | } 70 | 71 | }; 72 | return shallow.shallowMember(); 73 | } 74 | 75 | Foo7.propTypes = process.env.NODE_ENV !== "production" ? { 76 | foo: PropTypes.string 77 | } : {}; 78 | 79 | function Foo8() { 80 | const obj = { 81 | deep: { 82 | member() { 83 | return
; 84 | } 85 | 86 | } 87 | }; 88 | return obj.deep.member(); 89 | } 90 | 91 | Foo8.propTypes = process.env.NODE_ENV !== "production" ? { 92 | foo: PropTypes.string 93 | } : {}; 94 | 95 | const Foo9 = () => React.createElement("div", null); 96 | 97 | Foo9.propTypes = process.env.NODE_ENV !== "production" ? { 98 | foo: PropTypes.string 99 | } : {}; 100 | 101 | const Foo10 = () => { 102 | return React.createElement("div", null); 103 | }; 104 | 105 | Foo10.propTypes = process.env.NODE_ENV !== "production" ? { 106 | foo: PropTypes.string 107 | } : {}; 108 | 109 | const Foo11 = () => true &&
; 110 | 111 | Foo11.propTypes = process.env.NODE_ENV !== "production" ? { 112 | foo: PropTypes.string 113 | } : {}; 114 | 115 | function Foo12(props) { 116 | return React.cloneElement(props.children); 117 | } 118 | 119 | Foo12.propTypes = process.env.NODE_ENV !== "production" ? { 120 | foo: PropTypes.string 121 | } : {}; 122 | const Foo13 = React.memo(() => true &&
); 123 | Foo13.propTypes = process.env.NODE_ENV !== "production" ? { 124 | foo: PropTypes.string 125 | } : {}; 126 | -------------------------------------------------------------------------------- /test/fixtures/stateless-return-undefined/actual.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | 3 | var Message = ({isFetching, isSuccess, isFailure, errorMsg}) => { 4 | let messageType; 5 | let messageTxt; 6 | if (isFetching) { 7 | messageType = 'warning'; 8 | messageTxt = 'Pending call...'; 9 | } else if (isSuccess) { 10 | messageType = 'success'; 11 | messageTxt = 'Repo pushed successfully'; 12 | } else if (isFailure) { 13 | messageType = 'danger'; 14 | messageTxt = 'Something wrong occured'; 15 | } 16 | 17 | if (messageTxt === null) { 18 | return; 19 | } 20 | 21 | return
{messageTxt}
; 22 | }; 23 | 24 | Message.propTypes = { 25 | isFetching: PropTypes.bool.isRequired, 26 | isSuccess: PropTypes.bool.isRequired, 27 | isFailure: PropTypes.bool.isRequired, 28 | errorMsg: PropTypes.string.isRequired 29 | }; 30 | 31 | export default Message; 32 | -------------------------------------------------------------------------------- /test/fixtures/stateless-return-undefined/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireWildcard(require("react")); 9 | 10 | var Message = function Message(_ref) { 11 | var isFetching = _ref.isFetching, 12 | isSuccess = _ref.isSuccess, 13 | isFailure = _ref.isFailure, 14 | errorMsg = _ref.errorMsg; 15 | var messageType; 16 | var messageTxt; 17 | 18 | if (isFetching) { 19 | messageType = 'warning'; 20 | messageTxt = 'Pending call...'; 21 | } else if (isSuccess) { 22 | messageType = 'success'; 23 | messageTxt = 'Repo pushed successfully'; 24 | } else if (isFailure) { 25 | messageType = 'danger'; 26 | messageTxt = 'Something wrong occured'; 27 | } 28 | 29 | if (messageTxt === null) { 30 | return; 31 | } 32 | 33 | return _react.default.createElement("div", { 34 | className: 'alert alert-' + messageType, 35 | role: "alert" 36 | }, messageTxt); 37 | }; 38 | 39 | var _default = Message; 40 | exports.default = _default; 41 | -------------------------------------------------------------------------------- /test/fixtures/stateless-return-undefined/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | 3 | var Message = ({ 4 | isFetching, 5 | isSuccess, 6 | isFailure, 7 | errorMsg 8 | }) => { 9 | let messageType; 10 | let messageTxt; 11 | 12 | if (isFetching) { 13 | messageType = 'warning'; 14 | messageTxt = 'Pending call...'; 15 | } else if (isSuccess) { 16 | messageType = 'success'; 17 | messageTxt = 'Repo pushed successfully'; 18 | } else if (isFailure) { 19 | messageType = 'danger'; 20 | messageTxt = 'Something wrong occured'; 21 | } 22 | 23 | if (messageTxt === null) { 24 | return; 25 | } 26 | 27 | return
{messageTxt}
; 28 | }; 29 | 30 | export default Message; 31 | -------------------------------------------------------------------------------- /test/fixtures/stateless-return-undefined/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireWildcard(require("react")); 9 | 10 | var Message = function Message(_ref) { 11 | var isFetching = _ref.isFetching, 12 | isSuccess = _ref.isSuccess, 13 | isFailure = _ref.isFailure, 14 | errorMsg = _ref.errorMsg; 15 | var messageType; 16 | var messageTxt; 17 | 18 | if (isFetching) { 19 | messageType = 'warning'; 20 | messageTxt = 'Pending call...'; 21 | } else if (isSuccess) { 22 | messageType = 'success'; 23 | messageTxt = 'Repo pushed successfully'; 24 | } else if (isFailure) { 25 | messageType = 'danger'; 26 | messageTxt = 'Something wrong occured'; 27 | } 28 | 29 | if (messageTxt === null) { 30 | return; 31 | } 32 | 33 | return _react.default.createElement("div", { 34 | className: 'alert alert-' + messageType, 35 | role: "alert" 36 | }, messageTxt); 37 | }; 38 | 39 | Message.propTypes = process.env.NODE_ENV !== "production" ? { 40 | isFetching: _react.PropTypes.bool.isRequired, 41 | isSuccess: _react.PropTypes.bool.isRequired, 42 | isFailure: _react.PropTypes.bool.isRequired, 43 | errorMsg: _react.PropTypes.string.isRequired 44 | } : {}; 45 | var _default = Message; 46 | exports.default = _default; 47 | -------------------------------------------------------------------------------- /test/fixtures/stateless-return-undefined/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | 3 | var Message = ({ 4 | isFetching, 5 | isSuccess, 6 | isFailure, 7 | errorMsg 8 | }) => { 9 | let messageType; 10 | let messageTxt; 11 | 12 | if (isFetching) { 13 | messageType = 'warning'; 14 | messageTxt = 'Pending call...'; 15 | } else if (isSuccess) { 16 | messageType = 'success'; 17 | messageTxt = 'Repo pushed successfully'; 18 | } else if (isFailure) { 19 | messageType = 'danger'; 20 | messageTxt = 'Something wrong occured'; 21 | } 22 | 23 | if (messageTxt === null) { 24 | return; 25 | } 26 | 27 | return
{messageTxt}
; 28 | }; 29 | 30 | Message.propTypes = process.env.NODE_ENV !== "production" ? { 31 | isFetching: PropTypes.bool.isRequired, 32 | isSuccess: PropTypes.bool.isRequired, 33 | isFailure: PropTypes.bool.isRequired, 34 | errorMsg: PropTypes.string.isRequired 35 | } : {}; 36 | export default Message; 37 | -------------------------------------------------------------------------------- /test/fixtures/unsafe-wrap/actual.js: -------------------------------------------------------------------------------- 1 | class Foo1 extends React.Component { 2 | render() {} 3 | } 4 | 5 | Foo1.propTypes = { 6 | bar1: PropTypes.string, 7 | }; 8 | 9 | class Foo2 extends React.Component { 10 | static propTypes = { 11 | bar2: PropTypes.string, 12 | }; 13 | 14 | render() {} 15 | } 16 | 17 | const Foo3 = () => ( 18 |
19 | ); 20 | 21 | Foo3.propTypes = { 22 | bar3: PropTypes.string 23 | }; 24 | -------------------------------------------------------------------------------- /test/fixtures/unsafe-wrap/expected.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Foo1 = 4 | /*#__PURE__*/ 5 | function (_React$Component) { 6 | babelHelpers.inherits(Foo1, _React$Component); 7 | 8 | function Foo1() { 9 | babelHelpers.classCallCheck(this, Foo1); 10 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo1).apply(this, arguments)); 11 | } 12 | 13 | babelHelpers.createClass(Foo1, [{ 14 | key: "render", 15 | value: function render() {} 16 | }]); 17 | return Foo1; 18 | }(React.Component); 19 | 20 | process.env.NODE_ENV !== "production" ? Foo1.propTypes = { 21 | bar1: PropTypes.string 22 | } : void 0; 23 | 24 | var Foo2 = 25 | /*#__PURE__*/ 26 | function (_React$Component2) { 27 | babelHelpers.inherits(Foo2, _React$Component2); 28 | 29 | function Foo2() { 30 | babelHelpers.classCallCheck(this, Foo2); 31 | return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo2).apply(this, arguments)); 32 | } 33 | 34 | babelHelpers.createClass(Foo2, [{ 35 | key: "render", 36 | value: function render() {} 37 | }]); 38 | return Foo2; 39 | }(React.Component); 40 | 41 | process.env.NODE_ENV !== "production" ? Foo2.propTypes = { 42 | bar2: PropTypes.string 43 | } : void 0; 44 | 45 | var Foo3 = function Foo3() { 46 | return React.createElement("div", null); 47 | }; 48 | 49 | process.env.NODE_ENV !== "production" ? Foo3.propTypes = { 50 | bar3: PropTypes.string 51 | } : void 0; 52 | -------------------------------------------------------------------------------- /test/fixtures/unsafe-wrap/options.json: -------------------------------------------------------------------------------- 1 | { 2 | "mode": "unsafe-wrap" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/variable-assignment-member-expressions/actual.js: -------------------------------------------------------------------------------- 1 | const shapePropType = PropTypes.shape({ 2 | foo: PropTypes.string, 3 | }); 4 | 5 | const ComponentA = () =>
; 6 | ComponentA.propTypes = { 7 | foo: shapePropType.isRequired, 8 | }; 9 | 10 | const somePropTypes = { 11 | foo: PropTypes.string, 12 | bar: PropTypes.number, 13 | }; 14 | 15 | const ComponentB = () =>
; 16 | ComponentB.propTypes = { 17 | foo: somePropTypes.foo.isRequired, 18 | }; 19 | 20 | const somePropTypesC = { 21 | foo: PropTypes.string, 22 | bar: PropTypes.number, 23 | }; 24 | 25 | const ComponentC = () =>
; 26 | ComponentC.propTypes = { 27 | foo: somePropTypesC['foo'].isRequired, 28 | }; 29 | 30 | const somePropTypesD = { 31 | foo: PropTypes.string, 32 | bar: PropTypes.number, 33 | }; 34 | 35 | const ComponentD = () =>
; 36 | const foo = { bar: 'foo' }; 37 | ComponentD.propTypes = { 38 | [foo.bar]: somePropTypesD['foo'].isRequired, 39 | }; 40 | -------------------------------------------------------------------------------- /test/fixtures/variable-assignment-member-expressions/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var ComponentA = function ComponentA() { 4 | return React.createElement("div", null); 5 | }; 6 | 7 | var ComponentB = function ComponentB() { 8 | return React.createElement("div", null); 9 | }; 10 | 11 | var ComponentC = function ComponentC() { 12 | return React.createElement("div", null); 13 | }; 14 | 15 | var ComponentD = function ComponentD() { 16 | return React.createElement("div", null); 17 | }; 18 | 19 | var foo = { 20 | bar: 'foo' 21 | }; 22 | -------------------------------------------------------------------------------- /test/fixtures/variable-assignment-member-expressions/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | const ComponentA = () =>
; 2 | 3 | const ComponentB = () =>
; 4 | 5 | const ComponentC = () =>
; 6 | 7 | const ComponentD = () =>
; 8 | 9 | const foo = { 10 | bar: 'foo' 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/variable-assignment-member-expressions/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var shapePropType = process.env.NODE_ENV !== "production" ? PropTypes.shape({ 4 | foo: PropTypes.string 5 | }) : {}; 6 | 7 | var ComponentA = function ComponentA() { 8 | return React.createElement("div", null); 9 | }; 10 | 11 | ComponentA.propTypes = process.env.NODE_ENV !== "production" ? { 12 | foo: shapePropType.isRequired 13 | } : {}; 14 | var somePropTypes = process.env.NODE_ENV !== "production" ? { 15 | foo: PropTypes.string, 16 | bar: PropTypes.number 17 | } : {}; 18 | 19 | var ComponentB = function ComponentB() { 20 | return React.createElement("div", null); 21 | }; 22 | 23 | ComponentB.propTypes = process.env.NODE_ENV !== "production" ? { 24 | foo: somePropTypes.foo.isRequired 25 | } : {}; 26 | var somePropTypesC = process.env.NODE_ENV !== "production" ? { 27 | foo: PropTypes.string, 28 | bar: PropTypes.number 29 | } : {}; 30 | 31 | var ComponentC = function ComponentC() { 32 | return React.createElement("div", null); 33 | }; 34 | 35 | ComponentC.propTypes = process.env.NODE_ENV !== "production" ? { 36 | foo: somePropTypesC['foo'].isRequired 37 | } : {}; 38 | var somePropTypesD = process.env.NODE_ENV !== "production" ? { 39 | foo: PropTypes.string, 40 | bar: PropTypes.number 41 | } : {}; 42 | 43 | var ComponentD = function ComponentD() { 44 | return React.createElement("div", null); 45 | }; 46 | 47 | var foo = { 48 | bar: 'foo' 49 | }; 50 | ComponentD.propTypes = process.env.NODE_ENV !== "production" ? babelHelpers.defineProperty({}, foo.bar, somePropTypesD['foo'].isRequired) : {}; 51 | -------------------------------------------------------------------------------- /test/fixtures/variable-assignment-member-expressions/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | const shapePropType = process.env.NODE_ENV !== "production" ? PropTypes.shape({ 2 | foo: PropTypes.string 3 | }) : {}; 4 | 5 | const ComponentA = () =>
; 6 | 7 | ComponentA.propTypes = process.env.NODE_ENV !== "production" ? { 8 | foo: shapePropType.isRequired 9 | } : {}; 10 | const somePropTypes = process.env.NODE_ENV !== "production" ? { 11 | foo: PropTypes.string, 12 | bar: PropTypes.number 13 | } : {}; 14 | 15 | const ComponentB = () =>
; 16 | 17 | ComponentB.propTypes = process.env.NODE_ENV !== "production" ? { 18 | foo: somePropTypes.foo.isRequired 19 | } : {}; 20 | const somePropTypesC = process.env.NODE_ENV !== "production" ? { 21 | foo: PropTypes.string, 22 | bar: PropTypes.number 23 | } : {}; 24 | 25 | const ComponentC = () =>
; 26 | 27 | ComponentC.propTypes = process.env.NODE_ENV !== "production" ? { 28 | foo: somePropTypesC['foo'].isRequired 29 | } : {}; 30 | const somePropTypesD = process.env.NODE_ENV !== "production" ? { 31 | foo: PropTypes.string, 32 | bar: PropTypes.number 33 | } : {}; 34 | 35 | const ComponentD = () =>
; 36 | 37 | const foo = { 38 | bar: 'foo' 39 | }; 40 | ComponentD.propTypes = process.env.NODE_ENV !== "production" ? { 41 | [foo.bar]: somePropTypesD['foo'].isRequired 42 | } : {}; 43 | -------------------------------------------------------------------------------- /test/fixtures/variable-assignment/actual.js: -------------------------------------------------------------------------------- 1 | const propTypesBasic = { 2 | foo: PropTypes.string 3 | }; 4 | 5 | const FooBasic = () => ( 6 |
7 | ); 8 | 9 | FooBasic.propTypes = propTypesBasic; 10 | 11 | const extraReference = { 12 | bar: PropTypes.string 13 | }; 14 | 15 | const propTypesWithExtraReference = Object.assign({}, extraReference, { 16 | foo: PropTypes.string 17 | }); 18 | 19 | const FooExtraReference = () => ( 20 |
21 | ); 22 | 23 | FooExtraReference.propTypes = propTypesWithExtraReference; 24 | 25 | const propTypesWithExtraReferenceSpread = { 26 | ...extraReference, 27 | ...({ foo: PropTypes.string }), 28 | bar: PropTypes.string 29 | }; 30 | 31 | const FooExtraReferenceSpread = () => ( 32 |
33 | ); 34 | 35 | FooExtraReferenceSpread.propTypes = propTypesWithExtraReferenceSpread; 36 | 37 | const propTypesWrapped = { 38 | foo: PropTypes.string 39 | }; 40 | 41 | const FooWrapped = () => ( 42 |
43 | ); 44 | 45 | FooWrapped.propTypes = someWrappingFunction(propTypesWrapped); 46 | 47 | const propTypesReferenced = { 48 | foo: PropTypes.string 49 | }; 50 | 51 | const FooReferenced = () => ( 52 |
53 | ); 54 | 55 | FooReferenced.propTypes = propTypesReferenced; 56 | 57 | export const propTypesExported = { 58 | foo: PropTypes.string 59 | }; 60 | 61 | const FooExported = () => ( 62 |
63 | ); 64 | 65 | FooExported.propTypes = propTypesExported; 66 | 67 | const propTypesCreateClass = { foo: PropTypes.string }; 68 | const FooCreateClass = createReactClass({ 69 | propTypes: propTypesCreateClass 70 | }); 71 | -------------------------------------------------------------------------------- /test/fixtures/variable-assignment/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.propTypesExported = void 0; 7 | 8 | var FooBasic = function FooBasic() { 9 | return React.createElement("div", null); 10 | }; 11 | 12 | var FooExtraReference = function FooExtraReference() { 13 | return React.createElement("div", null); 14 | }; 15 | 16 | var FooExtraReferenceSpread = function FooExtraReferenceSpread() { 17 | return React.createElement("div", null); 18 | }; 19 | 20 | var FooWrapped = function FooWrapped() { 21 | return React.createElement("div", null); 22 | }; 23 | 24 | var propTypesReferenced = { 25 | foo: PropTypes.string 26 | }; 27 | 28 | var FooReferenced = function FooReferenced() { 29 | return React.createElement("div", { 30 | bar: propTypesReferenced 31 | }); 32 | }; 33 | 34 | var propTypesExported = { 35 | foo: PropTypes.string 36 | }; 37 | exports.propTypesExported = propTypesExported; 38 | 39 | var FooExported = function FooExported() { 40 | return React.createElement("div", null); 41 | }; 42 | 43 | var FooCreateClass = createReactClass({ 44 | displayName: "FooCreateClass" 45 | }); 46 | -------------------------------------------------------------------------------- /test/fixtures/variable-assignment/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | const FooBasic = () =>
; 2 | 3 | const FooExtraReference = () =>
; 4 | 5 | const FooExtraReferenceSpread = () =>
; 6 | 7 | const FooWrapped = () =>
; 8 | 9 | const propTypesReferenced = { 10 | foo: PropTypes.string 11 | }; 12 | 13 | const FooReferenced = () =>
; 14 | 15 | export const propTypesExported = { 16 | foo: PropTypes.string 17 | }; 18 | 19 | const FooExported = () =>
; 20 | 21 | const FooCreateClass = createReactClass({}); 22 | -------------------------------------------------------------------------------- /test/fixtures/variable-assignment/expected-wrap-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.propTypesExported = void 0; 7 | var propTypesBasic = process.env.NODE_ENV !== "production" ? { 8 | foo: PropTypes.string 9 | } : {}; 10 | 11 | var FooBasic = function FooBasic() { 12 | return React.createElement("div", null); 13 | }; 14 | 15 | FooBasic.propTypes = process.env.NODE_ENV !== "production" ? propTypesBasic : {}; 16 | var extraReference = process.env.NODE_ENV !== "production" ? { 17 | bar: PropTypes.string 18 | } : {}; 19 | var propTypesWithExtraReference = process.env.NODE_ENV !== "production" ? Object.assign({}, extraReference, { 20 | foo: PropTypes.string 21 | }) : {}; 22 | 23 | var FooExtraReference = function FooExtraReference() { 24 | return React.createElement("div", null); 25 | }; 26 | 27 | FooExtraReference.propTypes = process.env.NODE_ENV !== "production" ? propTypesWithExtraReference : {}; 28 | var propTypesWithExtraReferenceSpread = process.env.NODE_ENV !== "production" ? babelHelpers.objectSpread({}, extraReference, { 29 | foo: PropTypes.string 30 | }, { 31 | bar: PropTypes.string 32 | }) : {}; 33 | 34 | var FooExtraReferenceSpread = function FooExtraReferenceSpread() { 35 | return React.createElement("div", null); 36 | }; 37 | 38 | FooExtraReferenceSpread.propTypes = process.env.NODE_ENV !== "production" ? propTypesWithExtraReferenceSpread : {}; 39 | var propTypesWrapped = process.env.NODE_ENV !== "production" ? { 40 | foo: PropTypes.string 41 | } : {}; 42 | 43 | var FooWrapped = function FooWrapped() { 44 | return React.createElement("div", null); 45 | }; 46 | 47 | FooWrapped.propTypes = process.env.NODE_ENV !== "production" ? someWrappingFunction(propTypesWrapped) : {}; 48 | var propTypesReferenced = { 49 | foo: PropTypes.string 50 | }; 51 | 52 | var FooReferenced = function FooReferenced() { 53 | return React.createElement("div", { 54 | bar: propTypesReferenced 55 | }); 56 | }; 57 | 58 | FooReferenced.propTypes = process.env.NODE_ENV !== "production" ? propTypesReferenced : {}; 59 | var propTypesExported = { 60 | foo: PropTypes.string 61 | }; 62 | exports.propTypesExported = propTypesExported; 63 | 64 | var FooExported = function FooExported() { 65 | return React.createElement("div", null); 66 | }; 67 | 68 | FooExported.propTypes = process.env.NODE_ENV !== "production" ? propTypesExported : {}; 69 | var propTypesCreateClass = process.env.NODE_ENV !== "production" ? { 70 | foo: PropTypes.string 71 | } : {}; 72 | var FooCreateClass = createReactClass({ 73 | displayName: "FooCreateClass", 74 | propTypes: propTypesCreateClass 75 | }); 76 | -------------------------------------------------------------------------------- /test/fixtures/variable-assignment/expected-wrap-es6.js: -------------------------------------------------------------------------------- 1 | const propTypesBasic = process.env.NODE_ENV !== "production" ? { 2 | foo: PropTypes.string 3 | } : {}; 4 | 5 | const FooBasic = () =>
; 6 | 7 | FooBasic.propTypes = process.env.NODE_ENV !== "production" ? propTypesBasic : {}; 8 | const extraReference = process.env.NODE_ENV !== "production" ? { 9 | bar: PropTypes.string 10 | } : {}; 11 | const propTypesWithExtraReference = process.env.NODE_ENV !== "production" ? Object.assign({}, extraReference, { 12 | foo: PropTypes.string 13 | }) : {}; 14 | 15 | const FooExtraReference = () =>
; 16 | 17 | FooExtraReference.propTypes = process.env.NODE_ENV !== "production" ? propTypesWithExtraReference : {}; 18 | const propTypesWithExtraReferenceSpread = process.env.NODE_ENV !== "production" ? babelHelpers.objectSpread({}, extraReference, { 19 | foo: PropTypes.string 20 | }, { 21 | bar: PropTypes.string 22 | }) : {}; 23 | 24 | const FooExtraReferenceSpread = () =>
; 25 | 26 | FooExtraReferenceSpread.propTypes = process.env.NODE_ENV !== "production" ? propTypesWithExtraReferenceSpread : {}; 27 | const propTypesWrapped = process.env.NODE_ENV !== "production" ? { 28 | foo: PropTypes.string 29 | } : {}; 30 | 31 | const FooWrapped = () =>
; 32 | 33 | FooWrapped.propTypes = process.env.NODE_ENV !== "production" ? someWrappingFunction(propTypesWrapped) : {}; 34 | const propTypesReferenced = { 35 | foo: PropTypes.string 36 | }; 37 | 38 | const FooReferenced = () =>
; 39 | 40 | FooReferenced.propTypes = process.env.NODE_ENV !== "production" ? propTypesReferenced : {}; 41 | export const propTypesExported = { 42 | foo: PropTypes.string 43 | }; 44 | 45 | const FooExported = () =>
; 46 | 47 | FooExported.propTypes = process.env.NODE_ENV !== "production" ? propTypesExported : {}; 48 | const propTypesCreateClass = process.env.NODE_ENV !== "production" ? { 49 | foo: PropTypes.string 50 | } : {}; 51 | const FooCreateClass = createReactClass({ 52 | propTypes: propTypesCreateClass 53 | }); 54 | -------------------------------------------------------------------------------- /test/fixtures/variable-comment-annotation/actual.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | import { connect } from 'react-redux' 4 | import FooComponent from './FooComponent' 5 | 6 | const Foo = connect(() => {}, () => {})(FooComponent); 7 | 8 | Foo.propTypes /* remove-proptypes */ = { 9 | bar: PropTypes.string.isRequired, 10 | } 11 | 12 | export default Foo 13 | -------------------------------------------------------------------------------- /test/fixtures/variable-comment-annotation/expected-remove-es5.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = babelHelpers.interopRequireDefault(require("react")); 9 | 10 | var _propTypes = babelHelpers.interopRequireDefault(require("prop-types")); 11 | 12 | var _reactRedux = require("react-redux"); 13 | 14 | var _FooComponent = babelHelpers.interopRequireDefault(require("./FooComponent")); 15 | 16 | var Foo = (0, _reactRedux.connect)(function () {}, function () {})(_FooComponent.default); 17 | var _default = Foo; 18 | exports.default = _default; 19 | -------------------------------------------------------------------------------- /test/fixtures/variable-comment-annotation/expected-remove-es6.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { connect } from 'react-redux'; 4 | import FooComponent from './FooComponent'; 5 | const Foo = connect(() => {}, () => {})(FooComponent); 6 | export default Foo; 7 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --require @babel/register 2 | --reporter dot 3 | --recursive 4 | test/{,**/}*.test.js 5 | -------------------------------------------------------------------------------- /test/utils.js: -------------------------------------------------------------------------------- 1 | // @flow weak 2 | 3 | export function trim(str) { 4 | return str.replace(/^\s+|\s+$/, '') 5 | } 6 | --------------------------------------------------------------------------------