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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hot reload refreshes before updating (shows pervious version) #8940

Closed
fredcallaway opened this issue Apr 11, 2023 · 9 comments 路 Fixed by #9026
Closed

Hot reload refreshes before updating (shows pervious version) #8940

fredcallaway opened this issue Apr 11, 2023 · 9 comments 路 Fixed by #9026
Labels
馃悰 Bug HMR Hot Module Reloading

Comments

@fredcallaway
Copy link

fredcallaway commented Apr 11, 2023

馃悰 bug report

Hot reload triggers a browser refresh (or something resembling it), but it reflect the state of the code before the save event. I need to save the file twice to see the correct version.

馃帥 Configuration (.babelrc, package.json, cli command)

// package.json
{
  "name": "graph-nav",
  "version": "1.0.0",
  "description": "Navigation experiments over graphs to characterize hierarchical structure in behavior.",
  "source": "templates/exp.template.html",
  "dependencies": {
    "eslint": "^7.26.0",
    "parcel": "^2.0.0-rc.0"
  },
  "devDependencies": {},
  "scripts": {
    "build": "parcel build --no-scope-hoist --public-url /dist",
    "watch": "parcel watch --public-url /dist --no-cache"
  },
  "engines": {
    "node": "14.x"
  },
}

No babel configuration.

Command:

parcel watch --public-url /dist
@pshbot
Copy link

pshbot commented Apr 26, 2023

Duplicate of #8827 ?

@mischnic
Copy link
Member

@fredcallaway Please share some example code that can be used to reproduce this.

@mischnic mischnic added HMR Hot Module Reloading 馃晲 Waiting labels Apr 26, 2023
@fredcallaway
Copy link
Author

Yes this is the same as #8827

I doubt this is useful, but I see the problem working from this repository: https://github.com/fredcallaway/graph-nav. I unfortunately don't have time to produce a minimal example :\

@mischnic
Copy link
Member

mischnic commented May 7, 2023

A specific commit and instructions on how to trigger this behaviour would also work

@fredcallaway
Copy link
Author

fredcallaway commented May 9, 2023

I'm afraid it's a bit involved, but here it is:

fredcallaway/graph-nav@f4b17ac

Steps to reproduce

Install Python dependencies into a virtualenv:

python3 -m venv env
. env/bin/activate
pip install -r requirements.txt

Install parcel and eslint:

npm install

If you have forego, then you can just do make dev. Otherwise, it's probably easiest to run the following commands in separate terminals:

parcel watch --public-url /dist
env/bin/python bin/herokuapp.py
open http://0.0.0.0:22362/testexperiment

Now you can edit any file to see the behavior. The easiest test is to open static/graph-nav/js/jspsych-CircleGraphNavigationInstruction.js and edit the "Welcome!" message on line 43.


I won't be offended if you don't do all that, but I'd be glad if it was useful :)

If you have any specific ideas about what could be wrong, I'm happy to do some testing myself as well.

@yoshifp
Copy link

yoshifp commented May 18, 2023

Hello @fredcallaway,

I am having a similar issue, but I'm working with proprietary code which I cannot share for reproduction purposes.

Can I ask a couple of questions to confirm your situation?

  1. it looks like from your documentation you are running Heroku for this project, is that correct?
  2. can I assume you are loading the JavaScript files via a web server not via the Parcel development server? As I can see you are using the parcel watch command instead of parcel serve.

This resembles similarities to the application I am working on, where the web server is serving the assets (JavaScript, etc) and I'm using the parcel watch command.

What happens in my situation is:

  1. Start parcel watch
  2. Load the application which loads the assets from the dist directory (ones written to disk, not from a running Parcel development server)
  3. Make changes to my code, watch the browser refresh trigger and watch Parcel build the changes
  4. Browser loads with previous version of the code
  5. Parcel finishes building

I have noticed, that if Parcel finishes building quick enough (<100ms) often these will be written to the dist directory in time and the web server will deliver the updated code. However, a lot of the time a build takes longer (500ms or more) and these are not picked up which results in needing to manually refresh the browser to see the changes.

Note, I have disabled the browser cache (through DevTools) and my web server returns unique URLs for the 'static' files, which includes a hash of the file content, this has helped a lot to reduce the impact of this problem.


I've tracked through the Parcel code and I think I've found the code that triggers the refresh, and possibly why it is happening too early. I don't have time today to dig into this and try to test making changes, I will try to do that tomorrow.

During the "buildProgress" event type in ServerReporter.js, a call is made to hmrServer.emitUpdate(event); which in the end sends a Web Socket message to the browser with the updates.

I expect that if this call is moved into the "buildSuccess" event type handler, it will trigger at the right time after files are written to disk.


I anticipate this wouldn't be a problem if I was using the parcel serve command as I assume the Parcel Development Server just won't provide a response until the updated code finishes building. This is how it worked for me on some previous NodeJS applications (they weren't using Parcel though, but were running a HMR and serving the files through their own Development Server).

@fredcallaway
Copy link
Author

@yoshifp yup sounds like you're experiencing the same thing as me.

it looks like from your documentation you are running Heroku for this project, is that correct?

Yup!

can I assume you are loading the JavaScript files via a web server not via the Parcel development server? As I can see you are using the parcel watch command instead of parcel serve.

Also yup! The server is gunicorn (wrapped by psiturk).

@mischnic
Copy link
Member

This is caused by #8582

Which sends HMR updates to the browser client's websocket before the bundles are written to disk. Because in the common case for e.g. React apps (using module.hot.accept() for hot module reloading), a single asset change doesn't entail a reload. If there is however a reload caused by that HMR update, then the dev server will stall any requests until the build is finished, thus never serving stale bundles from the previous build.

And this is why using something other than the builtin dev server breaks here: it doesn't wait until the build is finished to server to fresh bundles.

@wrapperup
Copy link

wrapperup commented May 19, 2023

I have a pretty unconventional setup where I process .eta templates through as html with parcel. I then run a koa server to render those processed templates (which I use in dev mode as well). Can confirm HMR works well after that change. Hope it gets merged in soon!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
馃悰 Bug HMR Hot Module Reloading
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants