remix-run / remix

Build Better Websites. Create modern, resilient user experiences with web fundamentals.
https://remix.run
MIT License
30.11k stars 2.55k forks source link

[Bug]: Live Reload not working. #1601

Closed drewkill32 closed 1 year ago

drewkill32 commented 2 years ago

Which Remix packages are impacted?

What version of Remix are you using?

1.1.3

What version of Node are you using? Minimum supported version is 14.

14.17.4

Steps to Reproduce

  1. starting from the Quickstart template.
  2. create a posts route.
  3. navigate to route
  4. the route does not show up

Every step along the way I have to restart the dev server to see the changes in the web. For example I added


export default function Posts() {
    const posts = useLoaderData();
    console.log('test3');
    return (
        <div>
            <h1>Posts</h1>
        </div>
    );
}

and the console still shows that it reloaded but still shows test2 (the value from when the dev server started)

Navigated to http://10.202.57.104:3000/posts index.tsx:18 test2 posts:23 šŸ’æ File changed: app\routes\posts\index.tsx posts:23 šŸ’æ Rebuilding... posts:23 šŸ’æ Rebuilt in 201ms posts:26 šŸ’æ Reloading window ... Navigated to http://10.202.57.104:3000/posts index.tsx:18 test2

I'm on Windows using Chrome(97.0.4692.71) and Edge(Version 97.0.1072.62), both failed

Expected Behavior

the hot reload should show the changes without having to restart

Actual Behavior

I have to stop the dev server and restart to see any changes

jacob-ebey commented 2 years ago

Check that the component is making it onto your page. If it's not, the first thing to check is what the value of NODE_ENV is when you run. If it's not "development", set it before you start the dev command.

drewkill32 commented 2 years ago

The component is on the page. I just double-checked the NODE_ENV by adding <p>{process.env.NODE_ENV}</p> to the component and restarted the server. It is in development

drewkill32 commented 2 years ago

I still have not found a solution other than it the hot-reloading it working on my Linux machine but refuses to work on Windows.

kurdi-dev commented 2 years ago

I'm also using Windows and I realized hot-reloads only work when I make changes inside the app directory of my Remix project. I don't know if this is how it is supposed to work or it's a bug!

dan-cooke commented 2 years ago

Same issue on MacOS. Nothing makes it work for me, even if i remove the process.env.NODE_ENV check around <LiveReload/>

I have reproduced the issue on 1.1.3 1.1.2 and 1.1.1 so downgrading does not appear to help.

I am using arc sandbox - so this may be affecting it.

Its dropped the Remix DX from a 10/10 down to a 1/10. I've had to put my project on hold until this is fixed. :(

All my components are inside the app directory

adamhp commented 2 years ago

I'm also using Windows and I realized hot-reloads only work when I make changes inside the app directory of my Remix project. I don't know if this is how it is supposed to work or it's a bug!

Interesting observation. I was struggling with this and your point made me realize I currently have all my components in a components/ folder outside of my app/ directory. I just did a brief experiment and moving a component into the app/ directory seems to fix it ā€” i.e. causes changes to reflect on the hot reload live.

As a possible feature, could we provide paths to whatever is watching the filesystem for hot reload?

seyaobey-dev commented 2 years ago

In my case I have all my components inside the ./app folder. But hot-reload is still not work. I am on MacOS

outmost commented 2 years ago

I still have not found a solution other than it the hot-reloading it working on my Linux machine but refuses to work on Windows.

I hit the same problems, then realised that WSL was sat in the middle. Live Reload started working perfectly once I moved my working directory to the Linux filesystem. https://docs.microsoft.com/en-us/windows/wsl/setup/environment#file-storage

nippur72 commented 2 years ago

same problem here on Windows and create-remix, I'm trying to follow the QuickStart tutorial but it doesn't reload šŸ˜¢

Tymek commented 2 years ago

Live Reload started working perfectly once I moved my working directory to the Linux filesystem. https://docs.microsoft.com/en-us/windows/wsl/setup/environment#file-storage

It doesn't seem to work on my end, even though I have project files in \\wsl$\.... It doesn't work in WSL2 or Docker. I don't know if it's related, but I get an error in browser console:

react-dom.development.js:67 Warning: Did not expect server HTML to contain a <script> in <html>.
    at head
    at html
    at http://localhost:3000/build/_shared/chunk-ONGAJZNE.js:20292:45
    at App
    at RemixRoute (http://localhost:3000/build/_shared/chunk-ZOVL2M7D.js:2492:3)
    at Routes2 (http://localhost:3000/build/_shared/chunk-ZOVL2M7D.js:2475:7)
    at Router (http://localhost:3000/build/_shared/chunk-ZOVL2M7D.js:287:15)
    at RemixCatchBoundary (http://localhost:3000/build/_shared/chunk-ZOVL2M7D.js:1022:10)
    at RemixErrorBoundary (http://localhost:3000/build/_shared/chunk-ZOVL2M7D.js:947:5)
    at RemixEntry (http://localhost:3000/build/_shared/chunk-ZOVL2M7D.js:2372:12)
    at RemixBrowser (http://localhost:3000/build/_shared/chunk-ZOVL2M7D.js:3068:27)
    at ClientCacheProvider (http://localhost:3000/build/entry.client-SUATVO3Z.js:30:32)
machour commented 2 years ago

@Tymek the warning is unrelated, check #1077

Tymek commented 2 years ago

Thx.

FIY everybody, if you move to Remix Stack (Blues) there is no issue with hot reloading in WSL2. It is using pm2 server internally for that, AFAIK. That's what I did.

mayank99 commented 2 years ago

Hot reload doesn't work for me on create-remix@1.3.3 with the starter templates. I'm on Windows with WSL2.

I dug a little deeper and found the root cause here: https://github.com/microsoft/WSL/issues/4739

This issue comes up across many tools, and the workaround is often to switch to polling.

Maybe remix should also offer a polling option?

mikestopcontinues commented 2 years ago

I don't mean to +1, but I'm also getting the issue on mac, with a fresh vercel/ts boilerplate.

Devr-pro commented 2 years ago

Same issue with me Am on Windows10 and all setup of remix was good but I then realized that My localhost isnt hotreloading on changes.., I have used this exp {process.env.NODE_ENV === 'development' ? <LiveReload/> : null} ..,But still my issue is persisting.

kiliman commented 2 years ago

They had started removing cross-env NODE_ENV=development from the package.json scripts. Due to the order in which things were occurring, the internal <LiveReload/> component wasn't getting the property environment.

Re-add the cross-env and it should work.

mikestopcontinues commented 2 years ago

@kiliman It doesn't work with or without manually setting NODE_ENV via CLI, .env, or in the config files. NODE_ENV is 'development' without any of them anyway.

BiffBish commented 2 years ago

Any known fixes? Running remix on WSL Ubuntu 20.04

kiliman commented 2 years ago

<LiveReload/> is a simple component. You can simply inline it in your root route.

export const LiveReload =
  process.env.NODE_ENV !== "development"
    ? () => null
    : function LiveReload({
        port = Number(process.env.REMIX_DEV_SERVER_WS_PORT || 8002),
      }: {
        port?: number;
      }) {
        let setupLiveReload = ((port: number) => {
          let protocol = location.protocol === "https:" ? "wss:" : "ws:";
          let host = location.hostname;
          let socketPath = `${protocol}//${host}:${port}/socket`;

          let ws = new WebSocket(socketPath);
          ws.onmessage = (message) => {
            let event = JSON.parse(message.data);
            if (event.type === "LOG") {
              console.log(event.message);
            }
            if (event.type === "RELOAD") {
              console.log("šŸ’æ Reloading window ...");
              window.location.reload();
            }
          };
          ws.onerror = (error) => {
            console.log("Remix dev asset server web socket error:");
            console.error(error);
          };
        }).toString();

        return (
          <script
            suppressHydrationWarning
            dangerouslySetInnerHTML={{
              __html: `(${setupLiveReload})(${JSON.stringify(port)})`,
            }}
          />
        );
      };
BiffBish commented 2 years ago

<LiveReload/> is a simple component. You can simply inline it in your root route.

export const LiveReload =
  process.env.NODE_ENV !== "development"
    ? () => null
    : function LiveReload({
        port = Number(process.env.REMIX_DEV_SERVER_WS_PORT || 8002),
      }: {
        port?: number;
      }) {
        let setupLiveReload = ((port: number) => {
          let protocol = location.protocol === "https:" ? "wss:" : "ws:";
          let host = location.hostname;
          let socketPath = `${protocol}//${host}:${port}/socket`;

          let ws = new WebSocket(socketPath);
          ws.onmessage = (message) => {
            let event = JSON.parse(message.data);
            if (event.type === "LOG") {
              console.log(event.message);
            }
            if (event.type === "RELOAD") {
              console.log("šŸ’æ Reloading window ...");
              window.location.reload();
            }
          };
          ws.onerror = (error) => {
            console.log("Remix dev asset server web socket error:");
            console.error(error);
          };
        }).toString();

        return (
          <script
            suppressHydrationWarning
            dangerouslySetInnerHTML={{
              __html: `(${setupLiveReload})(${JSON.stringify(port)})`,
            }}
          />
        );
      };

This doesn't seem to work? i start up the server and when i make a change to a document and do ctrl+s nothing happens int he console and the page doesn't recompile and build image

nilobarp commented 2 years ago

Had the same issue. Fixed by changing remix.confix.js from:

module.exports = {
  ignoredRouteFiles: [".*"],
};

to:

module.exports = {
  cacheDirectory: "./node_modules/.cache/remix",
  ignoredRouteFiles: [".*", "**/*.css", "**/*.test.{js,jsx,ts,tsx}"],
};
mikestopcontinues commented 2 years ago

@nilobarp That's already in my remix.config.js. Why would it matter either way? My best guess is these "solutions" are all part of an elaborate April fools prank. šŸ˜

kiliman commented 2 years ago

I believe there was a bug in the dev tool in that it wasn't passing the REMIX_DEV_SERVER_WS_PORT variable to the compiler. Have you tried the latest version? Remix now gets a random unused port for the WS port.

nilobarp commented 2 years ago

@mikeybinnswebdesign wish it was a prank. I tried everything mentioned in this thread, the only thing that worked was the change in remix.config.js. I undid the change reload stopped working, bring it back reload works again.

This is too much magic for my brain.

mikestopcontinues commented 2 years ago

@nilobarp @kiliman ā€” Just figured out, for me it was disabling devServerPort which doesn't seem to be working anyway. Thanks!

LukeXF commented 2 years ago

LiveReload does not work for me,

I copied the code that @kiliman shared and added more console logs. The frontend never seems to connect to the WS server and is just constantly pending.

image

No ws.onmessage console.log is ever ran either.

Any suggestions?

kiliman commented 2 years ago

@LukeXF Are you on Mac or Windows?

Did you add/change devServerPort in remix.config?

Also check to see if REMIX_DEV_SERVER_WS_PORT environment variable is defined.

Worst case, just update your dev script to:

"cross-env NODE_ENV=development PORT=3000 REMIX_DEV_SERVER_WS_PORT=8002 remix dev"

Also, try to connect to the web socket server using your browser: http://localhost:8002

You should see the message "Upgrade Required"

machour commented 2 years ago

@drewkill32 is this issue fixed for you ?

drewkill32 commented 2 years ago

Just tried again with the latest from remix. No it hasn't. If I run it on my Linux machine or Linux Subsystem for Windows the hot reload works.

LukeXF commented 2 years ago

I tried adding "cross-env NODE_ENV=development PORT=3000 REMIX_DEV_SERVER_WS_PORT=8002 remix dev" but I get:

Error: remix dev is not supported for custom servers. Because I'm using CF Pages in prod, anyway I removed the custom server: "./server.js" code and I get error: ReferenceError: crypto is not defined

{
  error: ReferenceError: crypto is not defined
  at createKey (/Users/lukebrown/Projects/example/remix/node_modules/@remix-run/cloudflare/crypto.js:35:13)
  at unsign (/Users/lukebrown/Projects/example/remix/node_modules/@remix-run/cloudflare/crypto.js:27:19)
  at decodeCookieValue (/Users/lukebrown/Projects/example/remix/node_modules/@remix-run/server-runtime/cookies.js:87:33)
  at Object.parse (/Users/lukebrown/Projects/example/remix/node_modules/@remix-run/server-runtime/cookies.js:53:66)
  at Object.getSession (/Users/lukebrown/Projects/example/remix/node_modules/@remix-run/server-runtime/sessions/cookieStorage.js:36:67)
  at loader (/Users/lukebrown/Projects/example/remix/app/root.tsx:145:39)
  at Object.callRouteLoader (/Users/lukebrown/Projects/example/remix/node_modules/@remix-run/server-runtime/data.js:77:20)
  at /Users/lukebrown/Projects/example/remix/node_modules/@remix-run/server-runtime/server.js:259:113
  at Array.map (<anonymous>)
  at handleDocumentRequest (/Users/lukebrown/Projects/example/remix/node_modules/@remix-run/server-runtime/server.js:259:67)
}

Then after installing I get: It appears you're using a module that is built in to node, but you installed it as a dependency which could cause problems. Please remove crypto before continuing. very odd! Didn't think I'd need to install crypto.

Anyway, I'm using node v16.13.0 on a Mac M1 Chip

REMIX_DEV_SERVER_WS_PORT is not used, but I have tried it, doesn't change anything, same with devServerPort, not using either at the moment.

http://localhost:8002/ still returns 404

I will investigate further on a clean project!

kiliman commented 2 years ago

http://localhost:8002/ still returns 404

Odd. If the web socket server wasn't running at all, you should have gotten a "can't connect error".

Have you tried rebooting to make sure there isn't some stray process hanging onto that port?

michael-marid commented 2 years ago

If you are using vs code (windows), you could do the following:

  1. Install Remote - WSL extension
  2. Open the green connection button (down-left) to connect to the distro (ex. Ubuntu).
  3. Git clone your project there and use the docker-compose file or run the server.
eran-or commented 2 years ago

Interesting behavior: When I clone the demo with npx create-remix --template remix-run/indie-stack blog-tutorial on my local machine the hot reloading works fine but when I use Gitpod then it's not working. so I guess it is something that relate to this (I'm working with mac 2013, in case it's matter) But when I added a file : app/routes/posts/index.tsx it didn't live reloaded. After playing with this more I see that if I move to the homepage at localhost:3000 and then refresh the live reload on posts is back to work.

ahmed1107 commented 2 years ago

LiveReload does not work for me,

I copied the code that @kiliman shared and added more console logs. The frontend never seems to connect to the WS server and is just constantly pending.

image

No ws.onmessage console.log is ever ran either.

Any suggestions?

Im experiancing the same using windows server

drewkill32 commented 2 years ago

When I create a new project from the indie-stack on a new Windows machine I still don't have hot reloading working. I can only get it to work using WSL

intcreator commented 2 years ago

to clarify the workaround that some other people have suggested, the Remix project needs to be installed in the WSL only portion of the WSL filesystem. it may look like /mnt/c/Users/[username]/projects/my-remix-app is in the WSL filesystem but since it's an abstraction of the Windows filesystem it will not work. however, it should work fine if you set up the project in /home/[username]/my-remix-app for example. the reason this works is the WSL filesystem is able to detect file changes in its own virtualized environment but not in its abstraction of the Windows filesystem

this workaround requires setting up your code editor to point to the WSL files which isn't an option for everyone, so I support an option for polling to be added as a short term solution while WSL itself gets the bug fixed

gonghaibo commented 2 years ago

I don't want to chat here or anything. But I ran into this problem. And I still don't know how to solve it.

So how to solve the macbook pro(m1) 11.6

RATIU5-zz commented 2 years ago

This issue still occurs on Windows with Remix 1.4.1. Creating or deleting files outside of app/routes works fine and live reload does not fail. Creating or deleting any type of file inside the routes folder reloads once then refuses to reload upon any further changes.

amanolar94 commented 2 years ago

<LiveReload/> is a simple component. You can simply inline it in your root route.

export const LiveReload =
  process.env.NODE_ENV !== "development"
    ? () => null
    : function LiveReload({
        port = Number(process.env.REMIX_DEV_SERVER_WS_PORT || 8002),
      }: {
        port?: number;
      }) {
        let setupLiveReload = ((port: number) => {
          let protocol = location.protocol === "https:" ? "wss:" : "ws:";
          let host = location.hostname;
          let socketPath = `${protocol}//${host}:${port}/socket`;

          let ws = new WebSocket(socketPath);
          ws.onmessage = (message) => {
            let event = JSON.parse(message.data);
            if (event.type === "LOG") {
              console.log(event.message);
            }
            if (event.type === "RELOAD") {
              console.log("šŸ’æ Reloading window ...");
              window.location.reload();
            }
          };
          ws.onerror = (error) => {
            console.log("Remix dev asset server web socket error:");
            console.error(error);
          };
        }).toString();

        return (
          <script
            suppressHydrationWarning
            dangerouslySetInnerHTML={{
              __html: `(${setupLiveReload})(${JSON.stringify(port)})`,
            }}
          />
        );
      };

This is the only solution that worked for me

haach commented 2 years ago

Had the same issue. Fixed by changing remix.confix.js from:

module.exports = {
  ignoredRouteFiles: [".*"],
};

to:

module.exports = {
  cacheDirectory: "./node_modules/.cache/remix",
  ignoredRouteFiles: [".*", "**/*.css", "**/*.test.{js,jsx,ts,tsx}"],
};

This worked for me! Thanks @nilobarp After a server restart that reload was hot hot hot šŸ”„

connordear commented 2 years ago

Experienced this on Windows: I was running remix dev through a git bash terminal inside VS Code and it wasn't working.

Switched the integrated terminal to cmd and everything started working great.

ndozhh commented 2 years ago

Had the same issue. Fixed by changing remix.confix.js from:

module.exports = {
  ignoredRouteFiles: [".*"],
};

to:

module.exports = {
  cacheDirectory: "./node_modules/.cache/remix",
  ignoredRouteFiles: [".*", "**/*.css", "**/*.test.{js,jsx,ts,tsx}"],
};

This worked for me! Thanks @nilobarp After a server restart that reload was hot hot hot šŸ”„

This worked for me too!

michaeldebetaz commented 2 years ago

I just updated to 1.5.1 and still am experiencing this issue. Am I the only one? I tried to play with the port (3000, 3001... instead of the deafault 8002), but nothing works.

EDIT: I just ran the jokes app and it works there. I'll investigate what in the Blues Stack is messing with the LiveReload.

EDIT2: I just ran a fresh Blues Stack and it does indeed fails to connect to the websocket. I guess I'll migrate my code to a simple create-remix template.

EDIT3: Moving my code to a fresh simple create-remix template (Remix App Server) did the work! Hot reload is back baby šŸš€

WebSocket connection to 'ws://localhost:3001/socket' failed:

Remix dev asset server web socket error:

Event
 isTrusted: true
 bubbles: false
 cancelBubble: false
 cancelable: false
 composed: false
 currentTarget: WebSocket {url: 'ws://localhost:3001/socket', readyState: 3, bufferedAmount: 0, onopen: null, onerror: ʒ, ā€¦}
 defaultPrevented: false
 eventPhase: 0
 path: []
 returnValue: true
 srcElement: WebSocket {url: 'ws://localhost:3001/socket', readyState: 3, 
 bufferedAmount: 0, onopen: null, onerror: ʒ, ā€¦}
 target: WebSocket {url: 'ws://localhost:3001/socket', readyState: 3, bufferedAmount: 0, onopen: null, onerror: ʒ, ā€¦}
 timeStamp: 2514.599999964237
 type: "error"
tomadimitrie commented 2 years ago

Same issue here, only in Docker it seems not to work Running it on the host works though (M1 Max)

tomadimitrie commented 2 years ago

Managed to fix this: Because the live reload is just a WebSocket, it wasn't by default published in Docker So I provided a fixed port in remix.config.js:

  devServerPort: 3001,

And published the port in my docker-compose.yml:

    ports:
      - "3001:3001"

Hope this helps someone

demirelio commented 2 years ago

Netlify Starter is not hot/live reloading.

The OS doesn't matter. I tried in both macOS and Windows10. It doesn't show any errors on the terminal. The changes on files don't make the browser reload.

kettanaito commented 2 years ago

This looks like a bug in the LiveReload implementation:

https://github.com/remix-run/remix/blob/15213866f8dca94e6164c46028f410625226599f/packages/remix-react/components.tsx#L1367

You cannot reference process in a browser environment, it doesn't exist there. It's either those expressions are meant to be evaluated during the build, or they are simply incorrect.

Screen Shot 2022-06-10 at 15 39 25

Copying a LiveReload into your setup is a bad idea. You'd be de-syncing your Remix setup from what the Remix team recommends (you won't get any fixes to LiveReload, for example). Besides, in the copy version there's still a reference to process, which will fail when run in the browser.

I'm migrating a custom create-remix App to the remix 1.5.1 and encountering this. Somehow, this isn't an issue in the latest create-remix App. I'm trying to find the difference in the setups but it looks identical. I'm also using a custom build to run in the cloud. Something must be off.

kettanaito commented 2 years ago

What fixed the issue for me was setting an explicit port prop on LiveReload:

import { LiveReload } from '@remix-run/react'

export default function App() {
  return (
    <html>
      <body><LiveReload port={8002} /></body>
    </html>
  )
}

It will stop attempting to look up the default value from the process then.

sharuma23 commented 2 years ago

I had this issue on Windows. Some other user here (forgot the name sorry :P) said something about an issue with the WSL filesystem so I made the project in my home directory (~), opened it up with code and then the live reloads and whatever worked just fine. Also just to note, VSCode used the WSL remote thingy like below. image

Edit: added "like below" for clarity

Ali-Parandeh commented 2 years ago

<LiveReload/> is a simple component. You can simply inline it in your root route.

export const LiveReload =
  process.env.NODE_ENV !== "development"
    ? () => null
    : function LiveReload({
        port = Number(process.env.REMIX_DEV_SERVER_WS_PORT || 8002),
      }: {
        port?: number;
      }) {
        let setupLiveReload = ((port: number) => {
          let protocol = location.protocol === "https:" ? "wss:" : "ws:";
          let host = location.hostname;
          let socketPath = `${protocol}//${host}:${port}/socket`;

          let ws = new WebSocket(socketPath);
          ws.onmessage = (message) => {
            let event = JSON.parse(message.data);
            if (event.type === "LOG") {
              console.log(event.message);
            }
            if (event.type === "RELOAD") {
              console.log("šŸ’æ Reloading window ...");
              window.location.reload();
            }
          };
          ws.onerror = (error) => {
            console.log("Remix dev asset server web socket error:");
            console.error(error);
          };
        }).toString();

        return (
          <script
            suppressHydrationWarning
            dangerouslySetInnerHTML={{
              __html: `(${setupLiveReload})(${JSON.stringify(port)})`,
            }}
          />
        );
      };

This solved my problem in Remix AWS stack. I suggest fixing the LiveReload component by copy pasting this inline in your root.tsx and getting rid of LiveReload component import from @remix/remix-run