babel-plugin-transform-react-remove-prop-types
Advanced tools
Comparing version
126
lib/index.js
@@ -11,11 +11,21 @@ 'use strict'; | ||
var wrapperIfTemplate = template('\n if (process.env.NODE_ENV !== "production") {\n NODE;\n }\n '); | ||
var VISITED_KEY = 'transform-react-remove-prop-types' + Date.now(); | ||
return { | ||
visitor: { | ||
Program: function Program(programPath, state) { | ||
var mode = state.opts.mode || 'remove'; | ||
var ignoreFilenames = void 0; | ||
if (state.opts.ignoreFilenames) { | ||
ignoreFilenames = new RegExp(state.opts.ignoreFilenames.join('|'), 'gi'); | ||
} else { | ||
ignoreFilenames = undefined; | ||
} | ||
var globalOptions = { | ||
visitedKey: 'transform-react-remove-prop-types' + Date.now(), | ||
wrapperIfTemplate: template('\n if (process.env.NODE_ENV !== "production") {\n NODE;\n }\n '), | ||
mode: state.opts.mode || 'remove', | ||
ignoreFilenames: ignoreFilenames, | ||
types: types | ||
}; | ||
// On program start, do an explicit traversal up front for this plugin. | ||
@@ -40,8 +50,4 @@ programPath.traverse({ | ||
if (parent) { | ||
remove(path, { | ||
visitedKey: VISITED_KEY, | ||
wrapperIfTemplate: wrapperIfTemplate, | ||
mode: mode, | ||
type: 'createClass', | ||
types: types | ||
(0, _remove2.default)(path, globalOptions, { | ||
type: 'createClass' | ||
}); | ||
@@ -61,8 +67,4 @@ } | ||
if (isReactClass(pathClassDeclaration.get('superClass'), scope)) { | ||
remove(path, { | ||
visitedKey: VISITED_KEY, | ||
wrapperIfTemplate: wrapperIfTemplate, | ||
mode: mode, | ||
(0, _remove2.default)(path, globalOptions, { | ||
type: 'class static', | ||
types: types, | ||
pathClassDeclaration: pathClassDeclaration | ||
@@ -93,17 +95,9 @@ }); | ||
if (isReactClass(superClass, scope)) { | ||
remove(path, { | ||
visitedKey: VISITED_KEY, | ||
wrapperIfTemplate: wrapperIfTemplate, | ||
mode: mode, | ||
type: 'class assign', | ||
types: types | ||
(0, _remove2.default)(path, globalOptions, { | ||
type: 'class assign' | ||
}); | ||
} | ||
} else if ((0, _isStatelessComponent2.default)(binding.path)) { | ||
remove(path, { | ||
visitedKey: VISITED_KEY, | ||
wrapperIfTemplate: wrapperIfTemplate, | ||
mode: mode, | ||
type: 'stateless', | ||
types: types | ||
(0, _remove2.default)(path, globalOptions, { | ||
type: 'stateless' | ||
}); | ||
@@ -122,4 +116,10 @@ } | ||
var _remove = require('./remove'); | ||
var _remove2 = _interopRequireDefault(_remove); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
// weak | ||
function isPathReactClass(path) { | ||
@@ -135,3 +135,3 @@ if (path.matchesPattern('React.Component') || path.matchesPattern('React.PureComponent')) { | ||
return false; | ||
} // weak | ||
} | ||
@@ -159,70 +159,2 @@ function isReactClass(superClass, scope) { | ||
return answer; | ||
} | ||
function remove(path, options) { | ||
var visitedKey = options.visitedKey, | ||
wrapperIfTemplate = options.wrapperIfTemplate, | ||
mode = options.mode, | ||
type = options.type, | ||
types = options.types; | ||
if (mode === 'remove') { | ||
// remove() crash in some conditions. | ||
if (path.parentPath.type === 'ConditionalExpression') { | ||
path.replaceWith(types.unaryExpression('void', types.numericLiteral(0))); | ||
} else { | ||
path.remove(); | ||
} | ||
} else if (mode === 'wrap') { | ||
// Prevent infinity loop. | ||
if (path.node[visitedKey]) { | ||
return; | ||
} | ||
path.node[visitedKey] = true; | ||
switch (type) { | ||
// This is legacy, we do not optimize it. | ||
case 'createClass': | ||
break; | ||
// Inspired from babel-plugin-transform-class-properties. | ||
case 'class static': | ||
{ | ||
var ref = void 0; | ||
var pathClassDeclaration = options.pathClassDeclaration; | ||
if (!pathClassDeclaration.isClassExpression() && pathClassDeclaration.node.id) { | ||
ref = pathClassDeclaration.node.id; | ||
} else { | ||
// Class without name not supported | ||
return; | ||
} | ||
var node = types.expressionStatement(types.assignmentExpression('=', types.memberExpression(ref, path.node.key), path.node.value)); | ||
// We need to append the node at the parent level in this case. | ||
if (pathClassDeclaration.parentPath.isExportDeclaration()) { | ||
pathClassDeclaration = pathClassDeclaration.parentPath; | ||
} | ||
pathClassDeclaration.insertAfter(node); | ||
path.remove(); | ||
break; | ||
} | ||
case 'class assign': | ||
case 'stateless': | ||
path.replaceWith(wrapperIfTemplate({ | ||
NODE: path.node | ||
})); | ||
break; | ||
default: | ||
break; | ||
} | ||
} else { | ||
throw new Error('transform-react-remove-prop-type: unsupported mode ' + mode + '.'); | ||
} | ||
} |
{ | ||
"name": "babel-plugin-transform-react-remove-prop-types", | ||
"version": "0.3.1", | ||
"version": "0.3.2", | ||
"description": "Remove unnecessary React propTypes from the production build", | ||
@@ -9,3 +9,3 @@ "main": "lib/index.js", | ||
"test:unit": "babel-node test/index.js", | ||
"test:unit:watch": "babel-node test/watch.js", | ||
"test:watch": "babel-node test/watch.js", | ||
"test": "npm run lint && npm run test:unit && npm run flow", | ||
@@ -12,0 +12,0 @@ "prebuild": "rm -rf lib/", |
@@ -66,3 +66,8 @@ # babel-plugin-transform-react-remove-prop-types | ||
"production": { | ||
"plugins": [["transform-react-remove-prop-types", {"mode": "wrap"}]] | ||
"plugins": [ | ||
["transform-react-remove-prop-types", { | ||
"mode": "wrap", | ||
"ignoreFilenames": ["node_modules"] | ||
}] | ||
] | ||
} | ||
@@ -96,3 +101,6 @@ } | ||
'transform-react-remove-prop-types', | ||
{mode: 'wrap'}, | ||
{ | ||
mode: 'wrap', | ||
ignoreFilenames: ['node_modules'], | ||
}, | ||
], | ||
@@ -119,2 +127,18 @@ ], | ||
### `ignoreFilenames` | ||
This filter generates a regular expression. | ||
Any filenames containing one of the array's strings will be ignored. | ||
By default, we match everything. | ||
Following the [Is it safe?](#user-content-is-it-safe) section, you might encounter a component | ||
depending on the `propTypes` at runtime to work. | ||
For this reason, we provide an array options to filter out some files and folders. | ||
For instance, you can ignore all the npm modules: | ||
```jsx | ||
ignoreFilenames: ['node_modules'], | ||
``` | ||
## Is it safe? | ||
@@ -121,0 +145,0 @@ |
125
src/index.js
// @flow weak | ||
import isStatelessComponent from './isStatelessComponent'; | ||
import remove from './remove'; | ||
@@ -43,88 +44,26 @@ function isPathReactClass(path) { | ||
function remove(path, options) { | ||
const { | ||
visitedKey, | ||
wrapperIfTemplate, | ||
mode, | ||
type, | ||
types, | ||
} = options; | ||
export default function ({ template, types }) { | ||
return { | ||
visitor: { | ||
Program(programPath, state) { | ||
let ignoreFilenames; | ||
if (mode === 'remove') { | ||
// remove() crash in some conditions. | ||
if (path.parentPath.type === 'ConditionalExpression') { | ||
path.replaceWith(types.unaryExpression('void', types.numericLiteral(0))); | ||
} else { | ||
path.remove(); | ||
} | ||
} else if (mode === 'wrap') { | ||
// Prevent infinity loop. | ||
if (path.node[visitedKey]) { | ||
return; | ||
} | ||
path.node[visitedKey] = true; | ||
switch (type) { | ||
// This is legacy, we do not optimize it. | ||
case 'createClass': | ||
break; | ||
// Inspired from babel-plugin-transform-class-properties. | ||
case 'class static': { | ||
let ref; | ||
let pathClassDeclaration = options.pathClassDeclaration; | ||
if (!pathClassDeclaration.isClassExpression() && pathClassDeclaration.node.id) { | ||
ref = pathClassDeclaration.node.id; | ||
if (state.opts.ignoreFilenames) { | ||
ignoreFilenames = new RegExp(state.opts.ignoreFilenames.join('|'), 'gi'); | ||
} else { | ||
// Class without name not supported | ||
return; | ||
ignoreFilenames = undefined; | ||
} | ||
const node = types.expressionStatement( | ||
types.assignmentExpression('=', types.memberExpression(ref, path.node.key), path.node.value), | ||
); | ||
const globalOptions = { | ||
visitedKey: `transform-react-remove-prop-types${Date.now()}`, | ||
wrapperIfTemplate: template(` | ||
if (process.env.NODE_ENV !== "production") { | ||
NODE; | ||
} | ||
`), | ||
mode: state.opts.mode || 'remove', | ||
ignoreFilenames, | ||
types, | ||
}; | ||
// We need to append the node at the parent level in this case. | ||
if (pathClassDeclaration.parentPath.isExportDeclaration()) { | ||
pathClassDeclaration = pathClassDeclaration.parentPath; | ||
} | ||
pathClassDeclaration.insertAfter(node); | ||
path.remove(); | ||
break; | ||
} | ||
case 'class assign': | ||
case 'stateless': | ||
path.replaceWith(wrapperIfTemplate( | ||
{ | ||
NODE: path.node, | ||
}, | ||
)); | ||
break; | ||
default: | ||
break; | ||
} | ||
} else { | ||
throw new Error(`transform-react-remove-prop-type: unsupported mode ${mode}.`); | ||
} | ||
} | ||
export default function ({ template, types }) { | ||
const wrapperIfTemplate = template(` | ||
if (process.env.NODE_ENV !== "production") { | ||
NODE; | ||
} | ||
`); | ||
const VISITED_KEY = `transform-react-remove-prop-types${Date.now()}`; | ||
return { | ||
visitor: { | ||
Program(programPath, state) { | ||
const mode = state.opts.mode || 'remove'; | ||
// On program start, do an explicit traversal up front for this plugin. | ||
@@ -149,8 +88,4 @@ programPath.traverse({ | ||
if (parent) { | ||
remove(path, { | ||
visitedKey: VISITED_KEY, | ||
wrapperIfTemplate, | ||
mode, | ||
remove(path, globalOptions, { | ||
type: 'createClass', | ||
types, | ||
}); | ||
@@ -171,8 +106,4 @@ } | ||
if (isReactClass(pathClassDeclaration.get('superClass'), scope)) { | ||
remove(path, { | ||
visitedKey: VISITED_KEY, | ||
wrapperIfTemplate, | ||
mode, | ||
remove(path, globalOptions, { | ||
type: 'class static', | ||
types, | ||
pathClassDeclaration, | ||
@@ -204,17 +135,9 @@ }); | ||
if (isReactClass(superClass, scope)) { | ||
remove(path, { | ||
visitedKey: VISITED_KEY, | ||
wrapperIfTemplate, | ||
mode, | ||
remove(path, globalOptions, { | ||
type: 'class assign', | ||
types, | ||
}); | ||
} | ||
} else if (isStatelessComponent(binding.path)) { | ||
remove(path, { | ||
visitedKey: VISITED_KEY, | ||
wrapperIfTemplate, | ||
mode, | ||
remove(path, globalOptions, { | ||
type: 'stateless', | ||
types, | ||
}); | ||
@@ -221,0 +144,0 @@ } |
24007
6.25%10
25%528
5.18%162
17.39%