Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

After updating to expo 52: ReferenceError: _WORKLET | __reanimatedLoggerConfig is not defined #6740

Open
abretonc7s opened this issue Nov 21, 2024 · 27 comments
Assignees
Labels
Missing repro This issue need minimum repro scenario Platform: Android This issue is specific to Android Platform: iOS This issue is specific to iOS Platform: Web This issue is specific to web

Comments

@abretonc7s
Copy link

Description

After updating to Expo SDK 52, I encountered a ReferenceError: _WORKLET is not defined error on web platform. This error occurred after running expo install --fix to update dependencies. The error prevents the application from running properly on web.

Relevant dependencies:

{
  "dependencies": {
    "expo": "~52.0.0",
    "react-native-reanimated": "~3.6.1",
    "@react-native-community/slider": "4.5.5",
    "@gorhom/bottom-sheet": "^5.0.5",
    "@gorhom/portal": "~1.0.14"
  }
}
// packages/expo-audio-ui/src/AnimatedCandle/AnimatedCandle.tsx
import { Rect } from '@shopify/react-native-skia'
import React, { useEffect } from 'react'
import { Platform } from 'react-native'
import { useSharedValue, withTiming } from 'react-native-reanimated'

import { CANDLE_OFFCANVAS_COLOR } from '../constants'

export interface AnimatedCandleProps {
    height: number
    x: number
    y: number
    startY: number
    width: number
    color: string
    animated?: boolean
}
const AnimatedCandle: React.FC<AnimatedCandleProps> = ({
    color: targetColor,
    x: targetX,
    y: targetY,
    startY,
    height: targetHeight,
    width,
    animated = true,
}) => {
    const y = useSharedValue(startY)
    const height = useSharedValue(0)
    const x = useSharedValue(targetX)
    const color = useSharedValue(CANDLE_OFFCANVAS_COLOR)

    useEffect(() => {
        if (Platform.OS === 'web') {
            y.value = targetY
            height.value = targetHeight
            x.value = targetX
            color.value = targetColor
            return
        }

        if (animated) {
            y.value = withTiming(targetY, { duration: 500 })
            height.value = withTiming(targetHeight, { duration: 500 })
            x.value = withTiming(targetX, { duration: 500 })
            color.value = withTiming(targetColor, { duration: 500 })
        } else {
            y.value = targetY
            height.value = targetHeight
            x.value = targetX
            color.value = targetColor
        }
    }, [targetY, targetHeight, targetX, targetColor, animated])

    return <Rect x={x} y={y} width={width} height={height} color={color} />
}

export default React.memo(AnimatedCandle)

Steps to reproduce

on Web it seems that using any wtihTiming creates the issue.

Snack or a link to a repository

https://github.com/deeeed/expo-audio-stream/blob/main/apps/playground/src/app/minimal.tsx

Reanimated version

3.6.1

React Native version

0.76.2

Platforms

Android, iOS, Web

JavaScript runtime

Hermes

Workflow

Expo Dev Client

Architecture

Fabric (New Architecture)

Build type

Debug app & dev bundle

Device

Real device

Device model

iphone pro 13

Acknowledgements

Yes

@github-actions github-actions bot added Missing repro This issue need minimum repro scenario Platform: Android This issue is specific to Android Platform: iOS This issue is specific to iOS Platform: Web This issue is specific to web labels Nov 21, 2024
@hirbod
Copy link
Contributor

hirbod commented Nov 22, 2024

I can confirm the problem. 3.16.* is failing on web for me. 3.15 works fine.

Screenshot 2024-11-22 at 10 27 12 Screenshot 2024-11-22 at 09 58 36

@tjzel
Copy link
Collaborator

tjzel commented Nov 22, 2024

@hirbod @abretonc7s I'm on it!

@tjzel tjzel self-assigned this Nov 22, 2024
@tjzel
Copy link
Collaborator

tjzel commented Nov 22, 2024

Heyi @abretonc7s @hirbod I tried to reproduce it locally but it didn't work. Could you provide some minimal expo repo where this issue appears?

@MariusCatanoiu
Copy link

similar here.
Property '_reanimatedLoggerConfig' doesn't exit
at line 96 in the logger.ts file

@hirbod
Copy link
Contributor

hirbod commented Nov 22, 2024

For now, I added

if (Platform.OS === 'web') {
  global._WORKLET = false
  // @ts-expect-error
  global._log = console.log
  // @ts-expect-error
  global._getAnimationTimestamp = () => performance.now()
}

as a hack in my entrypoint. Everything works now, beside reanimatedLoggerConfig, but I don't import configureReanimatedLogger for web.

@tjzel
Copy link
Collaborator

tjzel commented Nov 25, 2024

@abretonc7s @hirbod @MariusCatanoiu

The supposed fix is available on @next and @nightly versions of Reanimated. Could you install it and see if it resolves the issue?

@abretonc7s
Copy link
Author

I tried the latest night build "react-native-reanimated": "3.17.0-nightly-20241124-af73db066"
image

@tjzel
Copy link
Collaborator

tjzel commented Nov 25, 2024

Well that sucks 🤔

@hirbod
Copy link
Contributor

hirbod commented Nov 25, 2024

That aligns with my observations, as I also tried patch 3.16.2, and it didn’t work.
I’m starting to think this issue occurs when both iOS and the web are running simultaneously and Metro strips code?

Now, let me add a bit more confusion to the topic:

if (Platform.OS !== 'web') {
  // We need to set the log level to error to avoid spamming the console because of NativeWind for now
  configureReanimatedLogger({
    level: ReanimatedLogLevel.error,
  });
} else {
  global._WORKLET = false;
  // @ts-expect-error
  global._log = console.log;
  // @ts-expect-error
  global._getAnimationTimestamp = () => performance.now();
}

This is my "hack." After adding it, changing the if condition from !== to ===, reloading, and then switching it back, the "bug" disappeared—even without the hack. Does that make sense? No. I’m starting to think the Metro bundler and its cache are doing something strange.

@tjzel
Copy link
Collaborator

tjzel commented Nov 25, 2024

Yes, it happened to me a few times recently that only after git clean -Xdf the Metro cache was properly reset in some exotic cases 🤔

@tjzel
Copy link
Collaborator

tjzel commented Nov 25, 2024

@abretonc7s Could you see if wiping all the caches works for you on the nightly versions?

@abretonc7s
Copy link
Author

Doesn't work with the nighlty, cleaning all caches.

You can easily reproduce, just make a component and run it on web

import React, { useEffect } from 'react'
import { ColorValue, View } from 'react-native'
import { Text } from 'react-native-paper'
import Animated, {
    useAnimatedStyle,
    useSharedValue,
    withRepeat,
    withSpring,
} from 'react-native-reanimated'

interface LoaderProps {
    color?: ColorValue
    size?: number
}

const Loader = ({ color, size = 40 }: LoaderProps) => {
    const rotateValue = useSharedValue(0)

    const handleRotation = (value: number): string => {
        'worklet'
        return `${value * 4 * Math.PI}rad`
    }

    const rotateStyles = useAnimatedStyle(() => {
        return {
            transform: [
                { rotate: handleRotation(rotateValue.value) },
                { scale: rotateValue.value + 0.3 },
            ],
            opacity: rotateValue.value + 0.2,
            borderRadius: rotateValue.value * 20,
        }
    })

    useEffect(() => {
        rotateValue.value = withRepeat(withSpring(0.5), -1, true)
    }, [])

    return (
        <View
            style={{
                justifyContent: 'center',
                alignItems: 'center',
            }}
        >
            <Animated.View
                style={[
                    {
                        height: size,
                        width: size,
                        backgroundColor: color,
                        marginTop: 5,
                    },
                    rotateStyles,
                ]}
            />
        </View>
    )
}

const TestScreen = () => {
    return (
        <View>
            <Text>Test</Text>
            <Loader />
        </View>
    )
}

export default TestScreen

util.js:347 Uncaught ReferenceError: _WORKLET is not defined

@tjzel
Copy link
Collaborator

tjzel commented Nov 26, 2024

@abretonc7s When I run this snippet on a fresh Expo app and start web everything works well.

@vonSchweeee
Copy link

vonSchweeee commented Nov 26, 2024

Same happening here, web only works with 3.15.x but Android only works on 3.16.x. (RN 0.76)

@abretonc7s
Copy link
Author

abretonc7s commented Nov 27, 2024

I have the reverse issue... 3.15 works for web but then android conflicts... Anyway expo recommends 3.16.1 which has the web issue.
I am currently running @hirbod hack as a workaround

if (Platform.OS === 'web') {
  global._WORKLET = false
  // @ts-expect-error
  global._log = console.log
  // @ts-expect-error
  global._getAnimationTimestamp = () => performance.now()
}

@byCedric
Copy link

byCedric commented Dec 2, 2024

I'd love to take a look at this issue too, mostly to see if this is a Reanimated issue or an Expo issue. Unfortunately, I can't reproduce with none of the examples here, nor do I get _WORKLET being undefined on web. Not using Reanimated 3.6.1, 3.16.1, 3.16.2, 3.16.3, 3.15.5, with or without treeshaking enabled, not in dev mode (expo start) and not in production exports (expo export -p web && npx serve ./dist) -- all using SDK 52 (expo@52.0.11).

If someone can provide a repro, using the blank or default Expo templates, I'd be more than happy to debug this too.

PS. The original monorepo posted also did not trigger this error for me.

@deeeed
Copy link

deeeed commented Dec 5, 2024

Hey @byCedric I pushed an update to https://deeeed.github.io/expo-audio-stream/playground/more where you can see the bug.

You can just pull this branch and run locally as well https://github.com/deeeed/expo-audio-stream/tree/docupdate

Currently there is a switch that enabled / disable the hack which is :

import { useToast } from '@siteed/design-system'
import { useCallback, useEffect, useState } from 'react'
import { Platform } from 'react-native'

import { baseLogger } from '../config'

const logger = baseLogger.extend('useReanimatedWebHack')

export function useReanimatedWebHack() {
    const [isHackEnabled, setIsHackEnabled] = useState(false)
    const { show } = useToast()

    useEffect(() => {
        if (Platform.OS === 'web') {
            // Initialize state based on existing global._WORKLET
            const initialValue = !!global._WORKLET
            logger.log('initialValue', initialValue)
            setIsHackEnabled(initialValue)
        }
    }, [])

    const handleHackToggle = useCallback((value: boolean) => {
        logger.log('handleHackToggle', value)

        if (Platform.OS === 'web') {
            setIsHackEnabled(value)
            if (value) {
                global._WORKLET = false
                // @ts-expect-error
                global._log = console.log
                // @ts-expect-error
                global._getAnimationTimestamp = () => performance.now()
                show({
                    type: 'success',
                    iconVisible: true,
                    message: 'Reanimated Web Hack Enabled',
                })
            } else {
                delete global._WORKLET
                // @ts-expect-error
                delete global._log
                // @ts-expect-error
                delete global._getAnimationTimestamp
                show({
                    type: 'warning',
                    iconVisible: true,
                    message: 'Reanimated Web Hack Disabled',
                })
            }
        }
    }, [])

    return {
        isHackEnabled,
        handleHackToggle,
    }
}

image

To see the issue, just go to the main page and start recording, without the hack you will get the error:
image

This deployed page runs with "react-native-reanimated": "3.17.0-nightly-20241204-5ffa47792",

@github-actions github-actions bot added Repro provided A reproduction with a snippet of code, snack or repo is provided and removed Missing repro This issue need minimum repro scenario labels Dec 5, 2024
@harshit-khandelwal-pi
Copy link

harshit-khandelwal-pi commented Dec 24, 2024

I was able to drill down the issue to this piece of code in metro.config.js

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

config.resolver.assetExts.push("wasm");

config.transformer = {
  ...config.transformer,
  getTransformOptions: async () => ({
    transform: {
      experimentalImportSupport: false,
      inlineRequires: true,
    },
  }),
};

module.exports = config;

This code is added to support canvaskit.wasm for web.

@github-actions github-actions bot added Missing repro This issue need minimum repro scenario and removed Repro provided A reproduction with a snippet of code, snack or repo is provided labels Dec 24, 2024
Copy link

Hey! 👋

The issue doesn't seem to contain a minimal reproduction.

Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?

@hirbod
Copy link
Contributor

hirbod commented Dec 26, 2024

We also have

  transform: {
    experimentalImportSupport: true,
    inlineRequires: true,
  },

in our config (+ lazyImports:true + disableImportExportTransform: true in our babel config)
Maybe related, not sure!

@hirbod
Copy link
Contributor

hirbod commented Dec 26, 2024

@tjzel here another one. Seems to be related. #6839

Also CC @byCedric

@SMBCheeky
Copy link

Any updates? :)

@tlow92
Copy link

tlow92 commented Jan 23, 2025

@SMBCheeky Have you tried my reply here? Was working for me in this case.

@SMBCheeky
Copy link

SMBCheeky commented Jan 23, 2025

I was interested if anyone found a fix for the library to work on both web and native, as I will surely need it in a couple of weeks. Since the project is universal, i cannot use different versions :)

I managed to make the error disappear by commenting out inlineRequires (or set to false), but then i wanted to console log a shared value and i got another error. Then I used the code mentioned above as a hack, and I was not getting the error nor the logs and Reanimated doesn't work.

Take what I said with a grain of salt because Reanimated has not worked for me in the past week on web, and I'm not sure if i'm also doing something on my side to contribute to it. It's a new universal project with sdk 52 and it may still have some issues :)

@tlow92
Copy link

tlow92 commented Jan 23, 2025

@SMBCheeky I am using these versions and universal works fine for me.

"react-native-reanimated": "3.16.1",
"expo": "52.0.14"

I suggest using fresh starter project expo52 + reanimated and add your major changes first. Piece by piece (e.g. metro.config.js) to see what change in your codebase makes it fail.

@SMBCheeky
Copy link

SMBCheeky commented Jan 23, 2025 via email

@SMBCheeky
Copy link

SMBCheeky commented Jan 24, 2025

I implemented the functionality for a feature with const scale = useRef(new Animated.Value(DEFAULT_CANVAS_SCALE)).current; instead of useSharedValue, as I wanted to make sure I also continue my work :)

After I replaced everything at the end,
Image
... the shared values do not want to update their values.

I wrapped the metro.config.js with the recommended wrapper function, I added the babel plugin, I wrote the reanimated babel plugin and set it at the end.... Pretty sure expo does all of this already, but I tried...

I then lowered expo to 52.0.14 and reanimated to 3.16.1, cleaned, nothing.

I set up a new project, but it was too much of a hassle to not get latest library versions ... expo-doctor is crippling us with "the only way forward is up" approach :) I copied over a scale transform.. nothing.

my-app.zip If anyone wants to check out the code.

:(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Missing repro This issue need minimum repro scenario Platform: Android This issue is specific to Android Platform: iOS This issue is specific to iOS Platform: Web This issue is specific to web
Projects
None yet
Development

No branches or pull requests

10 participants