diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Reanimated.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Reanimated.ts index 9cf6e51dcb..92775fff00 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Reanimated.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Reanimated.ts @@ -2,10 +2,30 @@ import type * as BabelCore from "@babel/core"; import { hasOwnProperty } from "../Utils/utils"; import { PluginOptions } from "./Options"; +function hasModule(name: string): boolean { + try { + return !!require.resolve(name); + } catch (error: any) { + if ( + error.code === "MODULE_NOT_FOUND" && + error.message.indexOf(name) !== -1 + ) { + return false; + } + throw error; + } +} + +/** + * Tries to detect if reanimated is installed by first looking for the presence of the babel plugin. + * However, babel-preset-expo includes it by default so it is occasionally ommitted. If so, we do + * a check to see if `react-native-animated` is requireable. + * + * See https://github.com/expo/expo/blob/e4b8d86442482c7316365a6b7ec1141eec73409d/packages/babel-preset-expo/src/index.ts#L300-L301 + */ export function pipelineUsesReanimatedPlugin( plugins: Array | null | undefined ): boolean { - let hasReanimated = false; if (Array.isArray(plugins)) { for (const plugin of plugins) { if (hasOwnProperty(plugin, "key")) { @@ -14,13 +34,12 @@ export function pipelineUsesReanimatedPlugin( typeof key === "string" && key.indexOf("react-native-reanimated") !== -1 ) { - hasReanimated = true; - break; + return true; } } } } - return hasReanimated; + return hasModule("react-native-reanimated"); } export function injectReanimatedFlag(options: PluginOptions): PluginOptions {