Next.js: Document Fast Refresh requirements and troubleshooting

Created on 19 May 2020  路  19Comments  路  Source: vercel/next.js

Bug report

Describe the bug

Fast refresh is not working when using named exports alongside default export.

To Reproduce

  • Setup new next project using next init
  • Go to pages/index.js and remove export default from your function component
export default function Home() {...}
// to
function Home() {...}
  • export something alongside your component as default
// end of the file
let a = 2;
export { a, Home as default};

Expected behavior

Fast refresh should work

System information

  • OS: Linux
  • Browser Chromium latest
  • Version of Next.js: 9.4.1
  • Version of Node.js: 12.16.3
story p2 documentation

Most helpful comment

Can you elaborate why you'd like to do this?

@Timer sure! I'm trying to troubleshoot an error I'm getting on worker in my local dev environment:

Uncaught ReferenceError: $RefreshSig$ is not defined

After some Googling it seems like this is related to React Refresh and I only started seeing this error after upgrading to Next.js 9.4. I should note that there are other people on my team using the same build and not getting this error.

I was just looking for an easy way to turn off Fast Refresh to troubleshoot the issue.

All 19 comments

You may ask why are you exporting something other than your component as default.
Bucklescript exports let bindings by default.

It's expected that Fast Refresh is disabled if you export something that is not a React Component (even a scalar value as shown above). We'll document this in the docs.

Related: #13024

@Timer sorry if this isn't the right place for this question, but is it possible to disable Fast Refresh globally in next.config.js? Thanks!

@thadwoodman it is not possible to disable Fast Refresh. Can you elaborate why you'd like to do this?

I had the very same question and the reason was that full reload is disastrous for us.

But I'm pretty sure that if your code comply with (the currently unclear) guidelines, you will not have full reloads. This leaves you with the same behaviour as hmr (before Fast Refresh was introduced), yet with the benefits of Fast Refresh.

Can you elaborate why you'd like to do this?

@Timer sure! I'm trying to troubleshoot an error I'm getting on worker in my local dev environment:

Uncaught ReferenceError: $RefreshSig$ is not defined

After some Googling it seems like this is related to React Refresh and I only started seeing this error after upgrading to Next.js 9.4. I should note that there are other people on my team using the same build and not getting this error.

I was just looking for an easy way to turn off Fast Refresh to troubleshoot the issue.

@Timer looks like issue persists even when I use downgrade Next.js to 9.3, so probably not an issue with Fast Refresh.

Okay, workaround for reason-react (bucklescript) projects is to make an interface file (.rei or .mli) and annotate your default binding:

let default: Js.t({.}) => React.element;

@Timer I am not sure if I fully understand this: So Fast Refresh will only work if my file only exports a default that is a React component, and that has a function with a name?

So exporting a default that is a React component, plus exporting some other named exports is not allowed? That's essential what a ReasonReact module file would do

// pages/somePage.re

let foo = "hello world";
[@react.component]
let default = () => { <div> </div>};

when transpiled to ES6 will look like this:

// pages/somePage.bs.js

import * as React from "react";

function Foo$default(Props) {
  return React.createElement("div", undefined);
}

var foo = "hello world";

var $$default = Foo$default;

export {
  foo ,
  $$default ,
  $$default as default, 
}

It's expected that Fast Refresh is disabled if you export something that is not a React Component (even a scalar value as shown above). We'll document this in the docs.

How can this be? When using export const getStaticProps it gets exported but it's not a React component either. 馃 Or is it because it's caught by Next.js internals and not actually exported?

Documenting it would be great, I've seen a few setup where people export scalars, like string and such to know whether a page uses SSG or SSR. Doing so would break fast refresh on all pages. 馃槩

I'd like to know the reason of it too. I'm using TypeScript and exporting types in my components and not sure if that triggers a hard refresh? And how about to work with external libraries which export named components not default exports?

@dohomi Exporting TS types won't trigger a hard refresh, because they're stripped from the bundled JS. Also, it's easy to know if a hard refresh is triggered, because the whole page refreshes.

@Vadorequest yes I just look for the reason behind it.. I have over 50 components and searching for the needle which forces a page reload instead of fast-refresh.. it would be great if the log would output the files involved which triggers the reload.

There's no need to find the "needle in the haystack", your components can export things that aren't valid react components as long as at least one component in the parent tree is valid (no additional exports).

@Timer thanks for clarifying this

Seems like it's happening when the page has an exported config I.E {amp: 'hybrid'} too.
@Timer Is this expected behaviour?

Exporting config does seem like a bug. Can you open a new issue @amiralies?

@Timer one quick question about this topic: I handle provider/context usually in one file. Like a default export for the Provider and the useContext hook for the particular context. This would lead into a full reload because its a hook and a component being exported, right? That might be the case for me why I am facing the reload

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jesselee34 picture jesselee34  路  3Comments

formula349 picture formula349  路  3Comments

rauchg picture rauchg  路  3Comments

kenji4569 picture kenji4569  路  3Comments

renatorib picture renatorib  路  3Comments