-
-
Notifications
You must be signed in to change notification settings - Fork 3k
fix: watch mode using chokidar v4 (#5355) #5379
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
base: main
Are you sure you want to change the base?
Conversation
Glob paths are no longer supported by chokidar starting at v4. This update works around this by resolving `watchFiles` and `watchIgnore` to valid paths and creating a list of matchers to determine if the files should be allowed or ignored through the chokidar `ignored` match function. This commit reverts changes from 8af0f1a so that the watched file changes are not fixed to the current directory. Additional note: when a `watchFile` path is removed while chokidar is watching it, recreating the `watchFile` path does not trigger events from chokidar to rerun the tests.
|
Might need to rethink this a bit. Currently, running into some issues:
|
This update fixes mochajs#5355 and refactors the previous watch mode fix attempt. Instead of only filtering the paths in the chokidar `ignored` match function, the chokidar `all` event handler now has a guard to ensure that only file paths that match the allowed patterns from `watchFiles` would trigger test reruns. Doing this solves the issue where creating/deleting directories trigger test reruns despite the watched path being a file (e.g., `**/*.xyz`) as the allowed patterns would not match with just the directory paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes seem reasonable to me at first, but they're not covered by tests at all. I think we'd want to have at least one integration test covering the behavior.
Maybe:
- Programmatically creates a big enough test case project to crash chokidar v4's watch mode
- Starts Mocha in watch mode
- Waits until it logs the expected message (and asserts it doesn't log an
EMFILE
or anything like that) - Closes Mocha
WDYT?
Hi @JoshuaKGoldberg, thanks for the response. Actually, the changes are really only meant for handling glob paths for To recap, since chokidar v4 dropped support for globs, this caused issues where files are not correctly being watched. Before 8af0f1a, the
These are the issues that these changes aim to address which are mostly fixes for the watched files, and I think that the While the Please let me know what you think. Thanks! |
The assorted recent watch mode issues for reference:
If it's easiest to fix >=1 of these all together in one PR (as in, the changed areas of code intersect a lot). I'd say go for it. 🙂 |
The list of issues seem about right to me, where the first 2 are more or less about the watch mode taking some time to start than before and the last being the main issue. I think the changes here now should already address these issues, unless I missed something. Let me know should we need to update a few things or if there's anything to do on my end, thanks! |
Great! Can you add test(s) to verify the changed behavior? #5379 (review) |
- Test for watched files from outside the current working directory - Test reruns with a thousand watched files
Added the following tests:
Though, I'm not too confident with the approach for the last added test. Let me know if we should change how we go about it, thanks. Edit: Well, the last test seems to have failed since it kind of relied on the machine's performance. I'll work on a fix for it and limit the change to a single file. |
Next step here will be ensuring the test failures are nothing new (ref #5361), then I can review the code and if I approve I'll ping Josh to do the same :D |
The test is dependent on how fast the machine could create 1000 watched files, otherwise the test could fail due to a timeout error. Reducing the number of watched files would make the test pass, but doing so would make it more or less similar to already existing tests. At that point, the test does not really test the limits of possibly huge projects with thousands of watched files, so it has been removed instead.
Looks like the test for 1000 watched files is failing due to a timeout error (tests have a timeout of 10000). I tried reducing it to 100 files and while it seems to pass, it does not really test the limits of possibly huge projects with thousands of watched files, so it has been removed instead. Though, the test for watched files outside the current working directory is kept as it is one of the main behaviors that we probably would want to keep in check. |
Going to stress test this one as we saw failures in 5 out of 30 runs on main branch with our
Next steps:
|
This update consolidates the function for retrieving the paths and globs that will be used for the `watchFiles` and `watchIgnore` paths. This should prevent path patterns from being duplicated and should now also handle and watch paths under the provided glob paths. Allowed and ignored file path results are now cached to a map (with a size limit of 1000) to skip re-matching already matched file paths. Additional tests for `watch.spec.js`: - Test file and directory paths under `--watch-files` (no glob pattern) - Test exact file path matches from `--watch-files` - Test `--watch-files` starting and ending with a glob pattern - Test `--watch-files` with a glob pattern in between
Pushed up an update to handle file paths under the provided
Let me know should there be any changes needed or if I missed a thing or two, thanks. Edit: I'm not sure why the netlify deploy preview is failing and how to resolve it. Clicking on it takes me to the netlify page with this permission error:
|
Thanks! You can ignore Netlify, that's the host of mochajs.org, so we only use it for changes to the website, and I think only contributions by trusted contributors will pass the deploy preview. It's not a blocker to approval or merging in any sense :) |
I'll review this tomorrow :) |
Hey @Arnesfield, I've been digging into this one and I can't get over how complex it all feels. Even our current (broken) glob parsing in this file is dozens of lines, it seems we should be using the glob library more directly in some way to handle all of this for us. The Chokidar v4 upgrade docs have this: // other way
import { glob } from 'node:fs/promises';
const watcher = watch(await Array.fromAsync(glob('**/*.js'))); Is something like that not possible for us? If not, why? I'll continue researching, right now I'm looking at how Chokidar v3 handled globs for a reference point. Ultimately, if we do need this complex code, I'm going to ask for a lot of unit tests. Because Chokidar used to handle glob parsing for us, we never stress tested it, at least that's what I'm seeing from our current coverage. |
Looks like Chokidar v3.5.3 accomplished its glob support with |
Hey @mark-wiemer, thanks for the response. Yeah, using What I think makes the chokidar v3 API very much different from the v4 API is that it seems they kind of prefer watching directories (or exact files) and only ignore the other paths via an Personally, I'm alright with any solution that would be better than this as long as the issue gets resolved. There's also the option to downgrade back to chokidar v3 until a major release like mocha 12, but I'll leave the decision up to the team here. |
Hey @Arnesfield, pushed a bit of cleanup and some more docs. Globs are new to me and this is my first big PR on this repo, but I'm happy to approve now :) pinging @mochajs/committers for a second opinion, and of course we'll give you time to review the changes I made to this branch. Thanks for the help, this is a great bugfix and actually a boon to performance! (See #5374 for perf notes) |
Test failures are known issues unrelated to this PR, ref #5361 |
Hi @mark-wiemer, thanks. I looked through the changes and I think I'm fine with them. This is probably just me being subjective and nitpicky, but some things I'd like to point out:
Well, that's just me trying to optimize the little things, hope you don't mind. I am a bit curious about the performance and what causes the ~5-second delay. Not sure when I'll have time to look into that though. Seems interesting nonetheless. On another topic, something is kinda bothering me with the changes I've made. It's a small edge case that I've thought about regarding the directory globs and it's not even really an issue because of how it's written. Right now, if we have a I think the directory patterns to match (if we're using
This way, paths like It's a small thing that doesn't really affect how it's intended to work, since the allowed patterns wouldn't allow I'm probably just looking into it too deeply. Let me know should we want to handle this case too, though it probably works just fine as it is now without going into too much detail. |
Thanks @Arnesfield. Perf is definitely important here but I focused on readability first, hence the change to Regarding adding these functions to Regarding your edge case concern, are you able to write a test case that reproduces this? If the behavior in your PR is significantly different than Mocha 11.2.1 (with Chokidar 3) or our current code (without your changes), it's definitely important to document. With so many users of Mocha, any potential breaking change should be deeply investigated. That said, for the record, Mocha 11.2.2 introduces a behavioral change where |
Looks good, thanks. For the edge case I brought up, the behavior of the watch mode wouldn't change even if it were to be addressed. It only ever applies when the |
@Arnesfield gotcha, so that edge case indicates a potential perf improvement and refactor, not a potential bug in the behavior that anyone using Mocha would see? |
Yeah. Actually, maybe "improvement" isn't the right term and more like handling that edge case makes it more precise instead of being just good enough. Now that I think about it, it's hard to say if there'd be any performance improvements since being more precise with the checks means more patterns to match. Anyway, I only brought it up so I wouldn't be the only one that's aware of it, and it could become something worth looking into in the future if it ever becomes an issue (probably not). For now, I'd say the current checks should be good enough. Let me know should there be anything to do on my end. Thanks! Edit: Meant precise and not concise* |
Thanks @Arnesfield. Just FYI, we're marking this one as semver-major, but Mocha 12 is planned soon (#5357). The likelihood of breaks with this change is just too high. |
Glob paths are no longer supported by chokidar starting at v4.
This update works around this by resolving
watchFiles
andwatchIgnore
to valid paths and creating a list of matchers to determine if the files should be allowed or ignored through the chokidarignored
match function.This commit reverts changes from 8af0f1a so that the watched file changes are not fixed to the current directory.
Additional note: when a
watchFile
path is removed while chokidar is watching it, recreating thewatchFile
path does not trigger events from chokidar to rerun the tests.PR Checklist
status: accepting prs
Overview