gilbarbara / react-joyride

Create guided tours in your apps
https://react-joyride.com/
MIT License
6.9k stars 536 forks source link

react-joyride fails to compile (Next.js, webpack) #1072

Open EliasVal opened 2 months ago

EliasVal commented 2 months ago

🐛 Bug Report

When trying to compile a Next.js app using react-joyride (React-rc, ReactDOM-rc, Next.js-canary), the build fails.

To Reproduce

Expected behavior

Normal build

Current behavior

Build fails with the following output:

../../node_modules/.pnpm/react-joyride@2.8.2_@types+react@18.3.4_react-dom@19.0.0-rc-eb3ad065-20240822_react@19.0.0-rc_qpewlespqf4wu6jearwtdzidwq/node_modules/react-joyride/dist/index.mjs
Attempted import error: 'unmountComponentAtNode' is not exported from 'react-dom' (imported as 'ReactDOM').

Import trace for requested module:
../../node_modules/.pnpm/react-joyride@2.8.2_@types+react@18.3.4_react-dom@19.0.0-rc-eb3ad065-20240822_react@19.0.0-rc_qpewlespqf4wu6jearwtdzidwq/node_modules/react-joyride/dist/index.mjs
../../packages/ui/JoyrideComponent.tsx
./app/connected/layout.tsx

../../node_modules/.pnpm/react-joyride@2.8.2_@types+react@18.3.4_react-dom@19.0.0-rc-eb3ad065-20240822_react@19.0.0-rc_qpewlespqf4wu6jearwtdzidwq/node_modules/react-joyride/dist/index.mjs
Attempted import error: 'unstable_renderSubtreeIntoContainer' is not exported from 'react-dom' (imported as 'ReactDOM').

Import trace for requested module:
../../node_modules/.pnpm/react-joyride@2.8.2_@types+react@18.3.4_react-dom@19.0.0-rc-eb3ad065-20240822_react@19.0.0-rc_qpewlespqf4wu6jearwtdzidwq/node_modules/react-joyride/dist/index.mjs
../../packages/ui/JoyrideComponent.tsx
./app/connected/layout.tsx

../../node_modules/.pnpm/react-joyride@2.8.2_@types+react@18.3.4_react-dom@19.0.0-rc-1eaccd82-20240816_react@19.0.0-rc_cwhwwon4ia5c6s37jmb66zmj2i/node_modules/react-joyride/dist/index.mjs
Attempted import error: 'unmountComponentAtNode' is not exported from 'react-dom' (imported as 'ReactDOM').

Import trace for requested module:
../../node_modules/.pnpm/react-joyride@2.8.2_@types+react@18.3.4_react-dom@19.0.0-rc-1eaccd82-20240816_react@19.0.0-rc_cwhwwon4ia5c6s37jmb66zmj2i/node_modules/react-joyride/dist/index.mjs
./app/connected/layout.tsx

../../node_modules/.pnpm/react-joyride@2.8.2_@types+react@18.3.4_react-dom@19.0.0-rc-1eaccd82-20240816_react@19.0.0-rc_cwhwwon4ia5c6s37jmb66zmj2i/node_modules/react-joyride/dist/index.mjs
Attempted import error: 'unstable_renderSubtreeIntoContainer' is not exported from 'react-dom' (imported as 'ReactDOM').
Import trace for requested module:
../../node_modules/.pnpm/react-joyride@2.8.2_@types+react@18.3.4_react-dom@19.0.0-rc-1eaccd82-20240816_react@19.0.0-rc_cwhwwon4ia5c6s37jmb66zmj2i/node_modules/react-joyride/dist/index.mjs
./app/connected/layout.tsx

System Information

System:
    OS: Windows 11 10.0.22631
    CPU: (24) x64 13th Gen Intel(R) Core(TM) i7-13700
    Memory: 36.57 GB / 63.70 GB
  Binaries:
    Node: 20.16.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.22 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 10.2.1 - C:\Program Files\nodejs\npm.CMD
    pnpm: 9.9.0 - ~\AppData\Local\pnpm\pnpm.CMD
    bun: 1.1.0 - ~\.bun\bin\bun.EXE
  npmPackages:
    react-joyride: ^2.8.2 => 2.8.2
EliasVal commented 2 months ago

It seems #1062 would resolve this issue

gilbarbara commented 2 months ago

Yeah, this library isn't compatible with React 19 yet.

EliasVal commented 2 months ago

Any plans/estimations on React 19 compatibility?

islamCodehood commented 2 months ago

Any updates for this?

EliasVal commented 2 months ago

Any updates for this?

It seems like @gilbarbara has other plans before updating this package to support React v19, which I disagree with but hey, I don't maintain nor contribute to this package 😅

But, in my opinion, React v19 should be prioritized since it is nearing release, and versions before 16.3 are being used less and less. One way to keep both parties happy is to do the v19 update and backport any new features @gilbarbara would like the React <16.3 folks to have. But supporting those legacy React versions is pretty pointless.

Anywho, my workaround was to clone and build #1062 and add it as a package in my monorepo. Is it the best way? I don't know. Does it work? sure does!

cjkihl commented 2 months ago

I've published a separate package in the meanwhile. https://www.npmjs.com/package/react-joyride-react-19

npm install react-joyride-react-19 It includes the latest from main and PR https://github.com/gilbarbara/react-joyride/pull/1062

I hope we can find a way moving forward where we can support React 19 and still keep backwards compatibility in the original package.

EliasVal commented 2 months ago

@cjkihl Amazing work! But do you mind updating the package? Thanks in advance :D

kirill2400 commented 2 months ago

@EliasVal You should use "use client" and next/dynamic with ssr: false on "react-joyride"

My working example:

image

then import exported consts as usual

EliasVal commented 2 months ago

@kirill2400 Build still fails when trying your solution.

kirill2400 commented 2 months ago

@EliasVal I have two projects with Next.js 14.2.5 and 14.2.7 with react-joyride 2.9.2 and this code work perfectly

"use client"
import dynamic from "next/dynamic";
import { Locale } from "react-joyride";
import { useEffect, useState } from "react";
import { hintTourSteps } from "@/components/Joyride/TourSteps";

const JoyRide = dynamic(
    () => import("react-joyride"),
    { ssr: false }
)

const locale: Locale =  {
    back: "Назад",
    close: "Закрыть",
    last: "Завершить",
    next: "Далее",
    nextLabelWithProgress: "Далее (Шаг {step} из {steps})",
    open: "Открыть обучение",
    skip: "Пропустить"
}

export const Tour = ({ uid, steps, repeatable }: { uid: string, steps: any, repeatable?: boolean }) => {
    const [ run, setRun ] = useState(false)

    useEffect(() => {
        let timeoutId: NodeJS.Timeout | undefined = undefined;
        if (typeof window != "undefined") {
            const value = localStorage.getItem(uid)
            if (!repeatable && value == "completed") {
                return
            }

            timeoutId = setTimeout(() => {
                setRun(true)
                timeoutId = undefined
            }, 1000)
        }

        return () => timeoutId && clearTimeout(timeoutId)
    }, [])

    return (
        <JoyRide
            steps={steps}
            callback={(e) => {
                if (e.action == "skip" || e.index == steps.length - 1) {
                    localStorage.setItem(uid, "completed")
                } else if (e.action == "next" && e.lifecycle == "ready") {
                    localStorage.setItem(uid, e.index.toString())
                }
            }}
            continuous={true}
            showSkipButton={true}
            disableCloseOnEsc={true}
            disableOverlayClose={true}
            hideCloseButton={true}
            locale={locale}
            run={run}
        />
    )
}

export const ShowWithTour = ({ uid, children }: { uid: string, children: React.ReactNode }) => {
    const [ show, setShow ] = useState(false)

    useEffect(() => {
        if (typeof window != "undefined") {
            const value = localStorage.getItem(uid)
            if (value == "completed") {
                return
            }

            setShow(true)
        }
    }, [])

    return show && children || <></>
}

export const HintTour = () => <Tour uid="hint-tour" steps={hintTourSteps} repeatable={true}/>

I can import or in any place in page and its worked. Can you say your versions?

EliasVal commented 1 month ago

@kirill2400 I'm using Next.js canary (15.0.0-canary) which is probably why I can't get this to work.

cjkihl commented 1 month ago

@cjkihl Amazing work! But do you mind updating the package? Thanks in advance :D

Sure. thank you for the reminder

mngrs commented 1 week ago

Are there any updates? This is currently blocking the migration to Next.js 15, which is a significant issue.

cjkihl commented 1 week ago

Are there any updates? This is currently blocking the migration to Next.js 15, which is a significant issue. @mngrs I published this package in the meanwhile: https://www.npmjs.com/package/react-joyride-react-19

gilbarbara commented 1 week ago

You can try the next version, but breaking changes will occur before the final release.

npm i react-joyride@next