-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(babel): add process.env.EXPO_OS (expo#27509)
# Why Add support for detecting the platform without needing to import `react-native` or `react-native-web`. <!-- Please describe the motivation for this PR, and link to relevant GitHub issues, forums posts, or feature requests. --> # How Add a babel plugin to replace `process.env.EXPO_OS` with the current `caller.platform` environment variable. Unlike `Platform.OS` which performs fake minifying ahead of time, this value cannot be used to remove unused require statements. We can fix this when we add tree shaking in the future. This transform can be used in any node module and is not limited to application code, similar to NODE_ENV. <!-- How did you build this feature or fix this bug and why? --> # Test Plan - Added tests for the babel transforms and sanity tests for minification to better understand the limitations of code removal in Metro. --------- Co-authored-by: Expo Bot <[email protected]>
- Loading branch information
Showing
11 changed files
with
238 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
104 changes: 104 additions & 0 deletions
104
packages/babel-preset-expo/src/__tests__/minify-sanity.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Run a number of basic operations on the minifier to ensure it works as expected | ||
import * as babel from '@babel/core'; | ||
|
||
import { minifyLikeMetroAsync } from './minify-util'; | ||
import preset from '..'; | ||
|
||
function getCaller(props: Record<string, string | boolean>): babel.TransformCaller { | ||
return props as unknown as babel.TransformCaller; | ||
} | ||
|
||
const DEFAULT_OPTS = { | ||
babelrc: false, | ||
presets: [[preset]], | ||
plugins: [ | ||
// Fold constants to emulate Metro | ||
require('metro-transform-plugins/src/constant-folding-plugin.js'), | ||
], | ||
sourceMaps: true, | ||
filename: 'unknown', | ||
configFile: false, | ||
compact: true, | ||
comments: false, | ||
retainLines: false, | ||
}; | ||
|
||
it(`removes unused functions in development`, async () => { | ||
const options = { | ||
...DEFAULT_OPTS, | ||
caller: getCaller({ | ||
name: 'metro', | ||
engine: 'hermes', | ||
platform: 'android', | ||
isDev: false, | ||
}), | ||
}; | ||
|
||
const src = ` | ||
function foo() {} | ||
function bar() { foo() } | ||
`; | ||
expect((await minifyLikeMetroAsync(babel.transform(src, options)!)).code).toBe(''); | ||
}); | ||
|
||
it(`retains exported functions`, async () => { | ||
const options = { | ||
...DEFAULT_OPTS, | ||
caller: getCaller({ | ||
name: 'metro', | ||
engine: 'hermes', | ||
platform: 'android', | ||
isDev: false, | ||
// Disable CJS | ||
supportsStaticESM: true, | ||
}), | ||
}; | ||
|
||
const src = ` | ||
export function foo() {} | ||
`; | ||
expect((await minifyLikeMetroAsync(babel.transform(src, options)!)).code).toBe( | ||
'export function foo(){}' | ||
); | ||
}); | ||
|
||
it(`does not remove top level variables due to module=false in the minifier (not passed from transformer)`, async () => { | ||
const options = { | ||
...DEFAULT_OPTS, | ||
caller: getCaller({ | ||
name: 'metro', | ||
engine: 'hermes', | ||
platform: 'android', | ||
isDev: false, | ||
}), | ||
}; | ||
|
||
const src = ` | ||
const a = 0; | ||
`; | ||
expect((await minifyLikeMetroAsync(babel.transform(src, options)!)).code).toBe('var a=0;'); | ||
}); | ||
|
||
it(`can remove unused functions based on platform-specific checks`, async () => { | ||
const options = { | ||
...DEFAULT_OPTS, | ||
caller: getCaller({ | ||
name: 'metro', | ||
engine: 'hermes', | ||
platform: 'android', | ||
isDev: false, | ||
supportsStaticESM: true, | ||
}), | ||
}; | ||
|
||
// noop should be removed when bundling for android | ||
const src = ` | ||
function noop() {} | ||
function android() {} | ||
export const value = process.env.EXPO_OS === 'android' ? android : noop; | ||
`; | ||
expect((await minifyLikeMetroAsync(babel.transform(src, options)!)).code).toBe( | ||
'function android(){}export var value=android;' | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Rough estimation of how minifying works by default in Expo / Metro. | ||
// We'll need to update this if we ever change the default minifier. | ||
import getDefaultConfig from 'metro-config/src/defaults'; | ||
import metroMinify from 'metro-minify-terser'; | ||
|
||
export async function minifyLikeMetroAsync({ | ||
code, | ||
map, | ||
}: { | ||
code?: string | null; | ||
map?: any; | ||
}): Promise<{ code?: string; map?: any }> { | ||
if (code == null) throw new Error('code is required for minifying'); | ||
// @ts-expect-error: untyped function | ||
const terserConfig = (await getDefaultConfig('/')).transformer.minifierConfig; | ||
return metroMinify({ | ||
code, | ||
map, | ||
reserved: [], | ||
config: { | ||
...terserConfig, | ||
// TODO: Enable module support | ||
// compress: { module: true }, | ||
}, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters