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

Next.js integration #84

Closed
mikestopcontinues opened this issue Jan 29, 2020 · 28 comments
Closed

Next.js integration #84

mikestopcontinues opened this issue Jan 29, 2020 · 28 comments
Assignees
Labels
good first issue Good for newcomers help wanted Extra attention is needed

Comments

@mikestopcontinues
Copy link

mikestopcontinues commented Jan 29, 2020

I've tried a number of locations, and I can't seem to make this work with Next. What's the recommended solution? Thanks!

@vzaidman
Copy link
Collaborator

I got to add it to the next.js examples indeed.

you can add it as an entry in next.config.js:

 webpack: (config, {dev, isServer, defaultLoaders}) => {
.....
    if (dev && !isServer) {
      const originalEntry = config.entry;
      config.entry = async () => {
        const entries = await originalEntry();
        if (entries['main.js'] && !entries['main.js'].includes('./common/whyDidYouRender.js')) {
          entries['main.js'].unshift('./common/whyDidYouRender.js');
        }
        return entries;
      };
    }

where ./common/whyDidYouRender.js looks like this:

import React from 'react';
import whyDidYouRender from '@welldone-software/why-did-you-render';

whyDidYouRender(React);

@vzaidman vzaidman self-assigned this Jan 30, 2020
@vzaidman vzaidman added the good first issue Good for newcomers label Jan 30, 2020
@vzaidman
Copy link
Collaborator

If anybody wants to open a next.js example here:
https://github.com/zeit/next.js/tree/master/examples

please notify me in this ticket.

@motiko
Copy link
Contributor

motiko commented Feb 24, 2020

I've created a PR vercel/next.js#10662

@vzaidman
Copy link
Collaborator

I've created a PR zeit/next.js#10662

beautiful!
when it's merged, you can open a PR with a link to the example added to the readme, so you would become a contributer of this library as well!
Thank you!

@motiko
Copy link
Contributor

motiko commented Feb 28, 2020

Quick update, message from maintainers:

This example is modifying the main entry using custom webpack configuration, let's try to avoid these kind of changes as they may cause unexpected issues, like hydration errors.

Please use a different method or give more information about why does it have to be this way 🙏

You can see my answer here . Hope it is enough and feel free to jump into the conversation if you feel like it @vzaidman 😃

@vzaidman
Copy link
Collaborator

vzaidman commented Mar 6, 2020

here is a working example of integration with next.js.
If for some reason the proposed way doesn't work, you can always try using the more intrusive but reliable way I proposed at the comment above.

@vzaidman vzaidman closed this as completed Mar 6, 2020
@mikestopcontinues
Copy link
Author

With one of the recent Next updates, neither one of these methods work.

@vzaidman config.entry is now a function. Wrapping and resolving the function, then prepending the whyDidYouRender script completely breaks Next.

And @motiko, I'm sorry to say your solution simply doesn't result in any output.

Do either of you have any other ideas?

@francescovenica
Copy link

are these solutions working on the last versions of wdyr and next? I can't get it working...no errore but nothing in console

@mikestopcontinues
Copy link
Author

@francescovenica I still haven't figured it out, and I gave it a good go.

@Vadorequest
Copy link

I'll give it a try. I just stumbled upon WDYU and I think that'd be a great addition to https://github.com/UnlyEd/next-right-now

Maybe I'll add into UnlyEd/next-right-now#42 if I get it to work.

@Vadorequest
Copy link

I've tried to add the following in _app, and while it doesn't seem to create any issue, it doesn't seem to do anything either. I've never used WDYU before so I'm not quite sure what to expect to be printed on the console. Could someone else confirm it does/not work?

if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') {
  // eslint-disable-next-line @typescript-eslint/no-var-requires
  const whyDidYouRender = require('@welldone-software/why-did-you-render');
  // eslint-disable-next-line no-console
  console.debug('Applying whyDidYouRender');
  whyDidYouRender(React);
}

@vzaidman
Copy link
Collaborator

try

if (process.env.NODE_ENV === 'development') {
  if (typeof window !== 'undefined') {
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const whyDidYouRender = require('@welldone-software/why-did-you-render');
    whyDidYouRender(React, {
      trackAllPureComponents: true
    });
  }
}

@Vadorequest
Copy link

Much better, thanks!

Getting this now:

image

So, it seems there are a few useless re-renders (2, at least), but I don't see how those information can help me knowing from what components they came from.

I tried, but can't locate the component that re-renders unnecessarily. Is that the expected behaviour?

@Vadorequest
Copy link

Alright, I also get this and understand a bit more how the logging is meant to work.

image

Basically, it seems to be working fine to me, it's just that the ReactAsyncHighlighter wasn't a component I had expected (it's not one of mine, so the name didn't trigger any bell, unlike Code and CodeBlock)

So, looks like #84 (comment) does the job for Next.js. :)

@vzaidman
Copy link
Collaborator

sadly it seems like issue #114 that i didn't solve yet.

look inside for a workaround (in short it is assigning ReactAsyncHighlighter.whyDidYouRender = false)

@Vadorequest
Copy link

Thanks for the link, I understand the underlying issue, it's unrelated to Next.js.

@francescovenica @mikestopcontinues #84 (comment) should do the trick for your Next.js app. I have it working using Next 9.4.0.

My commit:
https://github.com/UnlyEd/next-right-now/pull/52/commits/b54f416c6626a8de7bba0087e6203d55286be9d8

@nandorojo
Copy link

Just checking in here, does this work if I do it in a Next.js app?

if (process.env.NODE_ENV === 'development') {
  if (typeof window !== 'undefined') {
    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const whyDidYouRender = require('@welldone-software/why-did-you-render');
    whyDidYouRender(React, {
      trackAllPureComponents: true
    });
  }
}

@Vadorequest
Copy link

@nandorojo Here's what I did:
https://github.com/UnlyEd/next-right-now/blob/0174dcc21e36dd356e2be475bfca5339baf27fd3/src/modules/core/wdyr/wdyr.tsx

Imported from _app: https://github.com/UnlyEd/next-right-now/blob/0174dcc21e36dd356e2be475bfca5339baf27fd3/src/pages/_app.tsx#L10

And with a custom CSS style too:
https://github.com/UnlyEd/next-right-now/blob/0174dcc21e36dd356e2be475bfca5339baf27fd3/src/layouts/core/components/Head.tsx#L110-L117

@ivadenis
Copy link

Tried different approaches but wasnt able to make it work with next 12. No console output.

@dwilt
Copy link

dwilt commented Feb 14, 2022

@ivadenis did you try wiping the .next build folder and then re-running the dev server (next dev)?

rm -rf .next; next dev

For me, in our next project, I've noticed that WDYR doesn't enable unless you wipe the build folder

@ktravelet
Copy link

hey all, having issues here too. At the top of of wdyr.tsx I put the following logger, and typeof window is always undefined.

console.log(
  `testing if WDYR.  (typeof window): ${
    typeof window
  }. process.env.NODE_ENV: ${process.env.NODE_ENV}`
);

@hems
Copy link

hems commented Aug 28, 2022

Tried different approaches but wasnt able to make it work with next 12. No console output.

any updates on this?

@apperside
Copy link

There was no way to make it work for me: I added webpack config as suggested by @vzaidman , I ensured that it was loading wdyr.ts file by adding a log, I tried serveral babel tricks, but nothing worked untill I added the following

"jsxImportSource": "@welldone-software/why-did-you-render"

to tsconfig.ts

From that moment onward, it started finally working!

@hems
Copy link

hems commented Dec 15, 2022

Can anybody confirm the example from the README works on Next 12?

Anybody tried it with Next 13 yet?

@rocketana
Copy link

I tried all solutions from this thread, none of them works with Next,js 13.

Importing whyDidYouRender.js script in the root layout did nothing (well, it shouldn't, as it's a server component).

Adding it to the next.config webpack did nothing. I tested that it's added by printing webpack entries to the console, the absolute file path was there. Logging from the file never happened.

Importing it in a top level client component did also nothing. And logging from the script was printed to both, the browser console and the server terminal, it looks like it runs on the server being imported in a client component? (Sounds like I don't understand something, I'm still learning the concepts of Next.js 13 and client/server components). Anyway, it didn't work this way.

I then tried to init whyDidYouRender directly in a top level client component. It then starts to break the app with an error React has detected a change in the order of Hooks caused by HotReload and Router.

   Previous render            Next render
   ------------------------------------------------------
1. useMemo                    useMemo
2. useRef                     useRef
3. useRef                     useRef
4. useEffect                  useEffect
5. useReducer                 useReducer
6. useCallback                useRef
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The problem with hooks order's disappeared sometimes for an unknown reason. A few times I was able to see the reasons for re-render after navigating successfully. But 99/100 times I just get the error about hooks order. With the same code and same actions (I just open a page and try to navigate using next.js links).

It works fine until you try to navigate. I tested adding the following code to the top level client component and a child component. I got the reason as expected for both of them. I passed no options on the init.

    const [objState, setObjState] = useState({ name: 'World' })

    useEffect(() => {
        setObjState({ name: 'World' })
    }, [])

@hems
Copy link

hems commented Jan 23, 2023

I tried all solutions from this thread, none of them works with Next,js 13.

Unfortunately i didn't have time to test it with the new app folder yet, but i created a new issue ( since this one is closed ) asking for help with the new app folder.

You can see the new issue here

I also pointed to an example from the official documentation that hopefully will be helpful in your situation.

@AlbinoGeek
Copy link

AlbinoGeek commented Aug 19, 2023

I can't get this working in NextJS 13 either, even in pages/ as normal.

Also tried everything in this thread, including the jsxImportSource.

Simply put, the import does literally nothing, no changes to output.


src/pages/_app.tsx

import 'wdyr'

// ! Keep this newline, otherwise 'wdyr' gets organized lower in the imports.

import { CacheProvider } from '@emotion/react'
import type { EmotionCache } from '@emotion/utils'
import Box from '@mui/material/Box'
import CssBaseline from '@mui/material/CssBaseline'
import type { Theme } from '@mui/material/styles'

// ...

export default MyApp

src/wdyr.ts

/**
 * WDYR (why-did-you-render) helps locate unnecessary re-renders.
 * Applied in development environment, on the frontend only.
 *
 * It will only log unnecessary re-renders, not expected re-renders.
 *
 * @see https://github.com/welldone-software/why-did-you-render
 * @see https://github.com/vercel/next.js/tree/canary/examples/with-why-did-you-render
 */
import React from 'react'

if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') {
  // eslint-disable-next-line @typescript-eslint/no-var-requires
  const whyDidYouRender = require('@welldone-software/why-did-you-render')

  // eslint-disable-next-line no-console
  console.debug('Applying whyDidYouRender, to help you locate unnecessary re-renders during development. See https://github.com/welldone-software/why-did-you-render')

  // See https://github.com/welldone-software/why-did-you-render#options
  whyDidYouRender(React, {
    trackAllPureComponents: true,
    trackHooks:             true,
    logOwnerReasons:        true,
    collapseGroups:         true,
  })
}

package.json

{
  "name": "none-may-know",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev -p 9000",
    "build": "next build",
    "export": "next export",
    "start": "next start -p 9000",
    "lint": "next lint"
  },
  "dependencies": {
    "@emotion/cache": "^11.11.0",
    "@emotion/react": "^11.11.1",
    "@emotion/server": "^11.11.0",
    "@emotion/styled": "^11.11.0",
    "@emotion/utils": "^1.2.1",
    "@mui/icons-material": "^5.14.1",
    "@mui/lab": "^5.0.0-alpha.139",
    "@mui/material": "^5.14.1",
    "@mui/system": "^5.14.1",
    "next": "^13.4.12",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-use": "^17.4.0",
    "sharp": "^0.32.4",
    "swr": "^2.2.0"
  },
  "devDependencies": {
    "@next/eslint-plugin-next": "^13.4.12",
    "@types/node": "^20.4.4",
    "@types/react": "^18.2.16",
    "@types/react-dom": "^18.2.7",
    "@typescript-eslint/eslint-plugin": "^6.2.0",
    "@typescript-eslint/parser": "^6.2.0",
    "@welldone-software/why-did-you-render": "^7.0.1",
    "eslint": "^8.45.0",
    "eslint-config-next": "^13.4.12",
    "eslint-plugin-react": "^7.33.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "start-server-and-test": "^2.0.0",
    "typescript": "^5.1.6"
  },
  "packageManager": "yarn@3.2.0"
}

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "src",
    "target": "ESNext",
    "lib": ["dom", "dom.iterable", "ESNext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "jsxImportSource": "@welldone-software/why-did-you-render",
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

@YoannBuzenet
Copy link

Can't make it work neither. Did anyone find something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests