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

React Native application does not update on many code changes when using vim #1211

Open
antun opened this issue Feb 6, 2024 · 4 comments
Open
Labels

Comments

@antun
Copy link

antun commented Feb 6, 2024

Do you want to request a feature or report a bug?
bug

What is the current behavior?
Newly-created React Native app doesn't reflect every code change during development when using Metro. The behavior is intermittent. Some code changes will be reflected in the app, then some won't be after saving the file. None of the following work to "force" an update:

  • Saving the file repeatedly.
  • Hitting the "r" key to force reload in the Metro terminal window
  • Hitting the "r" key on the emulator to get it to reload.
  • Running with --reset-cache.

It looks minor, but it's really disruptive to development, since when I'm debugging, I can't tell which version of the app is currently being displayed. The only "workaround" I have is to add unique console.log() statements until one of them appears in the terminal that matches what I last wrote.

Usually the first code change is reflected after starting Metro. After that it's totally it or miss. I might get two or three successful updates in a row, and then none for a while.

If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can yarn install and yarn test.

  1. Create a new React Native+metro application by running npx react-native@latest init react_native_update_test
  2. Run in Android with npx react-native run-android. (Although I see the same behavior with iOS.)
  3. Open App.tsx in editor, and make a change (e.g. to some text.) Save the file.
  4. Make more changes, line by line. Change the styles. Try changing the same padding value multiple times - saving each time.

In the attached video, you can see:

  • At 0:07 the text I added wasn't reflected after saving the file.
  • Then at 0:25, I added another sentence, then both the previous sentence and that one appeared.
  • At 0:43, the text "Another change" was not reflected after saving.
  • Then at 1:04 I again added another sentence, saved, and now it updated.
  • At 1:31, the first style change is reflected upon saving.
  • After that, none of the other style changes are shown.
react_native_not_updating.mov

What is the expected behavior?
I presume that the app should update on every code change.

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.
Node v18.19.0
watchman 2023.12.04.00
Mac OS 14.2.1 (23C71)
metro@0.80.5

The metro config is the standard one for a new React Native app:

const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

/**
 * Metro configuration
 * https://facebook.github.io/metro/docs/configuration
 *
 * @type {import('metro-config').MetroConfig}
 */
const config = {};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);

@robhogan
Copy link
Contributor

robhogan commented Feb 6, 2024

Hi @antun - thanks for reporting. Something’s clearly wrong there but it’s hard to tell exactly where, since there are a few steps between a file event being detected and the app rendering updated modules (not all of them in Metro).

Just to clarify, when you hit r you see the client reload (the reloading indicator appears briefly and the state resets?), but the content doesn’t reflect your changes?

Could you possibly run a similar video starting Metro with DEBUG=Metro:* (eg DEBUG=Metro:* yarn start)? That should tell us more about whether file events are reaching Metro from Watchman, and whether the app is requesting updates.

@antun
Copy link
Author

antun commented Feb 6, 2024

Hi @robhogan , thanks for reviewing this so quickly!

Here's an updated video in debug mode:

react_native_not_updating_debug.mov

In this video, only the very first change to code was captured (about 0:22 in the video).

When I hit r, you can see the client reload. (Go to about 1:02 in the video, that's when I hit the reload button.)

Observations:

When a change is captured correctly, and the app updates, this is the output:

  Metro:WatchmanWatcher Handling change to: App.tsx (new: false, exists: true, type: f) +0ms
  Metro:WatchmanWatcher Handling change to: App.tsx~ (new: true, exists: false, type: f) +1ms
  Metro:DeltaCalculator Handling change: /Users/akarlovac/git/nissan/react_native_update_test/App.tsx (type: f) +12m
  Metro:DeltaCalculator Calculating delta (reset: false, shallow: false) +51ms
  Metro:DeltaCalculator Traversing dependencies for 1 paths +0ms
  Metro:DeltaCalculator Calculated graph delta {added: 0, modified: 1, deleted: 0} +55ms

When I save, and nothing happens, this is the output:

  Metro:WatchmanWatcher Received subscription response: metro-file-map-32531--Users-akarlovac-git-nissan-react_native_update_test-fe3d54f5bc828c7ca49865afa3708247 (fresh: false, files: 2, enter: undefined, leave: undefined) +5s
  Metro:WatchmanWatcher Handling change to: App.tsx (new: true, exists: true, type: f) +0ms
  Metro:WatchmanWatcher Handling change to: App.tsx~ (new: true, exists: false, type: f) +1ms
  Metro:DeltaCalculator Handling add: /Users/akarlovac/git/nissan/react_native_update_test/App.tsx (type: f) +5s
  Metro:DeltaCalculator Calculating delta (reset: false, shallow: false) +49ms

I noticed it mentions an App.tsx~ file. I checked with ls -a, but there is no App.tsx~ file - it may be that my editor (vim) creates that temporarily while saving. Not sure if that's relevant.

@antun
Copy link
Author

antun commented Feb 6, 2024

UPDATE

I did a bit more digging and found that with vim (editor) the default behavior is to write the buffer to a new file (I'm guessing this is App.tsx~), delete the original file (App.tsx) and then rename the new file (presumably App.tsx~ -> App.tsx). See this SO post.

If I set set nowritebackup in my .vimrc file, then the app updates on every code change. So I guess vim's save process is confusing Metro.

It sounds like it's not recommended to leave set nowritebackup since there's a risk of losing the file if something goes wrong during the save.

@robhogan
Copy link
Contributor

robhogan commented Feb 6, 2024

Interesting, thanks! It looks like from Metro's perspective Watchman reports a "new file" event for App.tsx, which generally won't trigger a graph update (because the slightly naive assumption is that a new file isn't part of an existing graph, so there's no way it can change the graph).

If Watchman sees the file as new it's odd that there's no prior, corresponding deletion event - Metro would treat delete+add the same as modified. I'll raise this with Watchman folks, but in any case we can change our assumptions here to treat added as possibly-modified, and the vim repro will help us verify, so thanks again. I'll leave this open until we've landed some way to support this editor behaviour.

@robhogan robhogan changed the title React Native application does not update on many code changes React Native application does not update on many code changes when using vim Feb 6, 2024
@robhogan robhogan added the bug label Feb 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants