Compiler warnings can cause HMR de-optimizations

I’m not sure this is necessarily a bug per se, but I felt compelled to share with the community in case any of you run into something like it in the future.

tl;dr:

  1. Make sure your development server config ignores either the lib directory or the compiler’s intermediate files (.cmi, cmt, etc) in the watch configuration.
  2. Compiler warnings in your codebase can cause unexpected HMR issues.

I went down a very odd rabbit hole with our app recently; whenever a Rescript source file got edited, our devs would get logged out of our app due to a full-page refresh from HMR. This was from an app-specific issue where the state for the user’s token would be reset during that refresh, then an API call would happen without it, resulting in a 401 + logout. We’ve had similar issues with HMR before, and it was usually just that a source was missing an interface.

However, when investigating the incremental compilations using vite --debug hmr and rescript build -w -verbose, I noticed that vite was actually watching the compiler’s intermediate files changing and triggering HMR checks; and seemingly completely unrelated rescript files to the one that was just saved were being marked as modified during incremental compilation, even if they had interfaces!

Another developer on the team astutely noted that all of the ‘unrelated’ files had compiler warnings, which led me to the conclusion that the compiler is updating the file modified time on all compiled files that had warnings on the previous compilation; my assumption is this is so that it can print out all of the compiler warnings again. This triggers the file watching implementation on the development server, and if the compiled file isn’t eligible for HMR, can cause a full-page refresh.

Fixing the few warnings we had promptly resolved this issue.

As an aside, it would be nice if -verbose listed all of the files being incrementally compiled instead of the progress, to debug this.

2 Likes

Can you share a vite.config example to ignore this?
Would be great to include in GitHub - rescript-lang/create-rescript-app: npm create rescript-app@latest

2 Likes