Don't consider require-like calls to be likely HOCs (#15940)

This commit is contained in:
Dan Abramov 2019-06-20 16:13:18 +01:00 committed by GitHub
parent d4f384d25b
commit 3d0af2aea8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 3 deletions

View File

@ -13,6 +13,7 @@
"babel-jest": "^23.0.1",
"babel-plugin-check-es2015-constants": "^6.5.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-syntax-trailing-function-commas": "^6.5.0",
"babel-plugin-transform-async-to-generator": "^6.22.0",
"babel-plugin-transform-class-properties": "^6.11.5",

View File

@ -115,8 +115,40 @@ export default function(babel) {
if (!isComponentishName(name)) {
return false;
}
if (init.type === 'Identifier' || init.type === 'MemberExpression') {
return false;
switch (init.type) {
case 'ArrowFunctionExpression':
case 'FunctionExpression':
// Likely component definitions.
break;
case 'CallExpression': {
// Maybe a HOC.
// Try to determine if this is some form of import.
const callee = init.callee;
const calleeType = callee.type;
if (calleeType === 'Import') {
return false;
} else if (calleeType === 'Identifier') {
if (callee.name.indexOf('require') === 0) {
return false;
} else if (callee.name.indexOf('import') === 0) {
return false;
}
// Neither require nor import. Might be a HOC.
// Pass through.
} else if (calleeType === 'MemberExpression') {
// Could be something like React.forwardRef(...)
// Pass through.
} else {
// More complicated call.
return false;
}
break;
}
case 'TaggedTemplateExpression':
// Maybe something like styled.div`...`
break;
default:
return false;
}
const initPath = path.get('init');
const foundInside = findInnerComponents(

View File

@ -15,7 +15,7 @@ function transform(input, options = {}) {
return wrap(
babel.transform(input, {
babelrc: false,
plugins: ['syntax-jsx', freshPlugin],
plugins: ['syntax-jsx', 'syntax-dynamic-import', freshPlugin],
}).code,
);
}
@ -407,4 +407,31 @@ describe('ReactFreshBabelPlugin', () => {
`),
).toMatchSnapshot();
});
it('does not consider require-like methods to be HOCs', () => {
// None of these were declared in this file.
// It's bad to register them because that would trigger
// modules to execute in an environment with inline requires.
// So we expect the transform to skip all of them even though
// they are used in JSX.
expect(
transform(`
const A = require('A');
const B = foo ? require('X') : require('Y');
const C = requireCond(gk, 'C');
const D = import('D');
export default function App() {
return (
<div>
<A />
<B />
<C />
<D />
</div>
);
}
`),
).toMatchSnapshot();
});
});

View File

@ -1,5 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ReactFreshBabelPlugin does not consider require-like methods to be HOCs 1`] = `
const A = require('A');
const B = foo ? require('X') : require('Y');
const C = requireCond(gk, 'C');
const D = import('D');
export default function App() {
return <div>
<A />
<B />
<C />
<D />
</div>;
}
_c = App;
var _c;
__register__(_c, 'App');
`;
exports[`ReactFreshBabelPlugin generates signatures for function declarations calling hooks 1`] = `
var _s = __signature__();

View File

@ -620,6 +620,11 @@ babel-plugin-syntax-class-properties@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
babel-plugin-syntax-dynamic-import@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da"
integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=
babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.8.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"