0
# Platform-Specific Inlining
1
2
Inlines platform-specific checks, development flags, and environment variables for React Native optimization, enabling platform-specific code paths and development vs production builds.
3
4
## Capabilities
5
6
### Inline Plugin
7
8
Performs compile-time inlining of platform checks and environment variables for React Native optimization.
9
10
```javascript { .api }
11
/**
12
* Creates a Babel plugin that inlines platform-specific code and environment variables
13
* @param context - Babel plugin context with types utility
14
* @param options - Configuration options for inlining behavior
15
* @returns Babel plugin object with platform and environment optimization
16
*/
17
function inlinePlugin(
18
context: { types: Types },
19
options: InlinePluginOptions
20
): PluginObj<State>;
21
22
interface InlinePluginOptions {
23
/** Whether this is a development build */
24
dev: boolean;
25
/** Whether to inline Platform.OS and Platform.select() calls */
26
inlinePlatform: boolean;
27
/** Whether the module is wrapped (affects scope detection) */
28
isWrapped: boolean;
29
/** Custom require function name (default: 'require') */
30
requireName?: string;
31
/** Target platform name (e.g., 'ios', 'android', 'web') */
32
platform: string;
33
}
34
35
interface State {
36
opts: InlinePluginOptions;
37
}
38
```
39
40
**Usage Examples:**
41
42
```javascript
43
const babel = require("@babel/core");
44
const { inlinePlugin } = require("metro-transform-plugins");
45
46
const code = `
47
import { Platform } from 'react-native';
48
49
if (__DEV__) {
50
console.log('Development mode');
51
}
52
53
const platformSpecific = Platform.select({
54
ios: 'iOS specific code',
55
android: 'Android specific code',
56
default: 'Fallback code'
57
});
58
59
const isProduction = process.env.NODE_ENV === 'production';
60
`;
61
62
const transformed = babel.transformSync(code, {
63
plugins: [
64
[inlinePlugin, {
65
dev: false,
66
inlinePlatform: true,
67
isWrapped: false,
68
platform: 'ios'
69
}]
70
]
71
});
72
73
// Result for iOS production build:
74
// import { Platform } from 'react-native';
75
//
76
// if (false) { // __DEV__ inlined to false
77
// console.log('Development mode');
78
// }
79
//
80
// const platformSpecific = 'iOS specific code'; // Platform.select inlined
81
//
82
// const isProduction = 'production'; // process.env.NODE_ENV inlined
83
```
84
85
### Development Flag Inlining
86
87
Replaces `__DEV__` global with boolean literals based on build configuration:
88
89
```javascript { .api }
90
/**
91
* __DEV__ global inlining
92
* Replaces __DEV__ identifier with boolean literal
93
*/
94
95
// When dev: true
96
if (__DEV__) { /* code */ } // → if (true) { /* code */ }
97
98
// When dev: false
99
if (__DEV__) { /* code */ } // → if (false) { /* code */ }
100
101
// Note: Combined with constant folding, this enables dead code elimination
102
```
103
104
### Environment Variable Inlining
105
106
Inlines `process.env.NODE_ENV` to string literals:
107
108
```javascript { .api }
109
/**
110
* Process environment inlining
111
* Replaces process.env.NODE_ENV with string literals
112
*/
113
114
// When dev: true
115
process.env.NODE_ENV === 'development' // → 'development' === 'development'
116
117
// When dev: false
118
process.env.NODE_ENV === 'production' // → 'production' === 'production'
119
```
120
121
### Platform OS Inlining
122
123
Inlines `Platform.OS` member expressions to platform string literals:
124
125
```javascript { .api }
126
/**
127
* Platform.OS inlining
128
* Replaces Platform.OS with target platform string
129
*/
130
131
// Configuration: platform: 'ios'
132
Platform.OS === 'ios' // → 'ios' === 'ios'
133
Platform.OS === 'android' // → 'ios' === 'android'
134
135
// Works with various Platform import patterns:
136
// import { Platform } from 'react-native';
137
// import * as ReactNative from 'react-native'; // ReactNative.Platform.OS
138
// const Platform = require('react-native').Platform;
139
```
140
141
### Platform Select Inlining
142
143
Inlines `Platform.select()` calls to platform-specific values:
144
145
```javascript { .api }
146
/**
147
* Platform.select() call inlining
148
* Replaces Platform.select() with platform-specific value
149
*/
150
151
// Original code
152
Platform.select({
153
ios: 'iOS value',
154
android: 'Android value',
155
web: 'Web value',
156
native: 'Native fallback',
157
default: 'Default fallback'
158
});
159
160
// When platform: 'ios' → 'iOS value'
161
// When platform: 'android' → 'Android value'
162
// When platform: 'web' → 'Web value'
163
// When platform: 'windows' → 'Native fallback' (if present)
164
// When platform: 'unknown' → 'Default fallback' (if present)
165
// When no match → undefined
166
```
167
168
### Platform Check Detection
169
170
Uses sophisticated AST analysis to detect platform-related code patterns:
171
172
```javascript { .api }
173
/**
174
* Platform detection utilities
175
* Identifies platform-related expressions and calls
176
*/
177
interface PlatformChecks {
178
/** Detects Platform.OS member expressions */
179
isPlatformNode(
180
node: MemberExpression,
181
scope: Scope,
182
isWrappedModule: boolean
183
): boolean;
184
185
/** Detects Platform.select() call expressions */
186
isPlatformSelectNode(
187
node: CallExpression,
188
scope: Scope,
189
isWrappedModule: boolean
190
): boolean;
191
}
192
```
193
194
### Import Pattern Recognition
195
196
Recognizes various import patterns for React Native Platform:
197
198
```javascript
199
// Direct import
200
import { Platform } from 'react-native';
201
202
// Namespace import
203
import * as ReactNative from 'react-native';
204
// Usage: ReactNative.Platform.OS
205
206
// CommonJS require
207
const { Platform } = require('react-native');
208
209
// Full namespace require
210
const ReactNative = require('react-native');
211
// Usage: ReactNative.Platform.OS
212
213
// Alternative React import (mapped internally)
214
import * as React from 'react';
215
// Usage: React.Platform.OS (mapped to 'react-native')
216
```
217
218
### Scope-Aware Detection
219
220
Properly handles variable scope to avoid false positives:
221
222
```javascript { .api }
223
/**
224
* Scope checking prevents incorrect inlining
225
* Only inlines global or Flow-declared variables
226
*/
227
228
// Global Platform - Will be inlined
229
Platform.OS
230
231
// Local Platform variable - Will NOT be inlined
232
function component() {
233
const Platform = { OS: 'custom' };
234
return Platform.OS; // Not inlined - local binding
235
}
236
237
// Wrapped module context detection
238
// Handles Metro's module wrapper function scope correctly
239
```
240
241
### Static Property Analysis
242
243
Ensures Platform.select objects have static properties before inlining:
244
245
```javascript { .api }
246
/**
247
* Static property validation
248
* Only inlines Platform.select() with static object properties
249
*/
250
251
// Valid for inlining - static properties
252
Platform.select({
253
ios: 'static',
254
android: 'values'
255
});
256
257
// NOT inlined - dynamic properties
258
Platform.select({
259
[dynamicKey]: 'value',
260
...spread
261
});
262
263
// NOT inlined - computed property access
264
Platform.select({
265
['computed']: 'value'
266
});
267
```
268
269
### Assignment Protection
270
271
Prevents inlining when variables are used in assignment contexts:
272
273
```javascript
274
// Will NOT be inlined - left-hand side of assignment
275
Platform.OS = 'modified';
276
277
// Will be inlined - right-hand side usage
278
const current = Platform.OS;
279
```
280
281
### Custom Require Names
282
283
Supports custom require function names for advanced bundling setups:
284
285
```javascript { .api }
286
/**
287
* Custom require function support
288
* @param requireName - Custom require function name (default: 'require')
289
*/
290
291
// With requireName: 'customRequire'
292
// Detects: customRequire('react-native').Platform.OS
293
// Instead of: require('react-native').Platform.OS
294
```