dohooo / react-native-reanimated-carousel

šŸŽ  React Native swiper/carousel component, fully implemented using reanimated v2, support to iOS/Android/Web. (Swiper/Carousel)
https://react-native-reanimated-carousel.vercel.app
MIT License
2.85k stars 329 forks source link

[4.0.0-alpha12] Metro error on Expo 51 / Web: Cannot access 'computedOffsetXValueWithAutoFillData' before initialization #634

Open mortenmo opened 4 months ago

mortenmo commented 4 months ago

Describe the bug

When starting up metro after migrating to Expo 51, carousel fails during initialization.

Screenshots

Metro error: Cannot access 'computedOffsetXValueWithAutoFillData' before initialization

   5 | });
   6 | exports.computedFillDataWithAutoFillData = computedFillDataWithAutoFillData;
>  7 | exports.computedOffsetXValueWithAutoFillData = computedOffsetXValueWithAutoFillData;
     |                                                ^
   8 | exports.computedRealIndexWithAutoFillData = computedRealIndexWithAutoFillData;
   9 | exports.convertToSharedIndex = convertToSharedIndex;
  10 |

Call Stack
  factory (node_modules/react-native-reanimated-carousel/lib/commonjs/utils/computed-with-auto-fill-data.js:7:48)
  loadModuleImplementation (node_modules/metro-runtime/src/polyfills/require.js:273:5)
  guardedLoadModule (node_modules/metro-runtime/src/polyfills/require.js:180:12)
  require (node_modules/metro-runtime/src/polyfills/require.js:89:7)
  factory (node_modules/react-native-reanimated-carousel/lib/commonjs/components/ItemRenderer.js:16:33)
  loadModuleImplementation (node_modules/metro-runtime/src/polyfills/require.js:273:5)
  guardedLoadModule (node_modules/metro-runtime/src/polyfills/require.js:180:12)
  require (node_modules/metro-runtime/src/polyfills/require.js:89:7)
  factory (node_modules/react-native-reanimated-carousel/lib/commonjs/components/Carousel.js:16:21)
  loadModuleImplementation (node_modules/metro-runtime/src/polyfills/require.js:273:5)

Versions (please complete the following information):

Additional context

Using metro to build web.

dosubot[bot] commented 4 months ago

Hey there, @mortenmo! šŸ‘‹ I'm here to help you with any bugs, questions, or contributions you have while you wait for a human maintainer. I'm a bot that can assist with all things related to the repository.

To resolve the initialization error "Cannot access 'computedOffsetXValueWithAutoFillData' before initialization" when starting up Metro after migrating to Expo 51, ensure that the function computedOffsetXValueWithAutoFillData is properly defined and exported before it is used. The provided code snippet already shows the correct definition and export of the function.

Here is the relevant part of the code:

export function computedOffsetXValueWithAutoFillData(
  params: BaseParams<{
    rawDataLength: number
    value: number
    size: number
  }>,
) {
  "worklet";

  const { rawDataLength, value, size, loop, autoFillData } = params;

  if (isAutoFillData({ loop, autoFillData })) {
    switch (rawDataLength) {
      case SINGLE_ITEM:
        return value % size;
      case DOUBLE_ITEM:
        return value % (size * 2);
    }
  }

  return value;
}

Ensure that this function is not being referenced before its definition in your code. If the error persists, it might be due to a circular dependency or an import issue. Double-check your import statements and the order of your function definitions to ensure there are no circular dependencies [1].

To continue talking to Dosu, mention @dosu.

hairgai commented 4 months ago

same

du5rte commented 4 months ago

Having the same issue

girlboss-energy commented 3 months ago

+1

resticker commented 3 months ago

I wonder if this is related to Babel's config? The React Native Reanimated docs requires react-native-reanimated/plugin to be added to the babel config to make worklets function properly. And I notice that computedOffsetXValueWithAutoFillData() uses a "worklet"

I'm using Expo and getting the same Metro error: Cannot access 'computedOffsetXValueWithAutoFillData' before initialization error when running in the browser. I added the plugin to babel.config.js, but still getting it (turns out this is auto added via babel-preset-expo

Here are the default Expo package versions for reference: image

resticker commented 3 months ago

Possible workaround: Add "@babel/plugin-transform-block-scoping" to my babel.config.js plugins list

image

Got this idea from this react-native-reanimated issue

I'd rather not need to add "@babel/plugin-transform-block-scoping" to my plugin list just for this issue, but at least it seems to work šŸ˜ƒ

hirenapatel1109 commented 2 months ago

Possible workaround: Add "@babel/plugin-transform-block-scoping" to my babel.config.js plugins list

image

Got this idea from this react-native-reanimated issue

I'd rather not need to add "@babel/plugin-transform-block-scoping" to my plugin list just for this issue, but at least it seems to work šŸ˜ƒ

This solution does not seem to work for me. I am using a Windows and using the Web version for testing.

hirenapatel1109 commented 2 months ago

I found the solution. As mentioned earlier, this issue is because of a circular dependency in react-native-gesture-handler. I found the circular issue here. Which references another PR that solved the circular dependency.

The solution is to simply upgrade the react-native-gesture-handler to the latest 2.18.1 by running

npm install --save react-native-gesture-handler@2.18.1
datJ0e commented 2 months ago

The solution is to simply upgrade the react-native-gesture-handler to the latest 2.18.1 by running

This doesn't seem to work for me, even after updating to react-native-gesture-handler 2.18.1. I also tried 2.19.0, still no luck.

kaumac commented 1 month ago

The solution is to simply upgrade the react-native-gesture-handler to the latest 2.18.1 by running

This doesn't seem to work for me, even after updating to react-native-gesture-handler 2.18.1. I also tried 2.19.0, still no luck.

Same here, tested 2.20.0 and no luck either

ystrdy commented 4 weeks ago

If you're using react-native-reanimated-carousel in an Expo project, you can try the following method:

First, customize the metro configuration by running npx expo customize metro.config.js

Then modify the code in the metro.config.js file to the following:

/* eslint-env node */
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

config.resolver.resolveRequest = (context, realModuleName, platform) => {
  if (realModuleName === 'react-native-reanimated-carousel') {
    return {
      filePath: path.resolve(__dirname, 'node_modules/react-native-reanimated-carousel/lib/module/index.js'),
      type: 'sourceFile',
    };
  }
  return context.resolveRequest(context, realModuleName, platform);
};

module.exports = config;
kaumac commented 4 weeks ago

If you're using react-native-reanimated-carousel in an Expo project, you can try the following method:

First, customize the metro configuration by running npx expo customize metro.config.js

Then modify the code in the metro.config.js file to the following:

/* eslint-env node */
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

config.resolver.resolveRequest = (context, realModuleName, platform) => {
  if (realModuleName === 'react-native-reanimated-carousel') {
    return {
      filePath: path.resolve(__dirname, 'node_modules/react-native-reanimated-carousel/lib/module/index.js'),
      type: 'sourceFile',
    };
  }
  return context.resolveRequest(context, realModuleName, platform);
};

module.exports = config;

Thanks @ystrdy !

I can confirm that doing this fixes the problem.

I was previously using @resticker 's solution. With @ystrdy 's solution I was able to remove the babel plugin and its working fine.

This solution should be added to the docs IMO, specially considering Expo is being recommended by default by RN now.

jony89 commented 2 weeks ago

same here.

rmondev commented 1 week ago

Thank you @ystrdy ! Your solution worked for me!

Vimiso commented 1 week ago
expo: ~51.0.39 => 51.0.39 
react-native: 0.74.5 => 0.74.5 
react-native-web: ~0.19.10 => 0.19.12 

Just to organise the multiple issues going on here:

1

upgrading to react-native-gesture-handler@2.18.1

In my case, this fixed the following warning:

WARN  Require cycle: node_modules/react-native-gesture-handler/lib/commonjs/RNGestureHandlerModule.web.js -> node_modules/react-native-gesture-handler/lib/commonjs/web/Gestures.js -> node_modules/react-native-gesture-handler/lib/commonjs/web/handlers/PanGestureHandler.js -> node_modules/react-native-gesture-handler/lib/commonjs/web/handlers/GestureHandler.js -> node_modules/react-native-gesture-handler/lib/commonjs/handlers/gestureHandlerCommon.js -> node_modules/react-native-gesture-handler/lib/commonjs/RNGestureHandlerModule.web.js

2

If you're using react-native-reanimated-carousel in an Expo project, you can try the following method:

First, customize the metro configuration by running npx expo customize metro.config.js

Then modify the code in the metro.config.js file to the following:

/* eslint-env node */
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

config.resolver.resolveRequest = (context, realModuleName, platform) => {
  if (realModuleName === 'react-native-reanimated-carousel') {
    return {
      filePath: path.resolve(__dirname, 'node_modules/react-native-reanimated-carousel/lib/module/index.js'),
      type: 'sourceFile',
    };
  }
  return context.resolveRequest(context, realModuleName, platform);
};

module.exports = config;

In my case, this fixed the following static rendering error:

Cannot access 'computedOffsetXValueWithAutoFillData' before initialization

Are us metro users stuck with this approach forever? It's a circular dependency issue. Is there a cleaner fix?

3 (bonus)

This issue recommends jumping onto version 4 (not yet stable release) - although for me not completely necessary.

PS. wen v4 release?!