Don't consider require-like calls to be likely HOCs (#15940)
Dan Abramov committed
Jun 20, 2019 at 16:13 UTC
3d0af2aea8c95d748af3b958de20668f247667da
5 files changed
+90
-3
package.json
+1
@@ -13,6 +13,7 @@
13
"babel-jest": "^23.0.1",
14
"babel-plugin-check-es2015-constants": "^6.5.0",
15
"babel-plugin-external-helpers": "^6.22.0",
16
+ "babel-plugin-syntax-dynamic-import": "^6.18.0",
17
"babel-plugin-syntax-trailing-function-commas": "^6.5.0",
18
"babel-plugin-transform-async-to-generator": "^6.22.0",
19
"babel-plugin-transform-class-properties": "^6.11.5",
packages/react-refresh/src/ReactFreshBabelPlugin.js
+34
-2
@@ -115,8 +115,40 @@ export default function(babel) {
115
if (!isComponentishName(name)) {
116
return false;
117
}
118
- if (init.type === 'Identifier' || init.type === 'MemberExpression') {
119
- return false;
118
+ switch (init.type) {
119
+ case 'ArrowFunctionExpression':
120
+ case 'FunctionExpression':
121
+ // Likely component definitions.
122
+ break;
123
+ case 'CallExpression': {
124
+ // Maybe a HOC.
125
+ // Try to determine if this is some form of import.
126
+ const callee = init.callee;
127
+ const calleeType = callee.type;
128
+ if (calleeType === 'Import') {
129
+ return false;
130
+ } else if (calleeType === 'Identifier') {
131
+ if (callee.name.indexOf('require') === 0) {
132
+ return false;
133
+ } else if (callee.name.indexOf('import') === 0) {
134
+ return false;
135
+ }
136
+ // Neither require nor import. Might be a HOC.
137
+ // Pass through.
138
+ } else if (calleeType === 'MemberExpression') {
139
+ // Could be something like React.forwardRef(...)
140
+ // Pass through.
141
+ } else {
142
+ // More complicated call.
143
+ return false;
144
+ }
145
+ break;
146
+ }
147
+ case 'TaggedTemplateExpression':
148
+ // Maybe something like styled.div`...`
149
+ break;
150
+ default:
151
+ return false;
152
}
153
const initPath = path.get('init');
154
const foundInside = findInnerComponents(
packages/react-refresh/src/__tests__/ReactFreshBabelPlugin-test.js
+28
-1
@@ -15,7 +15,7 @@ function transform(input, options = {}) {
15
return wrap(
16
babel.transform(input, {
17
babelrc: false,
18
- plugins: ['syntax-jsx', freshPlugin],
18
+ plugins: ['syntax-jsx', 'syntax-dynamic-import', freshPlugin],
19
}).code,
20
);
21
}
@@ -407,4 +407,31 @@ describe('ReactFreshBabelPlugin', () => {
407
`),
408
).toMatchSnapshot();
409
});
410
+
411
+ it('does not consider require-like methods to be HOCs', () => {
412
+ // None of these were declared in this file.
413
+ // It's bad to register them because that would trigger
414
+ // modules to execute in an environment with inline requires.
415
+ // So we expect the transform to skip all of them even though
416
+ // they are used in JSX.
417
+ expect(
418
+ transform(`
419
+ const A = require('A');
420
+ const B = foo ? require('X') : require('Y');
421
+ const C = requireCond(gk, 'C');
422
+ const D = import('D');
423
+
424
+ export default function App() {
425
+ return (
426
+ <div>
427
+ <A />
428
+ <B />
429
+ <C />
430
+ <D />
431
+ </div>
432
+ );
433
+ }
434
+ `),
435
+ ).toMatchSnapshot();
436
+ });
437
});
packages/react-refresh/src/__tests__/__snapshots__/ReactFreshBabelPlugin-test.js.snap
+22
@@ -1,5 +1,27 @@
1
// Jest Snapshot v1, https://goo.gl/fbAQLP
2
3
+exports[`ReactFreshBabelPlugin does not consider require-like methods to be HOCs 1`] = `
4
+
5
+const A = require('A');
6
+const B = foo ? require('X') : require('Y');
7
+const C = requireCond(gk, 'C');
8
+const D = import('D');
9
+
10
+export default function App() {
11
+ return <div>
12
+ <A />
13
+ <B />
14
+ <C />
15
+ <D />
16
+ </div>;
17
+}
18
+_c = App;
19
+
20
+var _c;
21
+
22
+__register__(_c, 'App');
23
+`;
24
+
25
exports[`ReactFreshBabelPlugin generates signatures for function declarations calling hooks 1`] = `
26
var _s = __signature__();
27
yarn.lock
+5
@@ -620,6 +620,11 @@ babel-plugin-syntax-class-properties@^6.8.0:
620
version "6.13.0"
621
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
622
623
+babel-plugin-syntax-dynamic-import@^6.18.0:
624
+ version "6.18.0"
625
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da"
626
+ integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=
627
+
628
babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.8.0:
629
version "6.18.0"
630
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"