diff --git a/packages/react-native-babel-preset/src/__tests__/inline-platform-plugin-test.js b/packages/react-native-babel-preset/src/__tests__/inline-platform-plugin-test.js index 2e182e5f763..8c3d53dba1a 100644 --- a/packages/react-native-babel-preset/src/__tests__/inline-platform-plugin-test.js +++ b/packages/react-native-babel-preset/src/__tests__/inline-platform-plugin-test.js @@ -483,6 +483,16 @@ describe('Platform.select', () => { expect(select('{ios: 1, ios: 2}')).toContain('const value=2'); }); + test('does not discard impure initializers', () => { + expectUnchanged(` + const value = require('react-native').Platform.select({ + ios: first(), + android: android(), + ios: last(), + }); + `); + }); + test('does not inline computed keys', () => { expect(select('{[key]: 1, default: 2}')).toContain('Platform.select'); }); diff --git a/packages/react-native-babel-preset/src/inline-platform-plugin.js b/packages/react-native-babel-preset/src/inline-platform-plugin.js index f70a24b3e95..b15fe01efd5 100644 --- a/packages/react-native-babel-preset/src/inline-platform-plugin.js +++ b/packages/react-native-babel-preset/src/inline-platform-plugin.js @@ -520,13 +520,23 @@ module.exports = function inlinePlatformPlugin( return; } - path.replaceWith( - findProperty(spec, platform, () => - findProperty(spec, 'native', () => - findProperty(spec, 'default', () => t.identifier('undefined')), - ), + const replacement = findProperty(spec, platform, () => + findProperty(spec, 'native', () => + findProperty(spec, 'default', () => t.identifier('undefined')), ), ); + // Inlining must not drop side effects from discarded property values. + if ( + spec.properties.some( + property => + t.isObjectProperty(property) && + property.value !== replacement && + !path.scope.isPure(property.value), + ) + ) { + return; + } + path.replaceWith(replacement); }, }, };