babel-preset-expo 9.9.0 → 10.0.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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # babel-preset-expo
2
2
 
3
- This preset extends the default React Native preset (`metro-react-native-babel-preset`) and adds support for decorators, tree-shaking web packages, and loading font icons with optional native dependencies if they're installed.
3
+ This preset extends the default React Native preset (`@react-native/babel-preset`) and adds support for decorators, tree-shaking web packages, and loading font icons with optional native dependencies if they're installed.
4
4
 
5
- You can use this preset in any React Native project as a drop-in replacement for `metro-react-native-babel-preset`. If your project isn't using native font loading or web support then this preset will only add support for decorators with `@babel/plugin-proposal-decorators` - this is mostly used for supporting legacy community libraries.
5
+ You can use this preset in any React Native project as a drop-in replacement for `@react-native/babel-preset`. If your project isn't using native font loading or web support then this preset will only add support for decorators with `@babel/plugin-proposal-decorators` - this is mostly used for supporting legacy community libraries.
6
6
 
7
7
  If you start your **web** project with `@expo/webpack-config` or `npx expo start` and your project doesn't contain a `babel.config.js` or a `.babelrc` then it will default to using `babel-preset-expo` for loading.
8
8
 
@@ -92,14 +92,10 @@ This can improve the initial load time of your app because evaluating dependenci
92
92
 
93
93
  The value of `lazyImports` has a few possible effects:
94
94
 
95
- - `null` - [metro-react-native-babel-preset](https://github.com/facebook/metro/tree/master/packages/metro-react-native-babel-preset) will handle it. (Learn more about it here: https://github.com/facebook/metro/commit/23e3503dde5f914f3e642ef214f508d0a699851d)
96
-
95
+ - `null` - [@react-native/babel-preset](https://github.com/facebook/react-native/tree/main/packages/react-native-babel-preset) will handle it. (Learn more about it here: https://github.com/facebook/metro/commit/23e3503dde5f914f3e642ef214f508d0a699851d)
97
96
  - `false` - No lazy initialization of any imported module.
98
-
99
97
  - `true` - Lazy-init all imported modules except local imports (e.g., `./foo`), certain Expo packages that have side effects, and the two cases mentioned [here](https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs#lazy).
100
-
101
98
  - `Array<string>` - [babel-plugin-transform-modules-commonjs](https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs#lazy) will handle it.
102
-
103
99
  - `(string) => boolean` - [babel-plugin-transform-modules-commonjs](https://babeljs.io/docs/en/babel-plugin-transform-modules-commonjs#lazy) will handle it.
104
100
 
105
101
  If you choose to do this, you can also access the list of Expo packages that have side effects by using `const lazyImportsBlacklist = require('babel-preset-expo/lazy-imports-blacklist');` which returns a `Set`.
@@ -117,11 +113,20 @@ The value of `lazyImports` has a few possible effects:
117
113
 
118
114
  ### `disableImportExportTransform`
119
115
 
120
- Enabling this option will allow your project to run with older JavaScript syntax (i.e. `module.exports`). This option will break tree shaking and increase your bundle size, but will eliminate the following error when `module.exports` is used:
116
+ Pass `true` to disable the transform that converts import/export to `module.exports`. Avoid setting this property directly. If you're using Metro, set `experimentalImportSupport: true` instead to ensure the entire pipeline is configured correctly.
121
117
 
122
- > `TypeError: Cannot assign to read only property 'exports' of object '#<Object>'`
118
+ ```js
119
+ // metro.config.js
120
+
121
+ config.transformer.getTransformOptions = async () => ({
122
+ transform: {
123
+ // Setting this to `true` will automatically toggle `disableImportExportTransform` in `babel-preset-expo`.
124
+ experimentalImportSupport: true,
125
+ },
126
+ });
127
+ ```
123
128
 
124
- **default:** `false` when using Webpack. `true` otherwise.
129
+ If `undefined` (default), this will be set automatically via `caller.supportsStaticESM` which is set by the bundler.
125
130
 
126
131
  ```js
127
132
  [
@@ -134,15 +139,15 @@ Enabling this option will allow your project to run with older JavaScript syntax
134
139
 
135
140
  ### `unstable_transformProfile`
136
141
 
137
- Changes the engine preset in `metro-react-native-babel-preset` based on the JavaScript engine that is being targeted. In Expo SDK 50 and greater, this is automatically set based on the [`jsEngine`](https://docs.expo.dev/versions/latest/config/app/#jsengine) option in your `app.json`.
142
+ Changes the engine preset in `@react-native/babel-preset` based on the JavaScript engine that is being targeted. In Expo SDK 50 and greater, this is automatically set based on the [`jsEngine`](https://docs.expo.dev/versions/latest/config/app/#jsengine) option in your `app.json`.
138
143
 
139
144
  ### `enableBabelRuntime`
140
145
 
141
- Passed to `metro-react-native-babel-preset`.
146
+ Passed to `@react-native/babel-preset`.
142
147
 
143
148
  ### `disableFlowStripTypesTransform`
144
149
 
145
- Passed to `metro-react-native-babel-preset`.
150
+ Passed to `@react-native/babel-preset`.
146
151
 
147
152
  ## Platform-specific options
148
153
 
package/build/common.d.ts CHANGED
@@ -4,7 +4,11 @@ export declare function getBundler(caller: any): any;
4
4
  export declare function getPlatform(caller: any): any;
5
5
  export declare function getPossibleProjectRoot(caller: any): any;
6
6
  export declare function getIsDev(caller: any): any;
7
+ export declare function getIsFastRefreshEnabled(caller: any): any;
7
8
  export declare function getIsProd(caller: any): boolean;
9
+ export declare function getIsNodeModule(caller: any): boolean;
8
10
  export declare function getBaseUrl(caller: any): string;
9
11
  export declare function getIsServer(caller: any): any;
12
+ export declare function getExpoRouterAbsoluteAppRoot(caller: any): string;
10
13
  export declare function getInlineEnvVarsEnabled(caller: any): boolean;
14
+ export declare function getAsyncRoutes(caller: any): boolean;
package/build/common.js CHANGED
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getInlineEnvVarsEnabled = exports.getIsServer = exports.getBaseUrl = exports.getIsProd = exports.getIsDev = exports.getPossibleProjectRoot = exports.getPlatform = exports.getBundler = exports.hasModule = void 0;
6
+ exports.getAsyncRoutes = exports.getInlineEnvVarsEnabled = exports.getExpoRouterAbsoluteAppRoot = exports.getIsServer = exports.getBaseUrl = exports.getIsNodeModule = exports.getIsProd = exports.getIsFastRefreshEnabled = exports.getIsDev = exports.getPossibleProjectRoot = exports.getPlatform = exports.getBundler = exports.hasModule = void 0;
7
+ const path_1 = __importDefault(require("path"));
4
8
  function hasModule(name) {
5
9
  try {
6
10
  return !!require.resolve(name);
@@ -59,6 +63,12 @@ function getIsDev(caller) {
59
63
  return process.env.BABEL_ENV === 'development' || process.env.NODE_ENV === 'development';
60
64
  }
61
65
  exports.getIsDev = getIsDev;
66
+ function getIsFastRefreshEnabled(caller) {
67
+ if (!caller)
68
+ return false;
69
+ return caller.isHMREnabled && !caller.isServer && !caller.isNodeModule && getIsDev(caller);
70
+ }
71
+ exports.getIsFastRefreshEnabled = getIsFastRefreshEnabled;
62
72
  function getIsProd(caller) {
63
73
  if (caller?.isDev != null)
64
74
  return caller.isDev === false;
@@ -66,6 +76,10 @@ function getIsProd(caller) {
66
76
  return process.env.BABEL_ENV === 'production' || process.env.NODE_ENV === 'production';
67
77
  }
68
78
  exports.getIsProd = getIsProd;
79
+ function getIsNodeModule(caller) {
80
+ return caller?.isNodeModule ?? false;
81
+ }
82
+ exports.getIsNodeModule = getIsNodeModule;
69
83
  function getBaseUrl(caller) {
70
84
  return caller?.baseUrl ?? '';
71
85
  }
@@ -74,13 +88,36 @@ function getIsServer(caller) {
74
88
  return caller?.isServer ?? false;
75
89
  }
76
90
  exports.getIsServer = getIsServer;
91
+ function getExpoRouterAbsoluteAppRoot(caller) {
92
+ const rootModuleId = caller?.routerRoot ?? './app';
93
+ if (path_1.default.isAbsolute(rootModuleId)) {
94
+ return rootModuleId;
95
+ }
96
+ const projectRoot = getPossibleProjectRoot(caller) || '/';
97
+ return path_1.default.join(projectRoot, rootModuleId);
98
+ }
99
+ exports.getExpoRouterAbsoluteAppRoot = getExpoRouterAbsoluteAppRoot;
77
100
  function getInlineEnvVarsEnabled(caller) {
78
101
  const isWebpack = getBundler(caller) === 'webpack';
79
102
  const isDev = getIsDev(caller);
80
103
  const isServer = getIsServer(caller);
104
+ const isNodeModule = getIsNodeModule(caller);
81
105
  const preserveEnvVars = caller?.preserveEnvVars;
82
106
  // Development env vars are added in the serializer to avoid caching issues in development.
83
107
  // Servers have env vars left as-is to read from the environment.
84
- return !isWebpack && !isDev && !isServer && !preserveEnvVars;
108
+ return !isNodeModule && !isWebpack && !isDev && !isServer && !preserveEnvVars;
85
109
  }
86
110
  exports.getInlineEnvVarsEnabled = getInlineEnvVarsEnabled;
111
+ function getAsyncRoutes(caller) {
112
+ const isServer = getIsServer(caller);
113
+ if (isServer) {
114
+ return false;
115
+ }
116
+ const isProd = getIsProd(caller);
117
+ const platform = getPlatform(caller);
118
+ if (platform !== 'web' && isProd) {
119
+ return false;
120
+ }
121
+ return caller?.asyncRoutes ?? false;
122
+ }
123
+ exports.getAsyncRoutes = getAsyncRoutes;
@@ -6,9 +6,7 @@ import { ConfigAPI, types } from '@babel/core';
6
6
  * EXPO_PUBLIC_USE_STATIC
7
7
  * EXPO_ROUTER_ABS_APP_ROOT
8
8
  * EXPO_ROUTER_APP_ROOT
9
- * EXPO_ROUTER_IMPORT_MODE_IOS
10
- * EXPO_ROUTER_IMPORT_MODE_ANDROID
11
- * EXPO_ROUTER_IMPORT_MODE_WEB
9
+ * EXPO_ROUTER_IMPORT_MODE
12
10
  */
13
11
  export declare function expoRouterBabelPlugin(api: ConfigAPI & {
14
12
  types: typeof types;
@@ -4,92 +4,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.expoRouterBabelPlugin = void 0;
7
- const config_1 = require("expo/config");
8
- const fs_1 = __importDefault(require("fs"));
7
+ const core_1 = require("@babel/core");
9
8
  const path_1 = __importDefault(require("path"));
10
9
  const resolve_from_1 = __importDefault(require("resolve-from"));
11
10
  const common_1 = require("./common");
12
11
  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
- }
12
+ function getExpoRouterAppRoot(projectRoot, appFolder) {
13
+ // TODO: We should have cache invalidation if the expo-router/entry file location changes.
70
14
  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
15
  const appRoot = path_1.default.relative(path_1.default.dirname(routerEntry), appFolder);
74
16
  debug('routerEntry', routerEntry, appFolder, appRoot);
75
- process.env.EXPO_ROUTER_APP_ROOT_2 = appRoot;
76
17
  return appRoot;
77
18
  }
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
19
  /**
94
20
  * Inlines environment variables to configure the process:
95
21
  *
@@ -97,80 +23,57 @@ function getExpoRouterAbsoluteAppRoot(projectRoot) {
97
23
  * EXPO_PUBLIC_USE_STATIC
98
24
  * EXPO_ROUTER_ABS_APP_ROOT
99
25
  * EXPO_ROUTER_APP_ROOT
100
- * EXPO_ROUTER_IMPORT_MODE_IOS
101
- * EXPO_ROUTER_IMPORT_MODE_ANDROID
102
- * EXPO_ROUTER_IMPORT_MODE_WEB
26
+ * EXPO_ROUTER_IMPORT_MODE
103
27
  */
104
28
  function expoRouterBabelPlugin(api) {
105
29
  const { types: t } = api;
106
30
  const platform = api.caller(common_1.getPlatform);
107
31
  const possibleProjectRoot = api.caller(common_1.getPossibleProjectRoot);
32
+ const asyncRoutes = api.caller(common_1.getAsyncRoutes);
33
+ const routerAbsoluteRoot = api.caller(common_1.getExpoRouterAbsoluteAppRoot);
34
+ function isFirstInAssign(path) {
35
+ return core_1.types.isAssignmentExpression(path.parent) && path.parent.left === path.node;
36
+ }
108
37
  return {
109
38
  name: 'expo-router',
110
39
  visitor: {
111
- // Convert `process.env.EXPO_ROUTER_APP_ROOT` to a string literal
112
40
  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
41
  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));
42
+ if (path.get('object').matchesPattern('process.env')) {
43
+ const key = path.toComputedKey();
44
+ if (t.isStringLiteral(key) && !isFirstInAssign(path)) {
45
+ // Used for log box on web.
46
+ if (key.value.startsWith('EXPO_PROJECT_ROOT')) {
47
+ path.replaceWith(t.stringLiteral(projectRoot));
48
+ }
49
+ else if (
50
+ // TODO: Add cache invalidation.
51
+ key.value.startsWith('EXPO_PUBLIC_USE_STATIC')) {
52
+ if (platform === 'web') {
53
+ const isStatic = process.env.EXPO_PUBLIC_USE_STATIC === 'true' ||
54
+ process.env.EXPO_PUBLIC_USE_STATIC === '1';
55
+ path.replaceWith(t.booleanLiteral(isStatic));
56
+ }
57
+ else {
58
+ path.replaceWith(t.booleanLiteral(false));
59
+ }
60
+ }
61
+ else if (key.value.startsWith('EXPO_ROUTER_IMPORT_MODE')) {
62
+ path.replaceWith(t.stringLiteral(asyncRoutes ? 'lazy' : 'sync'));
63
+ }
64
+ if (
65
+ // Skip loading the app root in tests.
66
+ // This is handled by the testing-library utils
67
+ process.env.NODE_ENV !== 'test') {
68
+ if (key.value.startsWith('EXPO_ROUTER_ABS_APP_ROOT')) {
69
+ path.replaceWith(t.stringLiteral(routerAbsoluteRoot));
70
+ }
71
+ else if (key.value.startsWith('EXPO_ROUTER_APP_ROOT')) {
72
+ path.replaceWith(t.stringLiteral(getExpoRouterAppRoot(possibleProjectRoot, routerAbsoluteRoot)));
73
+ }
74
+ }
144
75
  }
145
76
  }
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
77
  },
175
78
  },
176
79
  };
package/build/index.js CHANGED
@@ -18,7 +18,9 @@ function babelPresetExpo(api, options = {}) {
18
18
  let platform = api.caller((caller) => caller?.platform);
19
19
  const engine = api.caller((caller) => caller?.engine) ?? 'default';
20
20
  const isDev = api.caller(common_1.getIsDev);
21
+ const isFastRefreshEnabled = api.caller(common_1.getIsFastRefreshEnabled);
21
22
  const baseUrl = api.caller(common_1.getBaseUrl);
23
+ const supportsStaticESM = api.caller((caller) => caller?.supportsStaticESM);
22
24
  // Unlike `isDev`, this will be `true` when the bundler is explicitly set to `production`,
23
25
  // i.e. `false` when testing, development, or used with a bundler that doesn't specify the correct inputs.
24
26
  const isProduction = api.caller(common_1.getIsProd);
@@ -33,21 +35,21 @@ function babelPresetExpo(api, options = {}) {
33
35
  if (platform === 'web') {
34
36
  // Only disable import/export transform when Webpack is used because
35
37
  // Metro does not support tree-shaking.
36
- platformOptions.disableImportExportTransform = isWebpack;
38
+ platformOptions.disableImportExportTransform = supportsStaticESM ?? isWebpack;
37
39
  }
38
40
  else {
39
- platformOptions.disableImportExportTransform = false;
41
+ platformOptions.disableImportExportTransform = supportsStaticESM ?? false;
40
42
  }
41
43
  }
42
44
  if (platformOptions.unstable_transformProfile == null) {
43
45
  platformOptions.unstable_transformProfile = engine === 'hermes' ? 'hermes-stable' : 'default';
44
46
  }
45
47
  // Note that if `options.lazyImports` is not set (i.e., `null` or `undefined`),
46
- // `metro-react-native-babel-preset` will handle it.
48
+ // `@react-native/babel-preset` will handle it.
47
49
  const lazyImportsOption = platformOptions?.lazyImports;
48
50
  const extraPlugins = [];
49
51
  if (engine !== 'hermes') {
50
- // `metro-react-native-babel-preset` configures this plugin with `{ loose: true }`, which breaks all
52
+ // `@react-native/babel-preset` configures this plugin with `{ loose: true }`, which breaks all
51
53
  // getters and setters in spread objects. We need to add this plugin ourself without that option.
52
54
  // @see https://github.com/expo/expo/pull/11960#issuecomment-887796455
53
55
  extraPlugins.push([
@@ -78,10 +80,6 @@ function babelPresetExpo(api, options = {}) {
78
80
  if (platformOptions.useTransformReactJSXExperimental != null) {
79
81
  throw new Error(`babel-preset-expo: The option 'useTransformReactJSXExperimental' has been removed in favor of { jsxRuntime: 'classic' }.`);
80
82
  }
81
- const aliasPlugin = getAliasPlugin();
82
- if (aliasPlugin) {
83
- extraPlugins.push(aliasPlugin);
84
- }
85
83
  // Allow jest tests to redefine the environment variables.
86
84
  if (process.env.NODE_ENV !== 'test') {
87
85
  extraPlugins.push([
@@ -111,14 +109,23 @@ function babelPresetExpo(api, options = {}) {
111
109
  if ((0, common_1.hasModule)('expo-router')) {
112
110
  extraPlugins.push(expo_router_plugin_1.expoRouterBabelPlugin);
113
111
  }
112
+ if (isFastRefreshEnabled) {
113
+ extraPlugins.push([
114
+ require('react-refresh/babel'),
115
+ {
116
+ // We perform the env check to enable `isFastRefreshEnabled`.
117
+ skipEnvCheck: true,
118
+ },
119
+ ]);
120
+ }
114
121
  return {
115
122
  presets: [
116
123
  [
117
124
  // We use `require` here instead of directly using the package name because we want to
118
- // specifically use the `metro-react-native-babel-preset` installed by this package (ex:
125
+ // specifically use the `@react-native/babel-preset` installed by this package (ex:
119
126
  // `babel-preset-expo/node_modules/`). This way the preset will not change unintentionally.
120
127
  // Reference: https://github.com/expo/expo/pull/4685#discussion_r307143920
121
- require('metro-react-native-babel-preset'),
128
+ require('@react-native/babel-preset'),
122
129
  {
123
130
  // Defaults to undefined, set to `true` to disable `@babel/plugin-transform-flow-strip-types`
124
131
  disableFlowStripTypesTransform: platformOptions.disableFlowStripTypesTransform,
@@ -144,7 +151,7 @@ function babelPresetExpo(api, options = {}) {
144
151
  // behavior) or are in the blacklist.
145
152
  return !(importModuleSpecifier.includes('./') || lazyImports_1.lazyImports.has(importModuleSpecifier));
146
153
  }
147
- : // Pass the option directly to `metro-react-native-babel-preset`, which in turn
154
+ : // Pass the option directly to `@react-native/babel-preset`, which in turn
148
155
  // passes it to `babel-plugin-transform-modules-commonjs`
149
156
  lazyImportsOption,
150
157
  },
@@ -186,18 +193,5 @@ function babelPresetExpo(api, options = {}) {
186
193
  ].filter(Boolean),
187
194
  };
188
195
  }
189
- function getAliasPlugin() {
190
- if (!(0, common_1.hasModule)('@expo/vector-icons')) {
191
- return null;
192
- }
193
- return [
194
- require.resolve('babel-plugin-module-resolver'),
195
- {
196
- alias: {
197
- 'react-native-vector-icons': '@expo/vector-icons',
198
- },
199
- },
200
- ];
201
- }
202
196
  exports.default = babelPresetExpo;
203
197
  module.exports = babelPresetExpo;
@@ -12,17 +12,6 @@ function expoInlineEnvVars(api) {
12
12
  visitor: {
13
13
  MemberExpression(path, state) {
14
14
  const filename = state.filename;
15
- // If the filename is not defined, skip to prevent a node module from intercepting
16
- // environment variables.
17
- if (!filename) {
18
- debug('No filename found in state, skipping to be safe:', state.file.opts);
19
- return;
20
- }
21
- // Do nothing in node modules
22
- // Skip node_modules, the feature is a bit too sensitive to allow in arbitrary code.
23
- if (/node_modules/.test(filename)) {
24
- return;
25
- }
26
15
  if (path.get('object').matchesPattern('process.env')) {
27
16
  // @ts-expect-error: missing types
28
17
  const key = path.toComputedKey();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "babel-preset-expo",
3
- "version": "9.9.0",
3
+ "version": "10.0.0",
4
4
  "description": "The Babel preset for Expo projects",
5
5
  "main": "build/index.js",
6
6
  "files": [
@@ -47,13 +47,14 @@
47
47
  "@babel/preset-env": "^7.20.0",
48
48
  "@babel/preset-react": "^7.22.15",
49
49
  "@babel/plugin-transform-parameters": "^7.22.15",
50
- "babel-plugin-module-resolver": "^5.0.0",
50
+ "@react-native/babel-preset": "^0.73.18",
51
51
  "babel-plugin-react-native-web": "~0.18.10",
52
- "metro-react-native-babel-preset": "0.76.8"
52
+ "react-refresh": "0.14.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@babel/core": "^7.20.0",
56
+ "expo-module-scripts": "^3.3.0",
56
57
  "jest": "^29.2.1"
57
58
  },
58
- "gitHead": "3142a086578deffd8704a8f1b6f0f661527d836c"
59
+ "gitHead": "6aca7ce098ddc667776a3d7cf612adbb985e264a"
59
60
  }