babel-preset-expo 9.6.2 → 9.7.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.
@@ -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-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,150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const lazyImports_1 = require("./lazyImports");
4
+ function babelPresetExpo(api, options = {}) {
5
+ const { web = {}, native = {}, reanimated } = options;
6
+ const bundler = api.caller(getBundler);
7
+ const isWebpack = bundler === 'webpack';
8
+ let platform = api.caller((caller) => caller?.platform);
9
+ // If the `platform` prop is not defined then this must be a custom config that isn't
10
+ // defining a platform in the babel-loader. Currently this may happen with Next.js + Expo web.
11
+ if (!platform && isWebpack) {
12
+ platform = 'web';
13
+ }
14
+ const platformOptions = platform === 'web'
15
+ ? {
16
+ // Only disable import/export transform when Webpack is used because
17
+ // Metro does not support tree-shaking.
18
+ disableImportExportTransform: isWebpack,
19
+ ...web,
20
+ }
21
+ : { disableImportExportTransform: false, ...native };
22
+ // Note that if `options.lazyImports` is not set (i.e., `null` or `undefined`),
23
+ // `metro-react-native-babel-preset` will handle it.
24
+ const lazyImportsOption = options?.lazyImports;
25
+ const extraPlugins = [
26
+ // `metro-react-native-babel-preset` configures this plugin with `{ loose: true }`, which breaks all
27
+ // getters and setters in spread objects. We need to add this plugin ourself without that option.
28
+ // @see https://github.com/expo/expo/pull/11960#issuecomment-887796455
29
+ [require.resolve('@babel/plugin-proposal-object-rest-spread'), { loose: false }],
30
+ ];
31
+ // Set true to disable `@babel/plugin-transform-react-jsx`
32
+ // we override this logic outside of the metro preset so we can add support for
33
+ // React 17 automatic JSX transformations.
34
+ // If the logic for `useTransformReactJSXExperimental` ever changes in `metro-react-native-babel-preset`
35
+ // then this block should be updated to reflect those changes.
36
+ if (!platformOptions.useTransformReactJSXExperimental) {
37
+ extraPlugins.push([
38
+ require('@babel/plugin-transform-react-jsx'),
39
+ {
40
+ // Defaults to `automatic`, pass in `classic` to disable auto JSX transformations.
41
+ runtime: (options && options.jsxRuntime) || 'automatic',
42
+ ...(options &&
43
+ options.jsxRuntime !== 'classic' && {
44
+ importSource: (options && options.jsxImportSource) || 'react',
45
+ }),
46
+ },
47
+ ]);
48
+ // Purposefully not adding the deprecated packages:
49
+ // `@babel/plugin-transform-react-jsx-self` and `@babel/plugin-transform-react-jsx-source`
50
+ // back to the preset.
51
+ }
52
+ const aliasPlugin = getAliasPlugin();
53
+ if (aliasPlugin) {
54
+ extraPlugins.push(aliasPlugin);
55
+ }
56
+ if (platform === 'web') {
57
+ extraPlugins.push(require.resolve('babel-plugin-react-native-web'));
58
+ }
59
+ return {
60
+ presets: [
61
+ [
62
+ // We use `require` here instead of directly using the package name because we want to
63
+ // specifically use the `metro-react-native-babel-preset` installed by this package (ex:
64
+ // `babel-preset-expo/node_modules/`). This way the preset will not change unintentionally.
65
+ // Reference: https://github.com/expo/expo/pull/4685#discussion_r307143920
66
+ require('metro-react-native-babel-preset'),
67
+ {
68
+ // Defaults to undefined, set to something truthy to disable `@babel/plugin-transform-react-jsx-self` and `@babel/plugin-transform-react-jsx-source`.
69
+ withDevTools: platformOptions.withDevTools,
70
+ // Defaults to undefined, set to `true` to disable `@babel/plugin-transform-flow-strip-types`
71
+ disableFlowStripTypesTransform: platformOptions.disableFlowStripTypesTransform,
72
+ // Defaults to undefined, set to `false` to disable `@babel/plugin-transform-runtime`
73
+ enableBabelRuntime: platformOptions.enableBabelRuntime,
74
+ // Defaults to `'default'`, can also use `'hermes-canary'`
75
+ unstable_transformProfile: platformOptions.unstable_transformProfile,
76
+ // Set true to disable `@babel/plugin-transform-react-jsx` and
77
+ // the deprecated packages `@babel/plugin-transform-react-jsx-self`, and `@babel/plugin-transform-react-jsx-source`.
78
+ //
79
+ // Otherwise, you'll sometime get errors like the following (starting in Expo SDK 43, React Native 64, React 17):
80
+ //
81
+ // TransformError App.js: /path/to/App.js: Duplicate __self prop found. You are most likely using the deprecated transform-react-jsx-self Babel plugin.
82
+ // 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.
83
+ useTransformReactJSXExperimental: true,
84
+ disableImportExportTransform: platformOptions.disableImportExportTransform,
85
+ lazyImportExportTransform: lazyImportsOption === true
86
+ ? (importModuleSpecifier) => {
87
+ // Do not lazy-initialize packages that are local imports (similar to `lazy: true`
88
+ // behavior) or are in the blacklist.
89
+ return !(importModuleSpecifier.includes('./') || lazyImports_1.lazyImports.has(importModuleSpecifier));
90
+ }
91
+ : // Pass the option directly to `metro-react-native-babel-preset`, which in turn
92
+ // passes it to `babel-plugin-transform-modules-commonjs`
93
+ lazyImportsOption,
94
+ },
95
+ ],
96
+ ],
97
+ plugins: [
98
+ ...extraPlugins,
99
+ // TODO: Remove
100
+ [require.resolve('@babel/plugin-proposal-decorators'), { legacy: true }],
101
+ require.resolve('@babel/plugin-proposal-export-namespace-from'),
102
+ // Automatically add `react-native-reanimated/plugin` when the package is installed.
103
+ // TODO: Move to be a customTransformOption.
104
+ hasModule('react-native-reanimated') &&
105
+ reanimated !== false && [require.resolve('react-native-reanimated/plugin')],
106
+ ].filter(Boolean),
107
+ };
108
+ }
109
+ function getAliasPlugin() {
110
+ if (!hasModule('@expo/vector-icons')) {
111
+ return null;
112
+ }
113
+ return [
114
+ require.resolve('babel-plugin-module-resolver'),
115
+ {
116
+ alias: {
117
+ 'react-native-vector-icons': '@expo/vector-icons',
118
+ },
119
+ },
120
+ ];
121
+ }
122
+ function hasModule(name) {
123
+ try {
124
+ return !!require.resolve(name);
125
+ }
126
+ catch (error) {
127
+ if (error.code === 'MODULE_NOT_FOUND' && error.message.includes(name)) {
128
+ return false;
129
+ }
130
+ throw error;
131
+ }
132
+ }
133
+ /** Determine which bundler is being used. */
134
+ function getBundler(caller) {
135
+ if (!caller)
136
+ return null;
137
+ if (caller.bundler)
138
+ return caller.bundler;
139
+ if (
140
+ // Known tools that use `webpack`-mode via `babel-loader`: `@expo/webpack-config`, Next.js <10
141
+ caller.name === 'babel-loader' ||
142
+ // NextJS 11 uses this custom caller name.
143
+ caller.name === 'next-babel-turbo-loader') {
144
+ return 'webpack';
145
+ }
146
+ // Assume anything else is Metro.
147
+ return 'metro';
148
+ }
149
+ exports.default = babelPresetExpo;
150
+ module.exports = babelPresetExpo;
@@ -0,0 +1,2 @@
1
+ /** These Expo packages may have side-effects and should not be lazily initialized. */
2
+ export declare const lazyImports: Set<string>;
@@ -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']);
@@ -3,4 +3,4 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- module.exports = new Set(['expo', 'expo-asset', 'expo-task-manager']);
6
+ module.exports = require('./build/lazyImports').lazyImports;
package/package.json CHANGED
@@ -1,17 +1,20 @@
1
1
  {
2
2
  "name": "babel-preset-expo",
3
- "version": "9.6.2",
3
+ "version": "9.7.0",
4
4
  "description": "The Babel preset for Expo projects",
5
- "main": "index.js",
5
+ "main": "build/index.js",
6
6
  "files": [
7
- "index.js",
8
- "lazy-imports-blacklist.js",
9
- "plugins"
7
+ "build",
8
+ "lazy-imports-blacklist.js"
10
9
  ],
11
10
  "scripts": {
12
- "jest": "jest",
13
- "lint": "eslint .",
14
- "test": "jest --watch"
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": "79607a7325f47aa17c36d266100d09a4ff2cc544"
57
+ "gitHead": "ee2c866ba3c7fbc35ff2a3e896041cf15d3bd7c5"
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
- }