diff --git a/packages/metro-babel7-plugin-react-transform/__tests__/__fixtures__/babel7-regression/actual.js.es6 b/packages/metro-babel7-plugin-react-transform/__tests__/__fixtures__/babel7-regression/actual.js.es6 new file mode 100644 index 00000000..708d32ee --- /dev/null +++ b/packages/metro-babel7-plugin-react-transform/__tests__/__fixtures__/babel7-regression/actual.js.es6 @@ -0,0 +1,9 @@ +class Foo { + f() { + class Bar extends React.Component { + render() {} + } + + foo(Bar); + } +} diff --git a/packages/metro-babel7-plugin-react-transform/__tests__/__fixtures__/babel7-regression/babel.json b/packages/metro-babel7-plugin-react-transform/__tests__/__fixtures__/babel7-regression/babel.json new file mode 100644 index 00000000..06659d70 --- /dev/null +++ b/packages/metro-babel7-plugin-react-transform/__tests__/__fixtures__/babel7-regression/babel.json @@ -0,0 +1,7 @@ +{ + "transforms": [{ + "transform": "react-transform-hmr/lib/index.js", + "imports": ["react"], + "locals": ["module"] + }] +} diff --git a/packages/metro-babel7-plugin-react-transform/__tests__/__fixtures__/babel7-regression/expected.js.es6 b/packages/metro-babel7-plugin-react-transform/__tests__/__fixtures__/babel7-regression/expected.js.es6 new file mode 100644 index 00000000..15473dd3 --- /dev/null +++ b/packages/metro-babel7-plugin-react-transform/__tests__/__fixtures__/babel7-regression/expected.js.es6 @@ -0,0 +1,37 @@ +var _transformLib = _interopRequireDefault(require(\\"transform-lib\\")).default; + +const _components = { + Bar: { + displayName: \\"Bar\\", + isInFunction: true + } +}; + +const _transformLib2 = _transformLib({ + filename: \\"unknown\\", + components: _components, + locals: [], + imports: [] +}); + +function _wrapComponent(id) { + return function (Component) { + return _transformLib2(Component, id); + }; +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Foo { + f() { + const Bar = _wrapComponent(\\"Bar\\")(function () { + return class Bar extends React.Component { + render() {} + + }; + }()); + + foo(Bar); + } + +} diff --git a/packages/metro-babel7-plugin-react-transform/__tests__/__snapshots__/babel-plugin-react-transform-test.js.snap b/packages/metro-babel7-plugin-react-transform/__tests__/__snapshots__/babel-plugin-react-transform-test.js.snap index 30c05d1b..9db26621 100644 --- a/packages/metro-babel7-plugin-react-transform/__tests__/__snapshots__/babel-plugin-react-transform-test.js.snap +++ b/packages/metro-babel7-plugin-react-transform/__tests__/__snapshots__/babel-plugin-react-transform-test.js.snap @@ -1,5 +1,40 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`finds React components should babel7 regression 1`] = ` +"import _react from \\"react\\"; +import _reactTransformHmrLibIndexJs from \\"react-transform-hmr/lib/index.js\\"; +const _components = { + Bar: { + displayName: \\"Bar\\", + isInFunction: true + } +}; + +const _reactTransformHmrLibIndexJs2 = _reactTransformHmrLibIndexJs({ + filename: \\"unknown\\", + components: _components, + locals: [module], + imports: [_react] +}); + +function _wrapComponent(id) { + return function (Component) { + return _reactTransformHmrLibIndexJs2(Component, id); + }; +} + +class Foo { + f() { + class Bar extends React.Component { + render() {} + } + + Bar = _wrapComponent(\\"Bar\\")(Bar); + foo(Bar); + } +}" +`; + exports[`finds React components should code call expression with render method 1`] = ` "factory({ render() {} @@ -71,10 +106,10 @@ function _wrapComponent(id) { } import React, { Component } from 'react'; - -const Foo = _wrapComponent('Foo')(class Foo extends Component { +class Foo extends Component { render() {} -});" +} +Foo = _wrapComponent('Foo')(Foo);" `; exports[`finds React components should code class extends purecomponent with render method 1`] = ` @@ -99,10 +134,10 @@ function _wrapComponent(id) { } import React, { PureComponent } from 'react'; - -const Foo = _wrapComponent('Foo')(class Foo extends PureComponent { +class Foo extends PureComponent { render() {} -});" +} +Foo = _wrapComponent('Foo')(Foo);" `; exports[`finds React components should code class extends react component 1`] = `"class Foo extends React.Component {}"`; @@ -128,9 +163,10 @@ function _wrapComponent(id) { }; } -const Foo = _wrapComponent(\\"Foo\\")(class Foo extends React.Component { +class Foo extends React.Component { render() {} -});" +} +Foo = _wrapComponent(\\"Foo\\")(Foo);" `; exports[`finds React components should code class with render method 1`] = ` @@ -393,13 +429,14 @@ function _wrapComponent(id) { }; } -const Foo = _wrapComponent(\\"Foo\\")(class Foo extends BooComponent { +class Foo extends BooComponent { render() {} -}); - -const Bar = _wrapComponent(\\"Bar\\")(class Bar extends CustomComponent { +} +Foo = _wrapComponent(\\"Foo\\")(Foo); +class Bar extends CustomComponent { render() {} -});" +} +Bar = _wrapComponent(\\"Bar\\")(Bar);" `; exports[`finds React components should options multiple transforms 1`] = `"class Foo extends React.Component {}"`; @@ -433,9 +470,10 @@ function _wrapComponent(id) { }; } -const Foo = _wrapComponent(\\"Foo\\")(class Foo extends React.Component { +class Foo extends React.Component { render() {} -});" +} +Foo = _wrapComponent(\\"Foo\\")(Foo);" `; exports[`finds React components should options with imports 1`] = `"class Foo extends React.Component {}"`; @@ -463,9 +501,10 @@ function _wrapComponent(id) { }; } -const Foo = _wrapComponent(\\"Foo\\")(class Foo extends React.Component { +class Foo extends React.Component { render() {} -});" +} +Foo = _wrapComponent(\\"Foo\\")(Foo);" `; exports[`finds React components should options with locals 1`] = `"class Foo extends React.Component {}"`; @@ -491,7 +530,8 @@ function _wrapComponent(id) { }; } -const Foo = _wrapComponent(\\"Foo\\")(class Foo extends React.Component { +class Foo extends React.Component { render() {} -});" +} +Foo = _wrapComponent(\\"Foo\\")(Foo);" `; diff --git a/packages/metro-babel7-plugin-react-transform/lib/index.js b/packages/metro-babel7-plugin-react-transform/lib/index.js index c7fcfdd2..c6ac456c 100644 --- a/packages/metro-babel7-plugin-react-transform/lib/index.js +++ b/packages/metro-babel7-plugin-react-transform/lib/index.js @@ -125,6 +125,29 @@ module.exports = { // Can't wrap ClassDeclarations const isStatement = t.isStatement(path.node); + const isExport = t.isExportDefaultDeclaration(path.parent); + + if (isStatement && !isExport) { + // class decl + // need to work around Babel 7 detecting duplicate decls here + + path.insertAfter( + t.expressionStatement( + t.assignmentExpression( + '=', + t.identifier(componentId), + wrapComponent( + t.identifier(componentId), + componentId, + this.wrapperFunctionId, + ), + ), + ), + ); + + return; + } + const expression = t.toExpression(path.node); // wrapperFunction("componentId")(node) @@ -143,7 +166,7 @@ module.exports = { ]); } - if (t.isExportDefaultDeclaration(path.parent)) { + if (isExport) { path.parentPath.insertBefore(wrapped); path.parent.declaration = constId; } else {