From c190a543cae22a1201ef6f37ff8159bea7f224ba Mon Sep 17 00:00:00 2001 From: Clint Goodman Date: Thu, 25 Mar 2021 08:50:42 -0600 Subject: [PATCH] fix: constant variables only enable constant react elements issue-13051 --- .../src/index.js | 6 +++++- .../constant-elements/deopt-mutable-complex/output.mjs | 4 +--- .../constant-elements/deopt-mutable/output.mjs | 4 +--- .../test/fixtures/constant-elements/for-loop/input.js | 10 ++++++++++ .../test/fixtures/constant-elements/for-loop/output.js | 10 ++++++++++ .../constant-elements/global-reference/output.js | 4 +--- 6 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/input.js create mode 100644 packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/output.js diff --git a/packages/babel-plugin-transform-react-constant-elements/src/index.js b/packages/babel-plugin-transform-react-constant-elements/src/index.js index 2e486772bdd8..873b15a4d43b 100644 --- a/packages/babel-plugin-transform-react-constant-elements/src/index.js +++ b/packages/babel-plugin-transform-react-constant-elements/src/index.js @@ -64,13 +64,17 @@ export default declare((api, options) => { // Ignore identifiers & JSX expressions. if ( path.isJSXIdentifier() || - path.isIdentifier() || path.isJSXMemberExpression() || path.isJSXNamespacedName() ) { return; } + if (path.isIdentifier()) { + const binding = path.scope.getBinding(path.node.name); + if (binding && binding.constant) return; + } + if (!path.isImmutable()) { // If it's not immutable, it may still be a pure expression, such as string concatenation. // It is still safe to hoist that, so long as its result is immutable. diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable-complex/output.mjs b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable-complex/output.mjs index a4e8fa17c05a..83c8f677226e 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable-complex/output.mjs +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable-complex/output.mjs @@ -1,5 +1,3 @@ -var _span; - let foo = 'hello'; const mutate = () => { @@ -8,5 +6,5 @@ const mutate = () => { export const Component = () => { if (Math.random() > 0.5) mutate(); - return _span || (_span = {foo}); + return {foo}; }; diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable/output.mjs b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable/output.mjs index 15241789ceae..dd266a198d47 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable/output.mjs +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable/output.mjs @@ -1,7 +1,5 @@ -var _span; - let foo = 'hello'; export const Component = () => { foo = 'goodbye'; - return _span || (_span = {foo}); + return {foo}; }; diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/input.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/input.js new file mode 100644 index 000000000000..1dcb56c03217 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/input.js @@ -0,0 +1,10 @@ +function render() { + const nodes = []; + + for(let i = 0; i < 5; i++) { + nodes.push(
{i}
) + } + + return nodes; +} + \ No newline at end of file diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/output.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/output.js new file mode 100644 index 000000000000..af1cee1ef5fc --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/output.js @@ -0,0 +1,10 @@ +function render() { + const nodes = []; + + for (let i = 0; i < 5; i++) { + nodes.push(
{i}
); + } + + return nodes; +} + \ No newline at end of file diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/global-reference/output.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/global-reference/output.js index e7d32f1d64b6..dbaf45c6d760 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/global-reference/output.js +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/global-reference/output.js @@ -1,7 +1,5 @@ -var _div; - var Foo = React.createClass({ render: function render() { - return _div || (_div =
); + return
; } });