babel-preset-expo 9.6.2 → 9.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/common.d.ts +5 -0
- package/build/common.js +54 -0
- package/build/expo-inline-manifest-plugin.d.ts +9 -0
- package/build/expo-inline-manifest-plugin.js +149 -0
- package/build/expo-router-plugin.d.ts +20 -0
- package/build/expo-router-plugin.js +178 -0
- package/build/index.d.ts +19 -0
- package/build/index.js +143 -0
- package/build/lazyImports.d.ts +2 -0
- package/build/lazyImports.js +5 -0
- package/lazy-imports-blacklist.js +1 -1
- package/package.json +12 -16
- package/index.js +0 -189
- package/plugins/disable-ambiguous-requires.js +0 -52
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function hasModule(name: string): boolean;
|
|
2
|
+
/** Determine which bundler is being used. */
|
|
3
|
+
export declare function getBundler(caller: any): any;
|
|
4
|
+
export declare function getPlatform(caller: any): any;
|
|
5
|
+
export declare function getPossibleProjectRoot(caller: any): any;
|
package/build/common.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPossibleProjectRoot = exports.getPlatform = exports.getBundler = exports.hasModule = void 0;
|
|
4
|
+
function hasModule(name) {
|
|
5
|
+
try {
|
|
6
|
+
return !!require.resolve(name);
|
|
7
|
+
}
|
|
8
|
+
catch (error) {
|
|
9
|
+
if (error.code === 'MODULE_NOT_FOUND' && error.message.includes(name)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.hasModule = hasModule;
|
|
16
|
+
/** Determine which bundler is being used. */
|
|
17
|
+
function getBundler(caller) {
|
|
18
|
+
if (!caller)
|
|
19
|
+
return null;
|
|
20
|
+
if (caller.bundler)
|
|
21
|
+
return caller.bundler;
|
|
22
|
+
if (
|
|
23
|
+
// Known tools that use `webpack`-mode via `babel-loader`: `@expo/webpack-config`, Next.js <10
|
|
24
|
+
caller.name === 'babel-loader' ||
|
|
25
|
+
// NextJS 11 uses this custom caller name.
|
|
26
|
+
caller.name === 'next-babel-turbo-loader') {
|
|
27
|
+
return 'webpack';
|
|
28
|
+
}
|
|
29
|
+
// Assume anything else is Metro.
|
|
30
|
+
return 'metro';
|
|
31
|
+
}
|
|
32
|
+
exports.getBundler = getBundler;
|
|
33
|
+
function getPlatform(caller) {
|
|
34
|
+
if (!caller)
|
|
35
|
+
return null;
|
|
36
|
+
if (caller.platform)
|
|
37
|
+
return caller.platform;
|
|
38
|
+
const bundler = getBundler(caller);
|
|
39
|
+
if (bundler === 'webpack') {
|
|
40
|
+
return 'web';
|
|
41
|
+
}
|
|
42
|
+
// unknown
|
|
43
|
+
return caller.platform;
|
|
44
|
+
}
|
|
45
|
+
exports.getPlatform = getPlatform;
|
|
46
|
+
function getPossibleProjectRoot(caller) {
|
|
47
|
+
if (!caller)
|
|
48
|
+
return null;
|
|
49
|
+
if (caller.projectRoot)
|
|
50
|
+
return caller.projectRoot;
|
|
51
|
+
// unknown
|
|
52
|
+
return process.env.EXPO_PROJECT_ROOT;
|
|
53
|
+
}
|
|
54
|
+
exports.getPossibleProjectRoot = getPossibleProjectRoot;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.expoInlineManifestPlugin = void 0;
|
|
4
|
+
const config_1 = require("expo/config");
|
|
5
|
+
const common_1 = require("./common");
|
|
6
|
+
const debug = require('debug')('expo:babel:inline-manifest');
|
|
7
|
+
// Convert expo value to PWA value
|
|
8
|
+
function ensurePWAorientation(orientation) {
|
|
9
|
+
if (orientation) {
|
|
10
|
+
const webOrientation = orientation.toLowerCase();
|
|
11
|
+
if (webOrientation !== 'default') {
|
|
12
|
+
return webOrientation;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const RESTRICTED_MANIFEST_FIELDS = [
|
|
18
|
+
'androidNavigationBar',
|
|
19
|
+
'androidStatusBar',
|
|
20
|
+
'privacy',
|
|
21
|
+
// Remove iOS and Android.
|
|
22
|
+
'ios',
|
|
23
|
+
'android',
|
|
24
|
+
// Hide internal / build values
|
|
25
|
+
'plugins',
|
|
26
|
+
'hooks',
|
|
27
|
+
'_internal',
|
|
28
|
+
// Remove metro-specific values
|
|
29
|
+
'assetBundlePatterns',
|
|
30
|
+
];
|
|
31
|
+
function getExpoConstantsManifest(projectRoot) {
|
|
32
|
+
const { exp } = getConfigMemo(projectRoot);
|
|
33
|
+
const manifest = applyWebDefaults(exp);
|
|
34
|
+
for (const field of RESTRICTED_MANIFEST_FIELDS) {
|
|
35
|
+
delete manifest[field];
|
|
36
|
+
}
|
|
37
|
+
return manifest;
|
|
38
|
+
}
|
|
39
|
+
function applyWebDefaults(appJSON) {
|
|
40
|
+
// For RN CLI support
|
|
41
|
+
const { web: webManifest = {}, splash = {}, ios = {}, android = {} } = appJSON;
|
|
42
|
+
// rn-cli apps use a displayName value as well.
|
|
43
|
+
const { appName, webName } = (0, config_1.getNameFromConfig)(appJSON);
|
|
44
|
+
const languageISOCode = webManifest.lang;
|
|
45
|
+
const primaryColor = appJSON.primaryColor;
|
|
46
|
+
const description = appJSON.description;
|
|
47
|
+
// The theme_color sets the color of the tool bar, and may be reflected in the app's preview in task switchers.
|
|
48
|
+
const webThemeColor = webManifest.themeColor || primaryColor;
|
|
49
|
+
const dir = webManifest.dir;
|
|
50
|
+
const shortName = webManifest.shortName || webName;
|
|
51
|
+
const display = webManifest.display;
|
|
52
|
+
const startUrl = webManifest.startUrl;
|
|
53
|
+
const { scope, crossorigin } = webManifest;
|
|
54
|
+
const barStyle = webManifest.barStyle;
|
|
55
|
+
const orientation = ensurePWAorientation(webManifest.orientation || appJSON.orientation);
|
|
56
|
+
/**
|
|
57
|
+
* **Splash screen background color**
|
|
58
|
+
* `https://developers.google.com/web/fundamentals/web-app-manifest/#splash-screen`
|
|
59
|
+
* The background_color should be the same color as the load page,
|
|
60
|
+
* to provide a smooth transition from the splash screen to your app.
|
|
61
|
+
*/
|
|
62
|
+
const backgroundColor = webManifest.backgroundColor || splash.backgroundColor; // No default background color
|
|
63
|
+
return {
|
|
64
|
+
...appJSON,
|
|
65
|
+
name: appName,
|
|
66
|
+
description,
|
|
67
|
+
primaryColor,
|
|
68
|
+
// Ensure these objects exist
|
|
69
|
+
ios: {
|
|
70
|
+
...ios,
|
|
71
|
+
},
|
|
72
|
+
android: {
|
|
73
|
+
...android,
|
|
74
|
+
},
|
|
75
|
+
web: {
|
|
76
|
+
...webManifest,
|
|
77
|
+
meta: undefined,
|
|
78
|
+
build: undefined,
|
|
79
|
+
scope,
|
|
80
|
+
crossorigin,
|
|
81
|
+
description,
|
|
82
|
+
startUrl,
|
|
83
|
+
shortName,
|
|
84
|
+
display,
|
|
85
|
+
orientation,
|
|
86
|
+
dir,
|
|
87
|
+
barStyle,
|
|
88
|
+
backgroundColor,
|
|
89
|
+
themeColor: webThemeColor,
|
|
90
|
+
lang: languageISOCode,
|
|
91
|
+
name: webName,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function getExpoAppManifest(projectRoot) {
|
|
96
|
+
if (process.env.APP_MANIFEST) {
|
|
97
|
+
return process.env.APP_MANIFEST;
|
|
98
|
+
}
|
|
99
|
+
const exp = getExpoConstantsManifest(projectRoot);
|
|
100
|
+
debug('public manifest', exp);
|
|
101
|
+
return JSON.stringify(exp);
|
|
102
|
+
}
|
|
103
|
+
let config;
|
|
104
|
+
function getConfigMemo(projectRoot) {
|
|
105
|
+
if (!config) {
|
|
106
|
+
config = (0, config_1.getConfig)(projectRoot, {
|
|
107
|
+
isPublicConfig: true,
|
|
108
|
+
skipSDKVersionRequirement: true,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return config;
|
|
112
|
+
}
|
|
113
|
+
// Convert `process.env.APP_MANIFEST` to a modified web-specific variation of the app.json public manifest.
|
|
114
|
+
function expoInlineManifestPlugin(api) {
|
|
115
|
+
const { types: t } = api;
|
|
116
|
+
const platform = api.caller(common_1.getPlatform);
|
|
117
|
+
const possibleProjectRoot = api.caller(common_1.getPossibleProjectRoot);
|
|
118
|
+
return {
|
|
119
|
+
name: 'expo-inline-manifest-plugin',
|
|
120
|
+
visitor: {
|
|
121
|
+
MemberExpression(path, state) {
|
|
122
|
+
// Web-only feature, the native manifest is provided dynamically by the client.
|
|
123
|
+
if (platform !== 'web') {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (!t.isIdentifier(path.node.object, { name: 'process' }) ||
|
|
127
|
+
!t.isIdentifier(path.node.property, { name: 'env' })) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const parent = path.parentPath;
|
|
131
|
+
if (!t.isMemberExpression(parent.node)) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const projectRoot = possibleProjectRoot || state.file.opts.root || '';
|
|
135
|
+
if (
|
|
136
|
+
// Surfaces the `app.json` (config) as an environment variable which is then parsed by
|
|
137
|
+
// `expo-constants` https://docs.expo.dev/versions/latest/sdk/constants/
|
|
138
|
+
t.isIdentifier(parent.node.property, {
|
|
139
|
+
name: 'APP_MANIFEST',
|
|
140
|
+
}) &&
|
|
141
|
+
!parent.parentPath.isAssignmentExpression()) {
|
|
142
|
+
const manifest = getExpoAppManifest(projectRoot);
|
|
143
|
+
parent.replaceWith(t.stringLiteral(manifest));
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
exports.expoInlineManifestPlugin = expoInlineManifestPlugin;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ConfigAPI, types } from '@babel/core';
|
|
2
|
+
/**
|
|
3
|
+
* Inlines environment variables to configure the process:
|
|
4
|
+
*
|
|
5
|
+
* EXPO_PROJECT_ROOT
|
|
6
|
+
* EXPO_PUBLIC_USE_STATIC
|
|
7
|
+
* EXPO_ROUTER_ABS_APP_ROOT
|
|
8
|
+
* EXPO_ROUTER_APP_ROOT
|
|
9
|
+
* EXPO_ROUTER_IMPORT_MODE_IOS
|
|
10
|
+
* EXPO_ROUTER_IMPORT_MODE_ANDROID
|
|
11
|
+
* EXPO_ROUTER_IMPORT_MODE_WEB
|
|
12
|
+
*/
|
|
13
|
+
export declare function expoRouterBabelPlugin(api: ConfigAPI & {
|
|
14
|
+
types: typeof types;
|
|
15
|
+
}): {
|
|
16
|
+
name: string;
|
|
17
|
+
visitor: {
|
|
18
|
+
MemberExpression(path: any, state: any): void;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.expoRouterBabelPlugin = void 0;
|
|
7
|
+
const config_1 = require("expo/config");
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const resolve_from_1 = __importDefault(require("resolve-from"));
|
|
11
|
+
const common_1 = require("./common");
|
|
12
|
+
const debug = require('debug')('expo:babel:router');
|
|
13
|
+
let config;
|
|
14
|
+
function getConfigMemo(projectRoot) {
|
|
15
|
+
if (!config || process.env._EXPO_INTERNAL_TESTING) {
|
|
16
|
+
config = (0, config_1.getConfig)(projectRoot);
|
|
17
|
+
}
|
|
18
|
+
return config;
|
|
19
|
+
}
|
|
20
|
+
function getExpoRouterImportMode(projectRoot, platform) {
|
|
21
|
+
const envVar = 'EXPO_ROUTER_IMPORT_MODE_' + platform.toUpperCase();
|
|
22
|
+
if (process.env[envVar]) {
|
|
23
|
+
return process.env[envVar];
|
|
24
|
+
}
|
|
25
|
+
const env = process.env.NODE_ENV || process.env.BABEL_ENV;
|
|
26
|
+
const { exp } = getConfigMemo(projectRoot);
|
|
27
|
+
let asyncRoutesSetting;
|
|
28
|
+
if (exp.extra?.router?.asyncRoutes) {
|
|
29
|
+
const asyncRoutes = exp.extra?.router?.asyncRoutes;
|
|
30
|
+
if (typeof asyncRoutes === 'string') {
|
|
31
|
+
asyncRoutesSetting = asyncRoutes;
|
|
32
|
+
}
|
|
33
|
+
else if (typeof asyncRoutes === 'object') {
|
|
34
|
+
asyncRoutesSetting = asyncRoutes[platform] ?? asyncRoutes.default;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
let mode = [env, true].includes(asyncRoutesSetting) ? 'lazy' : 'sync';
|
|
38
|
+
// TODO: Production bundle splitting
|
|
39
|
+
if (env === 'production' && mode === 'lazy') {
|
|
40
|
+
throw new Error('Async routes are not supported in production yet. Set the `expo-router` Config Plugin prop `asyncRoutes` to `development`, `false`, or `undefined`.');
|
|
41
|
+
}
|
|
42
|
+
// NOTE: This is a temporary workaround for static rendering on web.
|
|
43
|
+
if (platform === 'web' && (exp.web || {}).output === 'static') {
|
|
44
|
+
mode = 'sync';
|
|
45
|
+
}
|
|
46
|
+
// Development
|
|
47
|
+
debug('Router import mode', mode);
|
|
48
|
+
process.env[envVar] = mode;
|
|
49
|
+
return mode;
|
|
50
|
+
}
|
|
51
|
+
function directoryExistsSync(file) {
|
|
52
|
+
return fs_1.default.statSync(file, { throwIfNoEntry: false })?.isDirectory() ?? false;
|
|
53
|
+
}
|
|
54
|
+
function getRouterDirectory(projectRoot) {
|
|
55
|
+
// more specific directories first
|
|
56
|
+
if (directoryExistsSync(path_1.default.join(projectRoot, 'src/app'))) {
|
|
57
|
+
// Log.log(chalk.gray('Using src/app as the root directory for Expo Router.'));
|
|
58
|
+
return './src/app';
|
|
59
|
+
}
|
|
60
|
+
// Log.debug('Using app as the root directory for Expo Router.');
|
|
61
|
+
return './app';
|
|
62
|
+
}
|
|
63
|
+
function getExpoRouterAppRoot(projectRoot) {
|
|
64
|
+
// Bump to v2 to prevent the CLI from setting the variable anymore.
|
|
65
|
+
// TODO: Bump to v3 to revert back to the CLI setting the variable again, but with custom value
|
|
66
|
+
// support.
|
|
67
|
+
if (process.env.EXPO_ROUTER_APP_ROOT_2) {
|
|
68
|
+
return process.env.EXPO_ROUTER_APP_ROOT_2;
|
|
69
|
+
}
|
|
70
|
+
const routerEntry = (0, resolve_from_1.default)(projectRoot, 'expo-router/entry');
|
|
71
|
+
// It doesn't matter if the app folder exists.
|
|
72
|
+
const appFolder = getExpoRouterAbsoluteAppRoot(projectRoot);
|
|
73
|
+
const appRoot = path_1.default.relative(path_1.default.dirname(routerEntry), appFolder);
|
|
74
|
+
debug('routerEntry', routerEntry, appFolder, appRoot);
|
|
75
|
+
process.env.EXPO_ROUTER_APP_ROOT_2 = appRoot;
|
|
76
|
+
return appRoot;
|
|
77
|
+
}
|
|
78
|
+
function getExpoRouterAbsoluteAppRoot(projectRoot) {
|
|
79
|
+
if (process.env.EXPO_ROUTER_ABS_APP_ROOT) {
|
|
80
|
+
return process.env.EXPO_ROUTER_ABS_APP_ROOT;
|
|
81
|
+
}
|
|
82
|
+
const { exp } = getConfigMemo(projectRoot);
|
|
83
|
+
const customSrc = exp.extra?.router?.unstable_src || getRouterDirectory(projectRoot);
|
|
84
|
+
const isAbsolute = customSrc.startsWith('/');
|
|
85
|
+
// It doesn't matter if the app folder exists.
|
|
86
|
+
const appFolder = isAbsolute ? customSrc : path_1.default.join(projectRoot, customSrc);
|
|
87
|
+
const appRoot = appFolder;
|
|
88
|
+
debug('absolute router entry', appFolder, appRoot);
|
|
89
|
+
process.env.EXPO_ROUTER_ABS_APP_ROOT = appFolder;
|
|
90
|
+
return appRoot;
|
|
91
|
+
}
|
|
92
|
+
// TODO: Strip the function `generateStaticParams` when bundling for node.js environments.
|
|
93
|
+
/**
|
|
94
|
+
* Inlines environment variables to configure the process:
|
|
95
|
+
*
|
|
96
|
+
* EXPO_PROJECT_ROOT
|
|
97
|
+
* EXPO_PUBLIC_USE_STATIC
|
|
98
|
+
* EXPO_ROUTER_ABS_APP_ROOT
|
|
99
|
+
* EXPO_ROUTER_APP_ROOT
|
|
100
|
+
* EXPO_ROUTER_IMPORT_MODE_IOS
|
|
101
|
+
* EXPO_ROUTER_IMPORT_MODE_ANDROID
|
|
102
|
+
* EXPO_ROUTER_IMPORT_MODE_WEB
|
|
103
|
+
*/
|
|
104
|
+
function expoRouterBabelPlugin(api) {
|
|
105
|
+
const { types: t } = api;
|
|
106
|
+
const platform = api.caller(common_1.getPlatform);
|
|
107
|
+
const possibleProjectRoot = api.caller(common_1.getPossibleProjectRoot);
|
|
108
|
+
return {
|
|
109
|
+
name: 'expo-router',
|
|
110
|
+
visitor: {
|
|
111
|
+
// Convert `process.env.EXPO_ROUTER_APP_ROOT` to a string literal
|
|
112
|
+
MemberExpression(path, state) {
|
|
113
|
+
if (!t.isIdentifier(path.node.object, { name: 'process' }) ||
|
|
114
|
+
!t.isIdentifier(path.node.property, { name: 'env' })) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const parent = path.parentPath;
|
|
118
|
+
if (!t.isMemberExpression(parent.node)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const projectRoot = possibleProjectRoot || state.file.opts.root || '';
|
|
122
|
+
// Used for log box and stuff
|
|
123
|
+
if (t.isIdentifier(parent.node.property, {
|
|
124
|
+
name: 'EXPO_PROJECT_ROOT',
|
|
125
|
+
}) &&
|
|
126
|
+
!parent.parentPath.isAssignmentExpression()) {
|
|
127
|
+
parent.replaceWith(t.stringLiteral(projectRoot));
|
|
128
|
+
}
|
|
129
|
+
else if (
|
|
130
|
+
// Enable static rendering
|
|
131
|
+
// TODO: Use a serializer or something to ensure this changes without
|
|
132
|
+
// needing to clear the cache.
|
|
133
|
+
t.isIdentifier(parent.node.property, {
|
|
134
|
+
name: 'EXPO_PUBLIC_USE_STATIC',
|
|
135
|
+
}) &&
|
|
136
|
+
!parent.parentPath.isAssignmentExpression()) {
|
|
137
|
+
if (platform === 'web') {
|
|
138
|
+
const isStatic = process.env.EXPO_PUBLIC_USE_STATIC === 'true' ||
|
|
139
|
+
process.env.EXPO_PUBLIC_USE_STATIC === '1';
|
|
140
|
+
parent.replaceWith(t.booleanLiteral(isStatic));
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
parent.replaceWith(t.booleanLiteral(false));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (process.env.NODE_ENV !== 'test' &&
|
|
147
|
+
t.isIdentifier(parent.node.property, {
|
|
148
|
+
name: 'EXPO_ROUTER_ABS_APP_ROOT',
|
|
149
|
+
}) &&
|
|
150
|
+
!parent.parentPath.isAssignmentExpression()) {
|
|
151
|
+
parent.replaceWith(t.stringLiteral(getExpoRouterAbsoluteAppRoot(projectRoot)));
|
|
152
|
+
}
|
|
153
|
+
else if (
|
|
154
|
+
// Skip loading the app root in tests.
|
|
155
|
+
// This is handled by the testing-library utils
|
|
156
|
+
process.env.NODE_ENV !== 'test' &&
|
|
157
|
+
t.isIdentifier(parent.node.property, {
|
|
158
|
+
name: 'EXPO_ROUTER_APP_ROOT',
|
|
159
|
+
}) &&
|
|
160
|
+
!parent.parentPath.isAssignmentExpression()) {
|
|
161
|
+
parent.replaceWith(
|
|
162
|
+
// This is defined in Expo CLI when using Metro. It points to the relative path for the project app directory.
|
|
163
|
+
t.stringLiteral(getExpoRouterAppRoot(projectRoot)));
|
|
164
|
+
}
|
|
165
|
+
else if (
|
|
166
|
+
// Expose the app route import mode.
|
|
167
|
+
platform &&
|
|
168
|
+
t.isIdentifier(parent.node.property, {
|
|
169
|
+
name: 'EXPO_ROUTER_IMPORT_MODE_' + platform.toUpperCase(),
|
|
170
|
+
}) &&
|
|
171
|
+
!parent.parentPath.isAssignmentExpression()) {
|
|
172
|
+
parent.replaceWith(t.stringLiteral(getExpoRouterImportMode(projectRoot, platform)));
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
exports.expoRouterBabelPlugin = expoRouterBabelPlugin;
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ConfigAPI, TransformOptions } from '@babel/core';
|
|
2
|
+
type BabelPresetExpoPlatformOptions = {
|
|
3
|
+
useTransformReactJSXExperimental?: boolean;
|
|
4
|
+
disableImportExportTransform?: boolean;
|
|
5
|
+
withDevTools?: boolean;
|
|
6
|
+
disableFlowStripTypesTransform?: boolean;
|
|
7
|
+
enableBabelRuntime?: boolean;
|
|
8
|
+
unstable_transformProfile?: 'default' | 'hermes-stable' | 'hermes-canary';
|
|
9
|
+
};
|
|
10
|
+
export type BabelPresetExpoOptions = {
|
|
11
|
+
lazyImports?: boolean;
|
|
12
|
+
reanimated?: boolean;
|
|
13
|
+
jsxRuntime?: 'classic' | 'automatic';
|
|
14
|
+
jsxImportSource?: string;
|
|
15
|
+
web?: BabelPresetExpoPlatformOptions;
|
|
16
|
+
native?: BabelPresetExpoPlatformOptions;
|
|
17
|
+
};
|
|
18
|
+
declare function babelPresetExpo(api: ConfigAPI, options?: BabelPresetExpoOptions): TransformOptions;
|
|
19
|
+
export default babelPresetExpo;
|
package/build/index.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const common_1 = require("./common");
|
|
4
|
+
const expo_inline_manifest_plugin_1 = require("./expo-inline-manifest-plugin");
|
|
5
|
+
const expo_router_plugin_1 = require("./expo-router-plugin");
|
|
6
|
+
const lazyImports_1 = require("./lazyImports");
|
|
7
|
+
function babelPresetExpo(api, options = {}) {
|
|
8
|
+
const { web = {}, native = {}, reanimated } = options;
|
|
9
|
+
const bundler = api.caller(common_1.getBundler);
|
|
10
|
+
const isWebpack = bundler === 'webpack';
|
|
11
|
+
let platform = api.caller((caller) => caller?.platform);
|
|
12
|
+
const engine = api.caller((caller) => caller?.engine) ?? 'default';
|
|
13
|
+
// If the `platform` prop is not defined then this must be a custom config that isn't
|
|
14
|
+
// defining a platform in the babel-loader. Currently this may happen with Next.js + Expo web.
|
|
15
|
+
if (!platform && isWebpack) {
|
|
16
|
+
platform = 'web';
|
|
17
|
+
}
|
|
18
|
+
const platformOptions = platform === 'web'
|
|
19
|
+
? {
|
|
20
|
+
// Only disable import/export transform when Webpack is used because
|
|
21
|
+
// Metro does not support tree-shaking.
|
|
22
|
+
disableImportExportTransform: isWebpack,
|
|
23
|
+
unstable_transformProfile: engine === 'hermes' ? 'hermes-stable' : 'default',
|
|
24
|
+
...web,
|
|
25
|
+
}
|
|
26
|
+
: {
|
|
27
|
+
disableImportExportTransform: false,
|
|
28
|
+
unstable_transformProfile: engine === 'hermes' ? 'hermes-stable' : 'default',
|
|
29
|
+
...native,
|
|
30
|
+
};
|
|
31
|
+
// Note that if `options.lazyImports` is not set (i.e., `null` or `undefined`),
|
|
32
|
+
// `metro-react-native-babel-preset` will handle it.
|
|
33
|
+
const lazyImportsOption = options?.lazyImports;
|
|
34
|
+
const extraPlugins = [];
|
|
35
|
+
if (engine !== 'hermes') {
|
|
36
|
+
// `metro-react-native-babel-preset` configures this plugin with `{ loose: true }`, which breaks all
|
|
37
|
+
// getters and setters in spread objects. We need to add this plugin ourself without that option.
|
|
38
|
+
// @see https://github.com/expo/expo/pull/11960#issuecomment-887796455
|
|
39
|
+
extraPlugins.push([
|
|
40
|
+
require.resolve('@babel/plugin-proposal-object-rest-spread'),
|
|
41
|
+
{ loose: false },
|
|
42
|
+
]);
|
|
43
|
+
}
|
|
44
|
+
// Set true to disable `@babel/plugin-transform-react-jsx`
|
|
45
|
+
// we override this logic outside of the metro preset so we can add support for
|
|
46
|
+
// React 17 automatic JSX transformations.
|
|
47
|
+
// If the logic for `useTransformReactJSXExperimental` ever changes in `metro-react-native-babel-preset`
|
|
48
|
+
// then this block should be updated to reflect those changes.
|
|
49
|
+
if (!platformOptions.useTransformReactJSXExperimental) {
|
|
50
|
+
extraPlugins.push([
|
|
51
|
+
require('@babel/plugin-transform-react-jsx'),
|
|
52
|
+
{
|
|
53
|
+
// Defaults to `automatic`, pass in `classic` to disable auto JSX transformations.
|
|
54
|
+
runtime: (options && options.jsxRuntime) || 'automatic',
|
|
55
|
+
...(options &&
|
|
56
|
+
options.jsxRuntime !== 'classic' && {
|
|
57
|
+
importSource: (options && options.jsxImportSource) || 'react',
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
]);
|
|
61
|
+
// Purposefully not adding the deprecated packages:
|
|
62
|
+
// `@babel/plugin-transform-react-jsx-self` and `@babel/plugin-transform-react-jsx-source`
|
|
63
|
+
// back to the preset.
|
|
64
|
+
}
|
|
65
|
+
const aliasPlugin = getAliasPlugin();
|
|
66
|
+
if (aliasPlugin) {
|
|
67
|
+
extraPlugins.push(aliasPlugin);
|
|
68
|
+
}
|
|
69
|
+
if (platform === 'web') {
|
|
70
|
+
extraPlugins.push(require.resolve('babel-plugin-react-native-web'));
|
|
71
|
+
// Webpack uses the DefinePlugin to provide the manifest to `expo-constants`.
|
|
72
|
+
if (bundler !== 'webpack') {
|
|
73
|
+
extraPlugins.push(expo_inline_manifest_plugin_1.expoInlineManifestPlugin);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if ((0, common_1.hasModule)('expo-router')) {
|
|
77
|
+
extraPlugins.push(expo_router_plugin_1.expoRouterBabelPlugin);
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
presets: [
|
|
81
|
+
[
|
|
82
|
+
// We use `require` here instead of directly using the package name because we want to
|
|
83
|
+
// specifically use the `metro-react-native-babel-preset` installed by this package (ex:
|
|
84
|
+
// `babel-preset-expo/node_modules/`). This way the preset will not change unintentionally.
|
|
85
|
+
// Reference: https://github.com/expo/expo/pull/4685#discussion_r307143920
|
|
86
|
+
require('metro-react-native-babel-preset'),
|
|
87
|
+
{
|
|
88
|
+
// Defaults to undefined, set to something truthy to disable `@babel/plugin-transform-react-jsx-self` and `@babel/plugin-transform-react-jsx-source`.
|
|
89
|
+
withDevTools: platformOptions.withDevTools,
|
|
90
|
+
// Defaults to undefined, set to `true` to disable `@babel/plugin-transform-flow-strip-types`
|
|
91
|
+
disableFlowStripTypesTransform: platformOptions.disableFlowStripTypesTransform,
|
|
92
|
+
// Defaults to undefined, set to `false` to disable `@babel/plugin-transform-runtime`
|
|
93
|
+
enableBabelRuntime: platformOptions.enableBabelRuntime,
|
|
94
|
+
// This reduces the amount of transforms required, as Hermes supports many modern language features.
|
|
95
|
+
unstable_transformProfile: platformOptions.unstable_transformProfile,
|
|
96
|
+
// Set true to disable `@babel/plugin-transform-react-jsx` and
|
|
97
|
+
// the deprecated packages `@babel/plugin-transform-react-jsx-self`, and `@babel/plugin-transform-react-jsx-source`.
|
|
98
|
+
//
|
|
99
|
+
// Otherwise, you'll sometime get errors like the following (starting in Expo SDK 43, React Native 64, React 17):
|
|
100
|
+
//
|
|
101
|
+
// TransformError App.js: /path/to/App.js: Duplicate __self prop found. You are most likely using the deprecated transform-react-jsx-self Babel plugin.
|
|
102
|
+
// Both __source and __self are automatically set when using the automatic jsxRuntime. Please remove transform-react-jsx-source and transform-react-jsx-self from your Babel config.
|
|
103
|
+
useTransformReactJSXExperimental: true,
|
|
104
|
+
disableImportExportTransform: platformOptions.disableImportExportTransform,
|
|
105
|
+
lazyImportExportTransform: lazyImportsOption === true
|
|
106
|
+
? (importModuleSpecifier) => {
|
|
107
|
+
// Do not lazy-initialize packages that are local imports (similar to `lazy: true`
|
|
108
|
+
// behavior) or are in the blacklist.
|
|
109
|
+
return !(importModuleSpecifier.includes('./') || lazyImports_1.lazyImports.has(importModuleSpecifier));
|
|
110
|
+
}
|
|
111
|
+
: // Pass the option directly to `metro-react-native-babel-preset`, which in turn
|
|
112
|
+
// passes it to `babel-plugin-transform-modules-commonjs`
|
|
113
|
+
lazyImportsOption,
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
],
|
|
117
|
+
plugins: [
|
|
118
|
+
...extraPlugins,
|
|
119
|
+
// TODO: Remove
|
|
120
|
+
[require.resolve('@babel/plugin-proposal-decorators'), { legacy: true }],
|
|
121
|
+
require.resolve('@babel/plugin-proposal-export-namespace-from'),
|
|
122
|
+
// Automatically add `react-native-reanimated/plugin` when the package is installed.
|
|
123
|
+
// TODO: Move to be a customTransformOption.
|
|
124
|
+
(0, common_1.hasModule)('react-native-reanimated') &&
|
|
125
|
+
reanimated !== false && [require.resolve('react-native-reanimated/plugin')],
|
|
126
|
+
].filter(Boolean),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function getAliasPlugin() {
|
|
130
|
+
if (!(0, common_1.hasModule)('@expo/vector-icons')) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
return [
|
|
134
|
+
require.resolve('babel-plugin-module-resolver'),
|
|
135
|
+
{
|
|
136
|
+
alias: {
|
|
137
|
+
'react-native-vector-icons': '@expo/vector-icons',
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
exports.default = babelPresetExpo;
|
|
143
|
+
module.exports = babelPresetExpo;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.lazyImports = void 0;
|
|
4
|
+
/** These Expo packages may have side-effects and should not be lazily initialized. */
|
|
5
|
+
exports.lazyImports = new Set(['expo', 'expo-asset', 'expo-task-manager']);
|
package/package.json
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "babel-preset-expo",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.8.0",
|
|
4
4
|
"description": "The Babel preset for Expo projects",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "build/index.js",
|
|
6
6
|
"files": [
|
|
7
|
-
"
|
|
8
|
-
"lazy-imports-blacklist.js"
|
|
9
|
-
"plugins"
|
|
7
|
+
"build",
|
|
8
|
+
"lazy-imports-blacklist.js"
|
|
10
9
|
],
|
|
11
10
|
"scripts": {
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
11
|
+
"build": "expo-module build",
|
|
12
|
+
"clean": "expo-module clean",
|
|
13
|
+
"lint": "expo-module lint",
|
|
14
|
+
"test": "expo-module test",
|
|
15
|
+
"prepare": "expo-module prepare",
|
|
16
|
+
"prepublishOnly": "expo-module prepublishOnly",
|
|
17
|
+
"expo-module": "expo-module"
|
|
15
18
|
},
|
|
16
19
|
"repository": {
|
|
17
20
|
"type": "git",
|
|
@@ -37,13 +40,6 @@
|
|
|
37
40
|
"eslintConfig": {
|
|
38
41
|
"extends": "universe/node"
|
|
39
42
|
},
|
|
40
|
-
"jest": {
|
|
41
|
-
"testEnvironment": "node",
|
|
42
|
-
"testPathIgnorePatterns": [
|
|
43
|
-
"<rootDir>/node_modules/",
|
|
44
|
-
"<rootDir>/__tests__/samples/"
|
|
45
|
-
]
|
|
46
|
-
},
|
|
47
43
|
"dependencies": {
|
|
48
44
|
"@babel/plugin-proposal-decorators": "^7.12.9",
|
|
49
45
|
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
|
|
@@ -58,5 +54,5 @@
|
|
|
58
54
|
"@babel/core": "^7.20.0",
|
|
59
55
|
"jest": "^29.2.1"
|
|
60
56
|
},
|
|
61
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "ee7897097f5f946ad7fcb94447eed789b984dd02"
|
|
62
58
|
}
|
package/index.js
DELETED
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
const lazyImportsBlacklist = require('./lazy-imports-blacklist');
|
|
2
|
-
|
|
3
|
-
let hasWarnedJsxRename = false;
|
|
4
|
-
|
|
5
|
-
module.exports = function (api, options = {}) {
|
|
6
|
-
const { web = {}, native = {}, reanimated } = options;
|
|
7
|
-
|
|
8
|
-
const bundler = api.caller(getBundler);
|
|
9
|
-
const isWebpack = bundler === 'webpack';
|
|
10
|
-
let platform = api.caller(getPlatform);
|
|
11
|
-
|
|
12
|
-
// If the `platform` prop is not defined then this must be a custom config that isn't
|
|
13
|
-
// defining a platform in the babel-loader. Currently this may happen with Next.js + Expo web.
|
|
14
|
-
if (!platform && isWebpack) {
|
|
15
|
-
platform = 'web';
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const platformOptions =
|
|
19
|
-
platform === 'web'
|
|
20
|
-
? {
|
|
21
|
-
// Only disable import/export transform when Webpack is used because
|
|
22
|
-
// Metro does not support tree-shaking.
|
|
23
|
-
disableImportExportTransform: !!isWebpack,
|
|
24
|
-
...web,
|
|
25
|
-
}
|
|
26
|
-
: { disableImportExportTransform: false, ...native };
|
|
27
|
-
|
|
28
|
-
// Note that if `options.lazyImports` is not set (i.e., `null` or `undefined`),
|
|
29
|
-
// `metro-react-native-babel-preset` will handle it.
|
|
30
|
-
const lazyImportsOption = options && options.lazyImports;
|
|
31
|
-
|
|
32
|
-
const extraPlugins = [];
|
|
33
|
-
|
|
34
|
-
if ('useTransformReactJsxExperimental' in platformOptions && !hasWarnedJsxRename) {
|
|
35
|
-
// https://github.com/expo/expo/pull/13945#pullrequestreview-724327024
|
|
36
|
-
hasWarnedJsxRename = true;
|
|
37
|
-
console.warn(
|
|
38
|
-
'Warning: useTransformReactJsxExperimental has been renamed to useTransformReactJSXExperimental (capitalized JSX) in react-native@0.64.0'
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Set true to disable `@babel/plugin-transform-react-jsx`
|
|
43
|
-
// we override this logic outside of the metro preset so we can add support for
|
|
44
|
-
// React 17 automatic JSX transformations.
|
|
45
|
-
// If the logic for `useTransformReactJSXExperimental` ever changes in `metro-react-native-babel-preset`
|
|
46
|
-
// then this block should be updated to reflect those changes.
|
|
47
|
-
if (!platformOptions.useTransformReactJSXExperimental) {
|
|
48
|
-
extraPlugins.push([
|
|
49
|
-
require('@babel/plugin-transform-react-jsx'),
|
|
50
|
-
{
|
|
51
|
-
// Defaults to `automatic`, pass in `classic` to disable auto JSX transformations.
|
|
52
|
-
runtime: (options && options.jsxRuntime) || 'automatic',
|
|
53
|
-
...(options &&
|
|
54
|
-
options.jsxRuntime !== 'classic' && {
|
|
55
|
-
importSource: (options && options.jsxImportSource) || 'react',
|
|
56
|
-
}),
|
|
57
|
-
},
|
|
58
|
-
]);
|
|
59
|
-
// Purposefully not adding the deprecated packages:
|
|
60
|
-
// `@babel/plugin-transform-react-jsx-self` and `@babel/plugin-transform-react-jsx-source`
|
|
61
|
-
// back to the preset.
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
presets: [
|
|
66
|
-
[
|
|
67
|
-
// We use `require` here instead of directly using the package name because we want to
|
|
68
|
-
// specifically use the `metro-react-native-babel-preset` installed by this package (ex:
|
|
69
|
-
// `babel-preset-expo/node_modules/`). This way the preset will not change unintentionally.
|
|
70
|
-
// Reference: https://github.com/expo/expo/pull/4685#discussion_r307143920
|
|
71
|
-
require('metro-react-native-babel-preset'),
|
|
72
|
-
{
|
|
73
|
-
// Defaults to undefined, set to something truthy to disable `@babel/plugin-transform-react-jsx-self` and `@babel/plugin-transform-react-jsx-source`.
|
|
74
|
-
withDevTools: platformOptions.withDevTools,
|
|
75
|
-
// Defaults to undefined, set to `true` to disable `@babel/plugin-transform-flow-strip-types`
|
|
76
|
-
disableFlowStripTypesTransform: platformOptions.disableFlowStripTypesTransform,
|
|
77
|
-
// Defaults to undefined, set to `false` to disable `@babel/plugin-transform-runtime`
|
|
78
|
-
enableBabelRuntime: platformOptions.enableBabelRuntime,
|
|
79
|
-
// Defaults to `'default'`, can also use `'hermes-canary'`
|
|
80
|
-
unstable_transformProfile: platformOptions.unstable_transformProfile,
|
|
81
|
-
// Set true to disable `@babel/plugin-transform-react-jsx` and
|
|
82
|
-
// the deprecated packages `@babel/plugin-transform-react-jsx-self`, and `@babel/plugin-transform-react-jsx-source`.
|
|
83
|
-
//
|
|
84
|
-
// Otherwise, you'll sometime get errors like the following (starting in Expo SDK 43, React Native 64, React 17):
|
|
85
|
-
//
|
|
86
|
-
// TransformError App.js: /path/to/App.js: Duplicate __self prop found. You are most likely using the deprecated transform-react-jsx-self Babel plugin.
|
|
87
|
-
// Both __source and __self are automatically set when using the automatic jsxRuntime. Please remove transform-react-jsx-source and transform-react-jsx-self from your Babel config.
|
|
88
|
-
useTransformReactJSXExperimental: true,
|
|
89
|
-
|
|
90
|
-
disableImportExportTransform: platformOptions.disableImportExportTransform,
|
|
91
|
-
lazyImportExportTransform:
|
|
92
|
-
lazyImportsOption === true
|
|
93
|
-
? (importModuleSpecifier) => {
|
|
94
|
-
// Do not lazy-initialize packages that are local imports (similar to `lazy: true`
|
|
95
|
-
// behavior) or are in the blacklist.
|
|
96
|
-
return !(
|
|
97
|
-
importModuleSpecifier.includes('./') ||
|
|
98
|
-
lazyImportsBlacklist.has(importModuleSpecifier)
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
: // Pass the option directly to `metro-react-native-babel-preset`, which in turn
|
|
102
|
-
// passes it to `babel-plugin-transform-modules-commonjs`
|
|
103
|
-
lazyImportsOption,
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
],
|
|
107
|
-
plugins: [
|
|
108
|
-
getObjectRestSpreadPlugin(),
|
|
109
|
-
...extraPlugins,
|
|
110
|
-
getAliasPlugin(),
|
|
111
|
-
[require.resolve('@babel/plugin-proposal-decorators'), { legacy: true }],
|
|
112
|
-
platform === 'web' && [require.resolve('babel-plugin-react-native-web')],
|
|
113
|
-
isWebpack && platform !== 'web' && [require.resolve('./plugins/disable-ambiguous-requires')],
|
|
114
|
-
require.resolve('@babel/plugin-proposal-export-namespace-from'),
|
|
115
|
-
|
|
116
|
-
// Automatically add `react-native-reanimated/plugin` when the package is installed.
|
|
117
|
-
hasModule('react-native-reanimated') &&
|
|
118
|
-
reanimated !== false && [require.resolve('react-native-reanimated/plugin')],
|
|
119
|
-
].filter(Boolean),
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
function getAliasPlugin() {
|
|
124
|
-
const aliases = {};
|
|
125
|
-
|
|
126
|
-
if (hasModule('@expo/vector-icons')) {
|
|
127
|
-
aliases['react-native-vector-icons'] = '@expo/vector-icons';
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (Object.keys(aliases).length) {
|
|
131
|
-
return [
|
|
132
|
-
require.resolve('babel-plugin-module-resolver'),
|
|
133
|
-
{
|
|
134
|
-
alias: aliases,
|
|
135
|
-
},
|
|
136
|
-
];
|
|
137
|
-
}
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* metro-react-native-babel-preset configures this plugin with `{ loose: true }`, which breaks all
|
|
143
|
-
* getters and setters in spread objects. We need to add this plugin ourself without that option.
|
|
144
|
-
* @see https://github.com/expo/expo/pull/11960#issuecomment-887796455
|
|
145
|
-
*/
|
|
146
|
-
function getObjectRestSpreadPlugin() {
|
|
147
|
-
return [require.resolve('@babel/plugin-proposal-object-rest-spread'), { loose: false }];
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function hasModule(name) {
|
|
151
|
-
try {
|
|
152
|
-
return !!require.resolve(name);
|
|
153
|
-
} catch (error) {
|
|
154
|
-
if (error.code === 'MODULE_NOT_FOUND' && error.message.includes(name)) {
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
throw error;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function getPlatform(caller) {
|
|
162
|
-
return caller && caller.platform;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Get the name of the `bundler`.
|
|
167
|
-
*
|
|
168
|
-
* @param {*} caller
|
|
169
|
-
*/
|
|
170
|
-
function getBundler(caller) {
|
|
171
|
-
if (!caller) return null;
|
|
172
|
-
|
|
173
|
-
const { bundler, name } = caller;
|
|
174
|
-
|
|
175
|
-
if (!bundler) {
|
|
176
|
-
if (name === 'metro') {
|
|
177
|
-
// This is a hack to determine if metro is being used.
|
|
178
|
-
return 'metro';
|
|
179
|
-
} else if (name === 'next-babel-turbo-loader') {
|
|
180
|
-
// NextJS 11
|
|
181
|
-
return 'webpack';
|
|
182
|
-
} else if (name === 'babel-loader') {
|
|
183
|
-
// expo/webpack-config, gatsby, storybook, and next.js <10
|
|
184
|
-
return 'webpack';
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
// Perhaps we should add a check to log once when an unexpected bundler is being used.
|
|
188
|
-
return bundler || null;
|
|
189
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Disable ambiguous module ID requires from React Native:
|
|
3
|
-
* https://github.com/facebook/react-native/commit/06b5bda34923b68ba5141e78c36ccbdc5f4bcff1
|
|
4
|
-
*
|
|
5
|
-
* Without this operation, the following error will be thrown when bundling with Webpack:
|
|
6
|
-
* `Critical dependency: require function is used in a way in which dependencies cannot be statically extracted`
|
|
7
|
-
*
|
|
8
|
-
* - react-native/Libraries/Performance/Systrace.js 124:2-9
|
|
9
|
-
* - react-native/Libraries/Core/setUpReactRefresh.js 30:2-9
|
|
10
|
-
*/
|
|
11
|
-
module.exports = () => ({
|
|
12
|
-
visitor: {
|
|
13
|
-
AssignmentExpression(path) {
|
|
14
|
-
if (isValidRequire(path) && (isCastedRequire(path) || isChainedRequire(path))) {
|
|
15
|
-
path.remove();
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Is a require statement being assigned to something.
|
|
23
|
-
* Prevents further checks when `path.node.left` is undefined.
|
|
24
|
-
*
|
|
25
|
-
* @param {*} path
|
|
26
|
-
*/
|
|
27
|
-
function isValidRequire(path) {
|
|
28
|
-
return path.node.operator === '=' && path.node.left.type === 'MemberExpression';
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Is a require statement formatted like: `(require: any)`
|
|
33
|
-
*
|
|
34
|
-
* Example from `react-native/Libraries/Core/setUpReactRefresh.js 30:2-9`:
|
|
35
|
-
* `(require: any).Refresh = Refresh;`
|
|
36
|
-
*
|
|
37
|
-
* @param {*} path
|
|
38
|
-
*/
|
|
39
|
-
function isCastedRequire(path) {
|
|
40
|
-
const { object } = path.node.left;
|
|
41
|
-
return object.type === 'TypeCastExpression' && object.expression.name === 'require';
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Is a require statement formatted like: `require.`
|
|
46
|
-
*
|
|
47
|
-
* @param {*} path
|
|
48
|
-
*/
|
|
49
|
-
function isChainedRequire(path) {
|
|
50
|
-
const { object } = path.node.left;
|
|
51
|
-
return object.type === 'Identifier' && object.name === 'require';
|
|
52
|
-
}
|