babel-preset-expo 11.0.10 → 11.1.0-canary-20240627-1402f4b

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
@@ -42,6 +42,24 @@ If the `bundler` is not defined, it will default to checking if a `babel-loader`
42
42
 
43
43
  ## Options
44
44
 
45
+ ### `react-compiler`
46
+
47
+ Settings to pass to `babel-plugin-react-compiler`. Set as `false` to disable the plugin. As of SDK 51, you must also enable `experiments.reactCompiler: true` in the `app.json`.
48
+
49
+ ```js
50
+ [
51
+ 'babel-preset-expo',
52
+ {
53
+ 'react-compiler': {
54
+ sources: (filename) => {
55
+ // Match file names to include in the React Compiler.
56
+ return filename.includes('src/path/to/dir');
57
+ },
58
+ },
59
+ },
60
+ ];
61
+ ```
62
+
45
63
  ### `minifyTypeofWindow`
46
64
 
47
65
  Set `minifyTypeofWindow: false` to preserve the `typeof window` check in your code, e.g. `if (typeof window === 'undefined')` -> `if (true)` in servers. This is useful when you're using libraries that mock the window object on native or in the server.
@@ -101,10 +101,7 @@ function reactClientReferencesPlugin() {
101
101
  path.pushContainer('body', core_1.template.ast(proxyModule.join('\n')));
102
102
  assertExpoMetadata(state.file.metadata);
103
103
  // Save the client reference in the metadata.
104
- if (!state.file.metadata.clientReferences) {
105
- state.file.metadata.clientReferences ??= [];
106
- }
107
- state.file.metadata.clientReferences.push(outputKey);
104
+ state.file.metadata.reactClientReference = outputKey;
108
105
  // Store the proxy export names for testing purposes.
109
106
  state.file.metadata.proxyExports = [...proxyExports];
110
107
  },
package/build/common.d.ts CHANGED
@@ -1,16 +1,17 @@
1
1
  export declare function hasModule(name: string): boolean;
2
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;
3
+ export declare function getBundler(caller?: any): "metro" | "webpack" | null;
4
+ export declare function getPlatform(caller?: any): string | null | undefined;
5
+ export declare function getPossibleProjectRoot(caller?: any): string | null | undefined;
6
6
  /** If bundling for a react-server target. */
7
- export declare function getIsReactServer(caller: any): boolean;
8
- export declare function getIsDev(caller: any): any;
9
- export declare function getIsFastRefreshEnabled(caller: any): any;
10
- export declare function getIsProd(caller: any): boolean;
11
- export declare function getIsNodeModule(caller: any): boolean;
12
- export declare function getBaseUrl(caller: any): string;
13
- export declare function getIsServer(caller: any): any;
14
- export declare function getExpoRouterAbsoluteAppRoot(caller: any): string;
15
- export declare function getInlineEnvVarsEnabled(caller: any): boolean;
16
- export declare function getAsyncRoutes(caller: any): boolean;
7
+ export declare function getIsReactServer(caller?: any): boolean;
8
+ export declare function getIsDev(caller?: any): boolean;
9
+ export declare function getIsFastRefreshEnabled(caller?: any): boolean | undefined;
10
+ export declare function getIsProd(caller?: any): boolean;
11
+ export declare function getIsNodeModule(caller?: any): boolean;
12
+ export declare function getBaseUrl(caller?: any): string;
13
+ export declare function getReactCompiler(caller?: any): boolean;
14
+ export declare function getIsServer(caller?: any): boolean;
15
+ export declare function getExpoRouterAbsoluteAppRoot(caller?: any): string;
16
+ export declare function getInlineEnvVarsEnabled(caller?: any): boolean;
17
+ export declare function getAsyncRoutes(caller?: any): boolean;
package/build/common.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getAsyncRoutes = exports.getInlineEnvVarsEnabled = exports.getExpoRouterAbsoluteAppRoot = exports.getIsServer = exports.getBaseUrl = exports.getIsNodeModule = exports.getIsProd = exports.getIsFastRefreshEnabled = exports.getIsDev = exports.getIsReactServer = exports.getPossibleProjectRoot = exports.getPlatform = exports.getBundler = exports.hasModule = void 0;
6
+ exports.getAsyncRoutes = exports.getInlineEnvVarsEnabled = exports.getExpoRouterAbsoluteAppRoot = exports.getIsServer = exports.getReactCompiler = exports.getBaseUrl = exports.getIsNodeModule = exports.getIsProd = exports.getIsFastRefreshEnabled = exports.getIsDev = exports.getIsReactServer = exports.getPossibleProjectRoot = exports.getPlatform = exports.getBundler = exports.hasModule = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  function hasModule(name) {
9
9
  try {
@@ -19,6 +19,7 @@ function hasModule(name) {
19
19
  exports.hasModule = hasModule;
20
20
  /** Determine which bundler is being used. */
21
21
  function getBundler(caller) {
22
+ assertExpoBabelCaller(caller);
22
23
  if (!caller)
23
24
  return null;
24
25
  if (caller.bundler)
@@ -35,6 +36,7 @@ function getBundler(caller) {
35
36
  }
36
37
  exports.getBundler = getBundler;
37
38
  function getPlatform(caller) {
39
+ assertExpoBabelCaller(caller);
38
40
  if (!caller)
39
41
  return null;
40
42
  if (caller.platform)
@@ -48,6 +50,7 @@ function getPlatform(caller) {
48
50
  }
49
51
  exports.getPlatform = getPlatform;
50
52
  function getPossibleProjectRoot(caller) {
53
+ assertExpoBabelCaller(caller);
51
54
  if (!caller)
52
55
  return null;
53
56
  if (caller.projectRoot)
@@ -58,10 +61,13 @@ function getPossibleProjectRoot(caller) {
58
61
  exports.getPossibleProjectRoot = getPossibleProjectRoot;
59
62
  /** If bundling for a react-server target. */
60
63
  function getIsReactServer(caller) {
64
+ assertExpoBabelCaller(caller);
61
65
  return caller?.isReactServer ?? false;
62
66
  }
63
67
  exports.getIsReactServer = getIsReactServer;
68
+ function assertExpoBabelCaller(caller) { }
64
69
  function getIsDev(caller) {
70
+ assertExpoBabelCaller(caller);
65
71
  if (caller?.isDev != null)
66
72
  return caller.isDev;
67
73
  // https://babeljs.io/docs/options#envname
@@ -69,12 +75,14 @@ function getIsDev(caller) {
69
75
  }
70
76
  exports.getIsDev = getIsDev;
71
77
  function getIsFastRefreshEnabled(caller) {
78
+ assertExpoBabelCaller(caller);
72
79
  if (!caller)
73
80
  return false;
74
81
  return caller.isHMREnabled && !caller.isServer && !caller.isNodeModule && getIsDev(caller);
75
82
  }
76
83
  exports.getIsFastRefreshEnabled = getIsFastRefreshEnabled;
77
84
  function getIsProd(caller) {
85
+ assertExpoBabelCaller(caller);
78
86
  if (caller?.isDev != null)
79
87
  return caller.isDev === false;
80
88
  // https://babeljs.io/docs/options#envname
@@ -86,14 +94,22 @@ function getIsNodeModule(caller) {
86
94
  }
87
95
  exports.getIsNodeModule = getIsNodeModule;
88
96
  function getBaseUrl(caller) {
97
+ assertExpoBabelCaller(caller);
89
98
  return caller?.baseUrl ?? '';
90
99
  }
91
100
  exports.getBaseUrl = getBaseUrl;
101
+ function getReactCompiler(caller) {
102
+ assertExpoBabelCaller(caller);
103
+ return caller?.supportsReactCompiler ?? false;
104
+ }
105
+ exports.getReactCompiler = getReactCompiler;
92
106
  function getIsServer(caller) {
107
+ assertExpoBabelCaller(caller);
93
108
  return caller?.isServer ?? false;
94
109
  }
95
110
  exports.getIsServer = getIsServer;
96
111
  function getExpoRouterAbsoluteAppRoot(caller) {
112
+ assertExpoBabelCaller(caller);
97
113
  const rootModuleId = caller?.routerRoot ?? './app';
98
114
  if (path_1.default.isAbsolute(rootModuleId)) {
99
115
  return rootModuleId;
@@ -103,6 +119,7 @@ function getExpoRouterAbsoluteAppRoot(caller) {
103
119
  }
104
120
  exports.getExpoRouterAbsoluteAppRoot = getExpoRouterAbsoluteAppRoot;
105
121
  function getInlineEnvVarsEnabled(caller) {
122
+ assertExpoBabelCaller(caller);
106
123
  const isWebpack = getBundler(caller) === 'webpack';
107
124
  const isDev = getIsDev(caller);
108
125
  const isServer = getIsServer(caller);
@@ -114,6 +131,7 @@ function getInlineEnvVarsEnabled(caller) {
114
131
  }
115
132
  exports.getInlineEnvVarsEnabled = getInlineEnvVarsEnabled;
116
133
  function getAsyncRoutes(caller) {
134
+ assertExpoBabelCaller(caller);
117
135
  const isServer = getIsServer(caller);
118
136
  if (isServer) {
119
137
  return false;
@@ -69,7 +69,7 @@ function expoRouterBabelPlugin(api) {
69
69
  path.replaceWith(t.stringLiteral(routerAbsoluteRoot));
70
70
  }
71
71
  else if (key.value.startsWith('EXPO_ROUTER_APP_ROOT')) {
72
- path.replaceWith(t.stringLiteral(getExpoRouterAppRoot(possibleProjectRoot, routerAbsoluteRoot)));
72
+ path.replaceWith(t.stringLiteral(getExpoRouterAppRoot(projectRoot, routerAbsoluteRoot)));
73
73
  }
74
74
  }
75
75
  }
package/build/index.d.ts CHANGED
@@ -13,6 +13,53 @@ type BabelPresetExpoPlatformOptions = {
13
13
  disableFlowStripTypesTransform?: boolean;
14
14
  enableBabelRuntime?: boolean;
15
15
  unstable_transformProfile?: 'default' | 'hermes-stable' | 'hermes-canary';
16
+ /** Settings to pass to `babel-plugin-react-compiler`. Set as `false` to disable the plugin. */
17
+ 'react-compiler'?: false | {
18
+ enableUseMemoCachePolyfill?: boolean;
19
+ compilationMode?: 'infer' | 'strict';
20
+ panicThreshold?: 'none' | 'all_errors' | 'critical_errors';
21
+ logger?: any;
22
+ environment?: {
23
+ customHooks?: unknown;
24
+ enableResetCacheOnSourceFileChanges?: boolean;
25
+ enablePreserveExistingMemoizationGuarantees?: boolean;
26
+ /** @default true */
27
+ validatePreserveExistingMemoizationGuarantees?: boolean;
28
+ enableForest?: boolean;
29
+ enableUseTypeAnnotations?: boolean;
30
+ /** @default true */
31
+ enableReactiveScopesInHIR?: boolean;
32
+ /** @default true */
33
+ validateHooksUsage?: boolean;
34
+ validateRefAccessDuringRender?: boolean;
35
+ /** @default true */
36
+ validateNoSetStateInRender?: boolean;
37
+ validateMemoizedEffectDependencies?: boolean;
38
+ validateNoCapitalizedCalls?: string[] | null;
39
+ /** @default true */
40
+ enableAssumeHooksFollowRulesOfReact?: boolean;
41
+ /** @default true */
42
+ enableTransitivelyFreezeFunctionExpressions: boolean;
43
+ enableEmitFreeze?: unknown;
44
+ enableEmitHookGuards?: unknown;
45
+ enableEmitInstrumentForget?: unknown;
46
+ assertValidMutableRanges?: boolean;
47
+ enableChangeVariableCodegen?: boolean;
48
+ enableMemoizationComments?: boolean;
49
+ throwUnknownException__testonly?: boolean;
50
+ enableTreatFunctionDepsAsConditional?: boolean;
51
+ /** Automatically enabled when reanimated plugin is added. */
52
+ enableCustomTypeDefinitionForReanimated?: boolean;
53
+ /** @default `null` */
54
+ hookPattern?: string | null;
55
+ };
56
+ gating?: unknown;
57
+ noEmit?: boolean;
58
+ runtimeModule?: string | null;
59
+ eslintSuppressionRules?: unknown | null;
60
+ flowSuppressions?: boolean;
61
+ ignoreUseNoForget?: boolean;
62
+ };
16
63
  /** Enable `typeof window` runtime checks. The default behavior is to minify `typeof window` on web clients to `"object"` and `"undefined"` on servers. */
17
64
  minifyTypeofWindow?: boolean;
18
65
  };
package/build/index.js CHANGED
@@ -21,9 +21,11 @@ function babelPresetExpo(api, options = {}) {
21
21
  let platform = api.caller((caller) => caller?.platform);
22
22
  const engine = api.caller((caller) => caller?.engine) ?? 'default';
23
23
  const isDev = api.caller(common_1.getIsDev);
24
+ const isNodeModule = api.caller(common_1.getIsNodeModule);
24
25
  const isServer = api.caller(common_1.getIsServer);
25
26
  const isReactServer = api.caller(common_1.getIsReactServer);
26
27
  const isFastRefreshEnabled = api.caller(common_1.getIsFastRefreshEnabled);
28
+ const isReactCompilerEnabled = api.caller(common_1.getReactCompiler);
27
29
  const baseUrl = api.caller(common_1.getBaseUrl);
28
30
  const supportsStaticESM = api.caller((caller) => caller?.supportsStaticESM);
29
31
  const isServerEnv = isServer || isReactServer;
@@ -57,6 +59,30 @@ function babelPresetExpo(api, options = {}) {
57
59
  // `@react-native/babel-preset` will handle it.
58
60
  const lazyImportsOption = platformOptions?.lazyImports;
59
61
  const extraPlugins = [];
62
+ // Add compiler as soon as possible to prevent other plugins from modifying the code.
63
+ if (isReactCompilerEnabled &&
64
+ // Don't run compiler on node modules, it can only safely be run on the user's code.
65
+ !isNodeModule &&
66
+ // Only run for client code. It's unclear if compiler has any benefits for React Server Components.
67
+ // NOTE: We might want to allow running it to prevent hydration errors.
68
+ !isServerEnv &&
69
+ // Give users the ability to opt-out of the feature, per-platform.
70
+ platformOptions['react-compiler'] !== false) {
71
+ extraPlugins.push([
72
+ require('babel-plugin-react-compiler'),
73
+ {
74
+ runtimeModule: 'babel-preset-expo/react-compiler-runtime.js',
75
+ // enableUseMemoCachePolyfill: true,
76
+ // compilationMode: 'infer',
77
+ environment: {
78
+ enableResetCacheOnSourceFileChanges: !isProduction,
79
+ ...(platformOptions['react-compiler']?.environment ?? {}),
80
+ },
81
+ panicThreshold: isDev ? undefined : 'NONE',
82
+ ...platformOptions['react-compiler'],
83
+ },
84
+ ]);
85
+ }
60
86
  if (engine !== 'hermes') {
61
87
  // `@react-native/babel-preset` configures this plugin with `{ loose: true }`, which breaks all
62
88
  // getters and setters in spread objects. We need to add this plugin ourself without that option.
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "babel-preset-expo",
3
- "version": "11.0.10",
3
+ "version": "11.1.0-canary-20240627-1402f4b",
4
4
  "description": "The Babel preset for Expo projects",
5
5
  "main": "build/index.js",
6
6
  "files": [
7
7
  "build",
8
- "lazy-imports-blacklist.js"
8
+ "lazy-imports-blacklist.js",
9
+ "react-compiler-runtime.js"
9
10
  ],
10
11
  "scripts": {
11
12
  "build": "expo-module build",
@@ -48,13 +49,14 @@
48
49
  "@babel/preset-typescript": "^7.23.0",
49
50
  "@babel/preset-react": "^7.22.15",
50
51
  "@react-native/babel-preset": "0.74.84",
52
+ "babel-plugin-react-compiler": "^0.0.0-experimental-938cd9a-20240601",
51
53
  "babel-plugin-react-native-web": "~0.19.10",
52
54
  "react-refresh": "^0.14.2"
53
55
  },
54
56
  "devDependencies": {
55
57
  "@babel/core": "^7.20.0",
56
- "expo-module-scripts": "^3.3.0",
58
+ "expo-module-scripts": "3.6.0-canary-20240627-1402f4b",
57
59
  "jest": "^29.2.1"
58
60
  },
59
- "gitHead": "6f609a05a2d4dac7fd281bcc502575440c5af7c9"
61
+ "gitHead": "1402f4bcfdfcec328fc1e20cf1656bbefe7c3b7b"
60
62
  }
@@ -0,0 +1,21 @@
1
+ // lib/react-compiler-runtime.js
2
+ const $empty = Symbol.for('react.memo_cache_sentinel');
3
+ const React = require('react');
4
+ /**
5
+ * DANGER: this hook is NEVER meant to be called directly!
6
+ *
7
+ * Note that this is a temporary userspace implementation of this function
8
+ * from React 19. It is not as efficient and may invalidate more frequently
9
+ * than the official API. Please upgrade to React 19 as soon as you can.
10
+ **/
11
+ export function c(size) {
12
+ return React.useState(() => {
13
+ const $ = new Array(size);
14
+ for (let ii = 0; ii < size; ii++) {
15
+ $[ii] = $empty;
16
+ }
17
+ // @ts-ignore
18
+ $[$empty] = true;
19
+ return $;
20
+ })[0];
21
+ }