Skip to content

Commit 6b2e449

Browse files
committed
Fix: Add support for relative Platform ES imports (inline-plugin)
read: #1521 (comment)
1 parent a817960 commit 6b2e449

2 files changed

Lines changed: 96 additions & 0 deletions

File tree

packages/metro-transform-plugins/src/__tests__/inline-plugin-test.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,4 +934,76 @@ describe('inline constants', () => {
934934

935935
compare([stripFlow, inlinePlugin], code, expected, {dev: false});
936936
});
937+
938+
test('replaces Platform.OS in the code if Platform is a top level relative Node.js require()', () => {
939+
// Source code before `@react-native/babel-preset`:
940+
// const { Platform } = require('../../Utilities/Platform');
941+
const code = `
942+
var _require2 = require('../../Utilities/Platform'),
943+
Platform = _require2.Platform;
944+
var test = Platform.OS === 'ios' ? 'ios' : 'not-ios';
945+
`;
946+
947+
compare([inlinePlugin], code, code.replace('Platform.OS', '"android"'), {
948+
inlinePlatform: true,
949+
platform: 'android',
950+
});
951+
});
952+
953+
test('replaces Platform.OS in the code if Platform is a top level relative ES import', () => {
954+
// Source code before `@react-native/babel-preset`:
955+
// import {Platform} from '../../Utilities/Platform';
956+
const code = `
957+
var _Platform = require("../../Utilities/Platform");
958+
var test = _Platform.Platform.OS === 'ios' ? 'ios' : 'not-ios';
959+
`;
960+
961+
compare(
962+
[inlinePlugin],
963+
code,
964+
code.replace('_Platform.Platform.OS', '"android"'),
965+
{
966+
inlinePlatform: true,
967+
platform: 'android',
968+
},
969+
);
970+
});
971+
972+
test('replaces Platform.select in the code if Platform is a top level relative Node.js require()', () => {
973+
const code = `
974+
var _require2 = require('../../Utilities/Platform'),
975+
Platform = _require2.Platform;
976+
977+
function a() {
978+
Platform.select({ios: 1, android: 2});
979+
var b = a.Platform.select({});
980+
}
981+
`;
982+
983+
compare([inlinePlugin], code, code.replace(/Platform\.select[^;]+/, '2'), {
984+
inlinePlatform: 'true',
985+
platform: 'android',
986+
});
987+
});
988+
989+
test('replaces Platform.select in the code if Platform is a top level relative ES import', () => {
990+
const code = `
991+
var _Platform = require("../../Utilities/Platform");
992+
993+
function a() {
994+
_Platform.Platform.select({ios: 1, android: 2});
995+
var b = a.Platform.select({});
996+
}
997+
`;
998+
999+
compare(
1000+
[inlinePlugin],
1001+
code,
1002+
code.replace(/_Platform\.Platform\.select[^;]+/, '2'),
1003+
{
1004+
inlinePlatform: 'true',
1005+
platform: 'android',
1006+
},
1007+
);
1008+
});
9371009
});

packages/metro-transform-plugins/src/utils/createInlinePlatformChecks.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,30 @@ export default function createInlinePlatformChecks(
148148
) {
149149
return true;
150150
}
151+
// Special case for handling transformed relative ES imports:
152+
// ```tsx
153+
// 1. Source code
154+
// import {Platform} from '../../Utilities/Platform';
155+
// const test = Platform.OS === 'ios' ? 1 : 2;
156+
//
157+
// 2. After `@react-native/babel-preset`
158+
// var _Platform = require("../../Utilities/Platform");
159+
// var test = _Platform.Platform.OS === 'ios' ? 1 : 2;
160+
// ```
161+
if (!identifier && isMemberExpression(node)) {
162+
const propIdentifier = patterns.find((pattern: {name: string}) =>
163+
isIdentifier(node.property, pattern),
164+
);
165+
const objName = node.object.name;
166+
if (
167+
propIdentifier &&
168+
objName != null &&
169+
isToplevelBinding(scope.getBinding(objName), isWrappedModule) &&
170+
objName.startsWith(`_${propIdentifier.name}`)
171+
) {
172+
return true;
173+
}
174+
}
151175
if (isImport(node, scope, patterns)) {
152176
return true;
153177
}

0 commit comments

Comments
 (0)