UNPKG

2.41 kBJavaScriptView Raw
1module.exports = function pureComponentFallback({ types: t, template }) {
2 const buildPureOrNormalSuperclass = () => t.LogicalExpression('||',
3 t.memberExpression(t.identifier('React'), t.identifier('PureComponent')),
4 t.memberExpression(t.identifier('React'), t.identifier('Component')));
5
6 const buildShouldComponentUpdate = () => {
7 const method = t.classMethod(
8 'method',
9 t.logicalExpression(
10 '&&',
11 t.unaryExpression('!', t.memberExpression(t.identifier('React'), t.identifier('PureComponent'))),
12 t.stringLiteral('shouldComponentUpdate')
13 ),
14 [t.identifier('nextProps'), t.identifier('nextState')],
15 t.blockStatement([template('return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);')()]),
16 true
17 );
18 return method;
19 };
20
21 function superclassIsPureComponent(path) {
22 const superclass = path.get('superClass');
23 // check for PureComponent
24 if (t.isIdentifier(superclass)) {
25 return superclass.node.name === 'PureComponent';
26 }
27
28 if (t.isMemberExpression(superclass)) {
29 // Check for React.PureComponent
30 return superclass.get('object').node.name === 'React'
31 && superclass.get('property').node.name === 'PureComponent';
32 }
33
34 return false;
35 }
36
37 return {
38 visitor: {
39 Program: {
40 exit({ node }, { file }) {
41 if (file.get('addShallowEqualImport')) {
42 const shallowEqualImportDeclaration = t.importDeclaration([
43 t.importDefaultSpecifier(t.identifier('shallowEqual')),
44 ], t.stringLiteral('enzyme-shallow-equal'));
45 node.body.unshift(shallowEqualImportDeclaration);
46 }
47 },
48 },
49
50 ClassDeclaration(path, { file }) {
51 if (superclassIsPureComponent(path)) {
52 const superclassPath = path.get('superClass');
53
54 // Replace the superclass
55 superclassPath.replaceWith(buildPureOrNormalSuperclass());
56
57 // Only add an SCU if one doesn't already exist
58 const existingSCU = path.get('body').get('body').find((
59 p => p.isClassMethod() && p.get('key').node.name === 'shouldComponentUpdate'
60 ));
61
62 if (!existingSCU) {
63 file.set('addShallowEqualImport', true);
64 path.get('body').unshiftContainer('body', buildShouldComponentUpdate());
65 }
66 }
67 },
68 },
69 };
70};