Giter Club home page Giter Club logo

babel-plugin-transform-react-remove-prop-types's People

Contributors

azizhk avatar bitfrost avatar bnjbvr avatar bryanrsmith avatar danez avatar dependabot[bot] avatar enoahnetzach avatar eps1lon avatar gandazgul avatar greenkeeperio-bot avatar helmus avatar insin avatar jjow avatar layershifter avatar lencioni avatar leusrox avatar lukeapage avatar newyork-anthonyng avatar nogsmpls avatar oliviertassinari avatar pkuczynski avatar strml avatar tquetano-netflix avatar vieron avatar vikr01 avatar wy-ei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

babel-plugin-transform-react-remove-prop-types's Issues

Let's merge projects

Hi. As I see your fork is much popular, than original project. Maybe we can join forces to make this plugin better?

Babel error with mode: "remove"

I recently tried integrating this plugin with react-virtualized. (I prefer declaring propTypes inside of the class body rather than at the footer so I was excited about the "wrap" mode.)

Running with mode: "remove" (the default) worked fine for me but when I tried running with mode: "wrap" I got the following error:

Error: source/ArrowKeyStepper/ArrowKeyStepper.js: We don't know what to do with this node type. We were previously a Statement but we can't fit in here?
    at NodePath.insertAfter (../node_modules/babel-core/node_modules/babel-traverse/lib/path/modification.js:175:13)
    at remove (../node_modules/babel-plugin-transform-react-remove-prop-types/lib/index.js:185:30)
    at ClassProperty (../node_modules/babel-plugin-transform-react-remove-prop-types/lib/index.js:58:17)
    at NodePath._call (../node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:76:18)
    at NodePath.call (../node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:48:17)
    at NodePath.visit (../node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:105:12)
    at TraversalContext.visitQueue (../node_modules/babel-core/node_modules/babel-traverse/lib/context.js:150:16)
    at TraversalContext.visitMultiple (../node_modules/babel-core/node_modules/babel-traverse/lib/context.js:103:17)
    at TraversalContext.visit (../node_modules/babel-core/node_modules/babel-traverse/lib/context.js:190:19)
    at Function.traverse.node (../node_modules/babel-core/node_modules/babel-traverse/lib/index.js:114:17)

FWIW, the container in question is of type: "ExportDefaultDeclaration" and the node is of type: "ClassDeclaration".

For what it's worth, I tried patching the change from your PR #45 onto my local version of babel-plugin-transform-react-remove-prop-types but it didn't seem to resolve the issue.

You can reproduce this issue (if you're interested) by checking out the propTypes branch of react-virtualized and then running:

npm i
npm run build

[question] /node_modules/prop-types/ functions expected in build?

We have a codebase based on react-boilerplate v3.4. I've been looking at the main.js that gets built and it includes references such as "./node_modules/prop-types/factoryWithThrowingShims.js" and var n=o("./node_modules/prop-types/node_modules/fbjs/lib/emptyFunction.js"),. Am I right in thinking that prop-types are not being removed in the build?

The .babelrc used is:

  "presets": [
    [
      "latest",
      {
        "es2015": {
          "modules": false
        }
      }
    ],
    "react",
    "stage-0"
  ],
  "env": {
    "production": {
      "only": [
        "app"
      ],
      "plugins": [
        "transform-react-remove-prop-types",
        "transform-react-inline-elements",
        "transform-react-constant-elements"
      ]
    },
    "analyze": {
      "only": [
        "app"
      ],
      "plugins": [
        "transform-react-remove-prop-types",
        "transform-react-inline-elements",
        "transform-react-constant-elements"
      ]
    },
    "test": {
      "plugins": [
        "transform-es2015-modules-commonjs",
        "dynamic-import-node"
      ]
    }
  }
}

and we most definitely pass the production flag with cross-env NODE_ENV=production webpack ... in our package.json scripts. All the code lives under the /app directory.

PropTypes aren't removed when extending via Object.assign()

When a component extends from parent and the properties are extended, they are not removed.

Sample Code:

export default class ComponentB extends ComponentA {
    static propTypes = Object.assign({}, {
        stringKey: PropTypes.string.isRequired,
    }, ComponentA.propTypes)
}

Edge case with stateless and cloneElement

Stateless function component that use React.cloneElement aren't supported:

// @flow weak

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import warning from 'warning';
import { createStyleSheet } from 'jss-theme-reactor';
import customPropTypes from '../utils/customPropTypes';

export const styleSheet = createStyleSheet('MuiListItemAvatar', () => {
  return {
    denseAvatar: {
      width: 36,
      height: 36,
      fontSize: 18,
      marginRight: 4,
    },
    denseAvatarIcon: {
      width: 20,
      height: 20,
    },
  };
});

/**
 * `<ListItemAvatar>` is a simple wrapper to apply the `dense` mode styles to `Avatar`.
 *
 * ```
 * <ListItemAvatar>
 *   <Avatar>
 * </ListItemAvatar>
 * ```
 */
export default function ListItemAvatar(props, context) {
  if (context.dense === undefined) {
    warning(false, `Material-UI: <ListItemAvatar> is a simple wrapper to apply the dense styles
      to <Avatar>. You do not need it unless you are controlling the <List> dense property.`);
    return props.children;
  }

  const {
    children,
    className: classNameProp,
    ...other
  } = props;
  const classes = context.styleManager.render(styleSheet);

  return React.cloneElement(children, {
    className: classNames(
      { [classes.denseAvatar]: context.dense },
      classNameProp,
      children.props.className,
    ),
    childrenClassName: classNames(
      { [classes.denseAvatarIcon]: context.dense },
      children.props.childrenClassName,
    ),
    ...other,
  });
}

ListItemAvatar.propTypes = {
  /**
   * The content of the component, normally `Avatar`.
   */
  children: PropTypes.element.isRequired,
  /**
   * The CSS class name of the root element.
   */
  className: PropTypes.string,
};

ListItemAvatar.contextTypes = {
  dense: PropTypes.bool,
  styleManager: customPropTypes.muiRequired,
};

PropTypes are not removed from inherited classes

Take a look at Parent class [1] and Child class [2] that extends Parent.

Once it's compiled with babel with babel-plugin-transform-react-remove-prop-types plugin, PropTypes are removed from Parent [3] class, but not from Child [4].

The test case repo contains gulpfile and .babelrc as well, @oliviertassinari.

Thanks!

[1] https://github.com/azasypkin/issues/blob/master/babel-plugin-transform-react-remove-prop-types/parent.jsx#L9-L11
[2] https://github.com/azasypkin/issues/blob/master/babel-plugin-transform-react-remove-prop-types/child.jsx#L10-L13
[3] https://github.com/azasypkin/issues/blob/master/babel-plugin-transform-react-remove-prop-types/dist/parent.js
[4] https://github.com/azasypkin/issues/blob/master/babel-plugin-transform-react-remove-prop-types/dist/child.js

Strategy for stripping propTypes from external packages

This is a question.

Say I have a .babelrc file like this:

{
  "presets": ["react", "es2015", "stage-1"],
  "env" : {
    "development" : {
        "presets" : ["react-hmre"]
    },
    "production" : {
        "plugins" : ["transform-react-remove-prop-types"]
    }
  }
}

And I'm building my project with webpack, so my JS loader looks like this:

            {
                test : /\.jsx?$/,
                exclude : /(?:node_modules)/,
                loaders : [ 'babel', 'eslint' ],
            },

As you can see node_modules are excluded, because running the transformer on npm code would be excessive / expensive. However, doing so means propType definitions from packages such as react-datepicker and react-autosuggest will remain in the final build.

So my question is, what would be the smartest strategy for removing propTypes from external packages in a setup like this?

Should we be convincing package authors to add this plugin to their builds with the wrap mode on?


P.S., I've tried just running the babel cli tool to strip propTypes from the compiled build, but that doesn't work (I guess, due to safeguards within your package to validate variables named propTypes are actually React related).

Wrapping propTypes with an environment check instead of removing them

Would it be feasible to wrap propType definitions in a if (process.env.NODE_ENV !== 'production') check (extracting them out first if they're part of a React.createClass()) instead of removing them completely?

This plugin is great and solves the problem of removing my own redundant propTypes for production, but it would be cool if it could also be adopted by authors transpiling reusable components to publish to npm, so your dependencies' propTypes could be available in development and test as normal, but automatically removed for production via the usual dead-code elimination process.

Could that be made an option into this plugin? Remove vs. move/wrap?

babel-react-optimize

After reading your medium post, I decided to actually write the babel preset that I've wanted for a little while.

A while back I wrote a transform for Facebook for transforming pure class components into plain functions: https://github.com/thejameskyle/babel-plugin-react-pure-components

I'm taking that and a few other ideas I have and putting them into the same kind of monorepo that we use for Babel projects: https://github.com/thejameskyle/babel-react-optimize

Since you are doing very similar checks for pure components, I thought we could abstract that logic into babel-helpers and share it between plugins.

Would you be interested in taking this code and putting it in a shared repo?

Possible bug

Not sure if this is a bug or an issue on my side.

I have a pure react component that returns a lodash map over a list

return map(mapList, (index) => {

when I build and run in production mode, I get an exception. I did some investigation and I concluded this line is the source of the issue

if (node.callee && node.callee.object.name === 'React' && node.callee.property.name === 'createElement')

you assume that the callee always has an object and property which in this specific case is not.

I can only fix this by not returning map directly but rather assign it to a variable and at the end return it

const mapper = map(mapList, (index) => {
...

return mapper

Now not sure if you still need to guard that the callee has an object and property before carrying on the rest of the test. otherwise just return false.

if (node.callee && node.callee.object && node.callee.object.name === 'React' && node.callee.property.name === 'createElement'

PureComponent support

React v15.3.0 was just shipped.
They have introduced a new component PureComponent. We should make sure we support it.

Class without name breaks

I have a context decorator that looks like this

export function context(contextTypes, passedContext) {
  return (DecoratedComponent) => {
    return class extends React.Component {
        static propTypes = DecoratedComponent.propTypes;
        static childContextTypes = contextTypes;
        getChildContext() {
          if (typeof passedContext === 'function') {
            return passedContext.bind(this)();
          } else {
            return passedContext;
          }
        }
        render() {
          return (
            <DecoratedComponent {...this.props} />
          );
        }
    };
  };
}

When compiling for production I get the following error:
Module build failed: TypeError: /.../index.js: Cannot read property 'name' of null
Seems to be related to #7 (#8). Any ideas on how to stop the removal of props when using a HOC?

Flow failed as node_modules

node_modules/babel-plugin-transform-react-remove-prop-types/src/index.js:83
 83:             const plugin = require(pluginName);
                                ^^^^^^^^^^^^^^^^^^^ The parameter passed to require() must be a literal string.


Found 1 error

Instead of removing propTypes, replace with empty object

Removing propTypes entirely is causing issues with third party dependencies that need them to be defined. This was causing issues when using react-native-web.

It was brought up that replacing propTypes with an empty object would have the effects of not needing those definitions, while allowing libraries to reference undefined properties on propTypes and prevent cannot read [name] of undefined errors.

Shouldn't this be a eslint plugin ?

Excuse me if I'm completely missing the point here, but, this seems like a bit of an after the fact solution.
In one way you could almost says it promotes not cleaning up your code.

If your declare a propType and then don't use it in your compoment, essentially it's an unused param, and it should be highlighted or removed from the code trough eslint.

It seems it does not work when importing modules

If I use this syntax, it works perfectly:

import React from 'react';

export default class MyComp extends React.Component {
    render() { 
        //...
    }
}

MyComp.propTypes = {
    name: React.PropTypes.object
}

however, it does not work like this:

import React, { Component } from 'react';

export default class MyComp extends Component {
    render() { 
        //...
    }
}

MyComp.propTypes = {
    name: React.PropTypes.object
}

ReactNative: `Component` has no propTypes defined

I think I just ran into the error situation mentioned here while using this plugin in my React Native app.

I accidentally wrote this code in my .babelrc:

...
  "plugins": [
    ...
    "transform-react-remove-prop-types"
    ...
  ]
...

Note that I did NOT put it under the production environment. Now in development, a bunch of my imported RN components from node_modules are complaining about not having prop types defined:

screen shot 2017-06-06 at 7 37 36 am

I have tried resetting the yarn cache, uninstalling and re-installing node modules, all to no avail. Is there a solution to basically undo the work this package has done and restore my project to where it was to begin with? I don't understand why a refresh of node_modules isn't solving the problem.

Please see a cross-post I made on the RN repo for additional info: facebook/react-native#14338

Thanks!

Publish latest

Could 775ebea be publish as 0.2.6 or 0.3.0. Was running into the same issue when directly inheriting from Component. Would be nice to be able to remove propTypes.

PropTypes in contextTypes and childContextTypes

Could this transform also do something with contextTypes and childContextTypes?

They're the only other places PropTypes are used AFAIK, so handling them too would allow complete removal of PropTypes from an app's own production built code. This would also be useful for slimming down the production build of libraries which use context while still allowing PropTypes to be validated in development.

React doesn't care which values they have in production, but uses their property names to validate that only expected child context is provided and to mask context properties which are made available to a child, so they should be wrapped by default rather than removed (although you might still want to be able remove them if doing a cross-compatible build for something like Preact, which implements context without contextTypes and childContextTypes).

Example input and expected output:

class Foo1 extends React.Component {
  static contextTypes = {
    bar1: React.PropTypes.string,
  };

  render() {}
}
class Foo1 extends React.Component {

  render() {}
}

process.env.NODE_ENV !== "production" ? Foo1.contextTypes = {
  bar1: React.PropTypes.string
} : {
  bar1: 1
};

Remove propTypes object for indirect assignment

This plugin removes the assignment of propTypes on react component, but it doesn't affect the referenced variable.

This means that the definition of the propTypes isn't removed.

For example:

const propTypes = {
  value: PropTypes.string,
};


export default function MyComponent() {
  return <div />;
}


MyComponent.propTypes = propTypes;

Becomes:

{
  value: PropTypes.string,
};


export default function MyComponent() {
  return <div />;
}

This is fine, except when referencing the propTypes from another component.

import MyComponent from './MyComponent';


const propTypes = {
  value: MyComponent.propTypes.value,
};


export default MyOtherComponent(props) {
  return <MyComponent value={props.value} />;
}


MyOtherComponent.propTypes = propTypes;

After processing this becomes:

import MyComponent from './MyComponent';


{
  value: MyComponent.propTypes.value,  // MyComponent.propTypes === undefined
};


export default MyOtherComponent(props) {
  return <MyComponent value={props.value} />;
}

This is a common use case, as this is the recommended way to define propTypes by the airbnb style guide (https://github.com/airbnb/javascript/tree/master/react#ordering)

I suggest to remove (or add an option to remove) the node that creates the propTypes object. So the latter example would simply become:

import MyComponent from './MyComponent';


export default MyOtherComponent(props) {
  return <MyComponent value={props.value} />;
}

When using wrap mode, the indirect assignment should be turned into a direct assignment. So the first example would be transformed into:

export default function MyComponent() {
  return <div />;
}


if (process.env.NODE_ENV !== 'production') {
  MyComponent.propTypes = {
    value: PropTypes.string,
  };
}

As a side effect, the bundle will become even smaller. ๐Ÿ˜„

TypeError: src/Checkbox/Checkbox.js: Cannot read property 'name' of null

Reproduction example using the wrap option:

// @flow weak

import { PropTypes } from 'react';
import { createStyleSheet } from 'jss-theme-reactor';
import { createSwitch } from '../internal/SwitchBase';
import withSwitchLabel from '../internal/withSwitchLabel';

export const styleSheet = createStyleSheet('MuiCheckbox', (theme) => {
  return {
    default: {
      color: theme.palette.text.secondary,
    },
    checked: {
      color: theme.palette.accent[500],
    },
    disabled: {
      color: theme.palette.action.disabled,
    },
  };
});

const Checkbox = createSwitch({ styleSheet });

Checkbox.displayName = 'Checkbox';

export default Checkbox;

const LabelCheckbox = withSwitchLabel(Checkbox);

export { LabelCheckbox };

/**
 * [Checkboxes](https://material.io/guidelines/components/selection-controls.html#selection-controls-checkbox)
 * allow the user to select multiple options from a set.
 */
export class CheckboxDocs {
  render() {}
  static propTypes = {
    /**
     * If `true`, the component is checked.
     */
    checked: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
    /**
     * The CSS class name of the root element when checked.
     */
    checkedClassName: PropTypes.string,
    /**
     * The icon to display when the component is checked.
     */
    checkedIcon: PropTypes.node,
    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,
    /**
     * @ignore
     */
    defaultChecked: PropTypes.bool,
    /**
     * If `true`, the switch will be disabled.
     */
    disabled: PropTypes.bool,
    /**
     * The CSS class name of the root element when disabled.
     */
    disabledClassName: PropTypes.string,
    /**
     * The icon to display when the component is unchecked.
     * If a string is provided, it will be used as a font ligature.
     */
    icon: PropTypes.node,
    /*
     * @ignore
     */
    name: PropTypes.string,
    /**
     * Callback fired when the state is changed.
     *
     * @param {object} event `change` event
     * @param {boolean} checked The `checked` value of the switch
     */
    onChange: PropTypes.func,
    /**
     * If `false`, the ripple effect will be disabled.
     */
    ripple: PropTypes.bool,
    /**
     * @ignore
     */
    tabIndex: PropTypes.string,
    /**
     * The value of the component.
     */
    value: PropTypes.string,
  };
}

Error

TypeError: src/components/button/index.js: Cannot read property 'name' of undefined
    at ClassProperty (/Users/neoziro/projects/xxx/node_modules/babel-plugin-transform-react-remove-prop-types/lib/index.js:55:84)
import React, {PropTypes} from 'react';
import styles from './button.scss';
import BaseComponent from 'components/base';
import classnames from 'classnames';

export default class Button extends BaseComponent {
  static propTypes = {
    block: PropTypes.bool,
    large: PropTypes.bool
  };

  styles = styles;

  render() {
    const {className: propClassName, children, block, large, ...props} = this.props;
    const className = classnames(styles.btn, {
      [styles.btnBlock]: block,
      [styles.btnLarge]: large
    }, propClassName);
    return <button {...{className}} {...props}>{children}</button>;
  }
}

Is the babel-core dependency needed?

Does this plugin need babel-core in its dependencies? It doesn't seem to depend on it at runtime.

Context for my question: I'm hoping to include this plugin in a Babel presets module which manually deduplicates dependencies to make Babel 6 presets less painful for people still on npm2.

Updating wording of "Remove unnecessary React propTypes"

Remove unnecessary React propTypes from the production build. You can save bandwidth by removing them.

I think it is ambiguous as to why exactly they are unnecessary. ( and also caused my initial confusion )

I would propose this:

Remove React propTypes from the production build, as they are unnecessary in production. You can save bandwidth by removing them.

False positive?

Following facebook/react-native#6750,
It seems that we have a false positive:

import {View} from 'react-native';

class CustomView extends React.Component {
  static propTypes = {
    style: View.propTypes.style
  };
  render() {
    return (
      <View style={this.props.style}>..</View>
    );
  }
}
SyntaxError: src/SwipeableViews.animated.js: You are accessing the propTypes from an imported Identifier.
It's likely to break at runtime. Instead, import the propTypes.
For more details, have a look at this issue: https://goo.gl/sHDdUk.
  115 |      * on the slide component.
  116 |      */
> 117 |     slideStyle: View.propTypes.style,
      |                 ^
  118 |     /**
  119 |      * This is the config given to Animated for the spring.
  120 |      * This is useful to change the dynamic of the transition.

Why is React.createClass not supported anymore?

First all @oliviertassinari thank you for maintaining this package and repo!

I wanted to ask about the previously supported React.createClass. Was there a specific reason for dropping this support from the previous fork? Was there a specific issue in supporting or did you simply want to concentrate support for es6 class style.

I searched but I couldn't find any more info on this.

My current use case is a codebase that uses React.createClass across. Without doing a codemod I wanted to see if there was an alternative to take advantage of fully removing propTypes in production.

Thanks!
Peter

PropTypes not removed for ES Class Inheritance

./components/Parent.jsx

import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';

export default class Parent extends PureComponent {
    static propTypes = {
        parentProp: PropTypes.string.isRequired,
    }
}

./components/Child.jsx

import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';
import Parent from './Parent';

export default class Child extends Parent {
    static propTypes = {
        childProp: PropTypes.string.isRequired,
    }
}

Flow warning

Flow 0.48.0 outputs the following warning:

node_modules/babel-plugin-transform-react-remove-prop-types/src/index.js:81
 81:             const plugin = require(pluginName);
                                ^^^^^^^^^^^^^^^^^^^ The parameter passed to require() must be a literal string.

Some modules actually rely on propTypes

Hi,

thank you for the plugin. It works well. I noticed though that some of the RN 3rd party modules rely on propTypes property. See for example react-native-vector-icons\lib\icon-button.js. Removing propTypes then results in

AndroidRuntime: com.facebook.react.common.JavascriptException: 
Requested keys of a value that is not an object., stack:

I modified my version of the plugin, so that only files not residing in node_modules are cleaned up preventing this type of crashes. In a function like isModule below I check if it's my own file or not and only then remove propTypes:

	function isModule(scope) {
		if (!scope.hub.file.opts) {
			return true;
		}
		var filename = scope.hub.file.opts.filename;
		if (!filename) {
			return true;
		}
		return filename.indexOf("node_modules") !== -1;
	}

I thought maybe it's worth adding an extra option to the plugin that would allow to skip 3rd party modules modification if needed.

PropTypes not always removed from stateless function components

We have a file containing several stateless function components, and one of those components is not having its PropTypes removed. I can't see why, since you have test cases for similar situations. This is what the file roughly looks like:

import CustomPropTypes from 'custom-prop-types';
import React from 'react';

export const Message = ({ className, isSent }) => {
  return (
    <div className={className} />
  );
};

Message.propTypes = {
  className: PropTypes.string,
  isSent: PropTypes.bool
};

/* โ€ฆ4 more components */

const FullMessage = ({ className, entry, isSent }) => {
  return (
    <div className={className} />
  );
};

// these PropTypes are never removed
FullMessage.propTypes = {
  className: PropTypes.string,
  entry: CustomPropTypes.entry.isRequired,
  isSent: PropTypes.bool
};

export default FullMessage;

There are the babel dependencies

"babel-plugin-transform-react-remove-prop-types": "0.2.10"
"babel-plugin-transform-runtime": "6.15.0"
"babel-preset-es2015": "6.18.0"
"babel-preset-react": "6.16.0"
"babel-preset-stage-1": "6.16.0"
"babel-core": "6.13.2" // because in versions >6.13.2 we can't set breakpoints in dev tools
"babel-runtime": "6.11.6"

support new prop-types package

Today's announcement includes a deprecation of React.PropTypes and an introduction of a new package prop-types. I expect not a whole lot of code will need to be added to support this. I'm happy to do it with a little direction.

[question] Is is removing both - React.PropTypes and PropTypes?

Never had to write AST transforms, so its quite hard to deduce this from the source code.

Is it removing both versions of PropTypes? From what I understand its also working by default for whole node_modules.

Another questions is - what exactly is stopping this transform to work? From my observations - PropTypes cannot use imported definitions, is that right?

Libraries I have problem with - react-textarea-autosize, react-visibility-sensor, react-linkify, react-transition-group

Example on how to use in webpack

I'm assuming something like this:

    var RemovePropTypesPlugin = require('babel-plugin-transform-react-remove-prop-types');

    plugins: [
         new RemovePropTypesPlugin(),
    ]

PropTypes not removed from 'createClass' in some situations

Looks like propTypes aren't removed from a component created with createClass in some situations. I've only quickly looked into it, but these are examples of code that still contains propTypes (and throws errors in production because the View propTypes don't exist anymore):

import View from 'View';

const ScrollView = React.createClass({
  propTypes: {
    children: View.propTypes.children
  }
});

and

import View from 'View';

const ScrollView = React.createClass({
  propTypes: {
    ...View.propTypes,
    onScroll: PropTypes.func
  }
});

Property consequent of ConditionalExpression expected node to be of a type ["Expression"] but instead got null

When trying to run with webpack 2.2.1, I'm getting the following error:

ERROR in ./~/react-intl/lib/index.es.js
Module build failed: TypeError: [redacted]/node_modules/react-intl/lib/index.es.js: Property consequent of ConditionalExpression expected node to be of a type ["Expression"] but instead got null
Module build failed: TypeError: [redacted]/node_modules/react-intl/lib/index.es.js: Property consequent of ConditionalExpression expected node to be of a type ["Expression"] but instead got null
    at Object.validate ([redacted]/node_modules/babel-types/lib/definitions/index.js:109:13)
    at Object.validate ([redacted]/node_modules/babel-types/lib/index.js:511:9)
    at NodePath._replaceWith ([redacted]/node_modules/babel-traverse/lib/path/replacement.js:176:7)
    at NodePath._remove ([redacted]/node_modules/babel-traverse/lib/path/removal.js:58:10)
    at NodePath.remove ([redacted]/node_modules/babel-traverse/lib/path/removal.js:30:8)
    at remove ([redacted]/node_modules/babel-plugin-transform-react-remove-prop-types/lib/index.js:157:10)
    at AssignmentExpression ([redacted]/node_modules/babel-plugin-transform-react-remove-prop-types/lib/index.js:97:15)
    at NodePath._call ([redacted]/node_modules/babel-traverse/lib/path/context.js:76:18)
    at NodePath.call ([redacted]/node_modules/babel-traverse/lib/path/context.js:48:17)
    at NodePath.visit ([redacted]/node_modules/babel-traverse/lib/path/context.js:105:12)
    at TraversalContext.visitQueue ([redacted]/node_modules/babel-traverse/lib/context.js:150:16)
    at TraversalContext.visitSingle ([redacted]/node_modules/babel-traverse/lib/context.js:108:19)
    at TraversalContext.visit ([redacted]/node_modules/babel-traverse/lib/context.js:192:19)
    at Function.traverse.node ([redacted]/node_modules/babel-traverse/lib/index.js:114:17)
    at NodePath.visit ([redacted]/node_modules/babel-traverse/lib/path/context.js:115:19)
    at TraversalContext.visitQueue ([redacted]/node_modules/babel-traverse/lib/context.js:150:16)
    at TraversalContext.visitSingle ([redacted]/node_modules/babel-traverse/lib/context.js:108:19)
    at TraversalContext.visit ([redacted]/node_modules/babel-traverse/lib/context.js:192:19)
    at Function.traverse.node ([redacted]/node_modules/babel-traverse/lib/index.js:114:17)
    at NodePath.visit ([redacted]/node_modules/babel-traverse/lib/path/context.js:115:19)
    at TraversalContext.visitQueue ([redacted]/node_modules/babel-traverse/lib/context.js:150:16)
    at TraversalContext.visitMultiple ([redacted]/node_modules/babel-traverse/lib/context.js:103:17)
    at TraversalContext.visit ([redacted]/node_modules/babel-traverse/lib/context.js:190:19)
    at Function.traverse.node ([redacted]/node_modules/babel-traverse/lib/index.js:114:17)
    at traverse ([redacted]/node_modules/babel-traverse/lib/index.js:79:12)
    at NodePath.traverse ([redacted]/node_modules/babel-traverse/lib/path/index.js:144:25)
    at PluginPass.Program ([redacted]/node_modules/babel-plugin-transform-react-remove-prop-types/lib/index.js:21:21)
    at newFn ([redacted]/node_modules/babel-traverse/lib/visitors.js:276:21)
    at NodePath._call ([redacted]/node_modules/babel-traverse/lib/path/context.js:76:18)
    at NodePath.call ([redacted]/node_modules/babel-traverse/lib/path/context.js:48:17)
 @ ./src/containers/MatchCenterScores.js 31:17-38
 @ ./src/containers/index.js
 @ ./src/app.js

Here is my .babelrc:

{
    "presets": ["es2015", "react"],
    "plugins": [
        ["transform-object-rest-spread", {useBuiltIns: true}],
        "transform-es2015-destructuring",
        "transform-class-properties",
        "transform-export-extensions",
        "lodash",
        "react-intl",
        "transform-node-env-inline",
        //"transform-inline-environment-variables",
        "transform-react-remove-prop-types"
    ]
}

Here is my webpack config:

var path = require('path')
module.exports = {
    entry: './src/app.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'build')
    },
    module: {
        rules: [
            {test: /\.(js|jsx)$/, use: 'babel-loader'}
        ]
    },
    resolve: {
        modules: [path.resolve(__dirname, 'src'), 'node_modules']
    }
}

Babel configuration doesn't accept plugin with options - path must be a string

The following fails once I try to add an option to babel-plugin-flow-react-proptypes:

    ["transform-react-remove-prop-types", {
          "mode": "wrap",
          "plugins": [
            ["babel-plugin-flow-react-proptypes", {"omitRuntimeTypeExport": true}],
            "babel-plugin-transform-flow-strip-types"
          ]
        }]
AssertionError [ERR_ASSERTION]: path must be a string
    at Module.require (module.js:512:3)
    at require (internal/module.js:11:18)
    at /Users/kross/projects/material-ui/node_modules/babel-plugin-transform-react-remove-prop-types/lib/index.js:35:26
    at Array.map (native)
    at PluginPass.Program (/Users/kross/projects/material-ui/node_modules/babel-plugin-transform-react-remove-prop-types/lib/index.js:34:52)
    at newFn (/Users/kross/projects/material-ui/node_modules/babel-traverse/lib/visitors.js:276:21)
    at NodePath._call (/Users/kross/projects/material-ui/node_modules/babel-traverse/lib/path/context.js:76:18)
    at NodePath.call (/Users/kross/projects/material-ui/node_modules/babel-traverse/lib/path/context.js:48:17)
    at NodePath.visit (/Users/kross/projects/material-ui/node_modules/babel-traverse/lib/path/context.js:105:12)
    at TraversalContext.visitQueue (/Users/kross/projects/material-ui/node_modules/babel-traverse/lib/context.js:150:16)

Error with stateless component

The following component returns an error when compiled with this plugin:

import React, { PropTypes } from 'react';

var Message = ({isFetching, isSuccess, isFailure, errorMsg}) => {
  let messageType;
  let messageTxt;
  if (isFetching) {
    messageType = 'warning';
    messageTxt = 'Pending call...';
  } else if (isSuccess) {
    messageType = 'success';
    messageTxt = 'Repo pushed successfully';
  } else if (isFailure) {
    messageType = 'danger';
    messageTxt = 'Something wrong occured';
  }

  if (messageTxt === null) {
    return;
  }

  return <div className={'alert alert-' + messageType} role='alert'>{messageTxt}</div>;
};

Message.propTypes = {
  isFetching: PropTypes.bool.isRequired,
  isSuccess: PropTypes.bool.isRequired,
  isFailure: PropTypes.bool.isRequired,
  errorMsg: PropTypes.string.isRequired
};

export default Message;

The error is the following:

Module build failed: TypeError: /Users/harijoe/Projects/perso/src/components/Message.js: Cannot read property 'type' of null

Go one step deeper by removing the PropTypes import

This plugin has been focusing on doing a single task so far: removing the propTypes.
However, we could be smarter. As raised by @kentcdodds, removing the prop types is one thing, we also have the import to take care of:

import PropTypes from 'prop-types';

I'm wondering if UglifyJS2 and other dead code eliminator tools are smart enough to take care of it, otherwise, we would have to implement it.

propTypes not removed for HOC

Hello,
I've just installed this and it seems that for my edge cases this is not working.

The following propTypes are not removed from the build. While all the others declared in the standard way are correctly removed.

CASE 1:

const myPropName = 'whatever';
BaseLink.propTypes = {
  prop1: PropTypes.string
  prop2: PropTypes.node
};

BaseLink.propTypes[myPropName] = PropTypes.object;  //<== This is not removed

CASE 2:

const myPropName = 'whatever';
// Both are not removed
MyComp.wrappedComponent.propTypes = {};
MyComp.wrappedComponent.propTypes[myPropName] = PropTypes.object.isRequired;

Here I used wrappedComponents, because I'm decorating my original component MyComp with mobx-react @observer that will indeed create a new wrapper. So the original component is available as MyComp.wrappedComponent.

CASE 3:
This applies to both cases above.
I'm importing my PropTypes from the new separate packages

import PropTypes from 'prop-types';

It seems the import is never removed from the build using the default config (supposed to be remove mode).

I'm not sure if this is due to the 2 cases above (still having some propTypes in the build would not allow to remove the import?) or because I import them from the separate package and not from the React core... ๐Ÿค”

Remove propTypes on stateless components

Hi!
Thanks for this plugin, just what I was looking for!

However, this plugin doesn't remove propTypes from stateless components. That is, it doesn't remove this:

const MyComponent = (props) => (
  <div></div>
);

MyComponent.propTypes = {
  someProp: React.PropTypes.string
};

Isn't this something that should be considered? I think stripping the propTypes should be okey in this case:

  1. The object that propTypes is assigned to is a function in the same module.
  2. The said function contains JSX directly inside the function body.

This doesn't work if you're not using JSX, so I could see it also removing the propTypes if:

  1. The said function takes a single argument called props or destructuring is used on that single argument and it destructures it to variable names which also exists in the propTypes object.

An even simpler way of detecting it would be to always strip the propTypes if the object it's assigned to is a function. It would be simpler to implement, but with the risk of false positives. Although I can't think of a use case where you use this plugin but you have propTypes that you don't want to remove.

Plugin 1 specified in "base.env.production" provided an invalid property of "default"

require("babel-core").transform("code", {
  plugins: [require('babel-plugin-transform-react-remove-prop-types')]
});

error info:

Error: Plugin 1 specified in "base.env.production" provided an invalid property of "default" while parsing file: /home/development/Projects/project/js/main.js
    at Plugin.init (/home/development/Projects/project/node_modules/babel-core/lib/transformation/plugin.js:115:13)
    at Function.normalisePlugin (/home/development/Projects/project/node_modules/babel-core/lib/transformation/file/options/option-manager.js:149:12)
    at /home/development/Projects/project/node_modules/babel-core/lib/transformation/file/options/option-manager.js:183:30
    at Array.map (native)
    at Function.normalisePlugins (/home/development/Projects/project/node_modules/babel-core/lib/transformation/file/options/option-manager.js:155:20)
    at OptionManager.mergeOptions (/home/development/Projects/project/node_modules/babel-core/lib/transformation/file/options/option-manager.js:277:36)
    at OptionManager.mergeOptions (/home/development/Projects/project/node_modules/babel-core/lib/transformation/file/options/option-manager.js:330:10)
    at OptionManager.init (/home/development/Projects/project/node_modules/babel-core/lib/transformation/file/options/option-manager.js:465:10)
    at File.initOptions (/home/development/Projects/project/node_modules/babel-core/lib/transformation/file/index.js:194:75)
    at new File (/home/development/Projects/project/node_modules/babel-core/lib/transformation/file/index.js:123:22)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.