-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
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
WebpackDevServer: (Only) Ignore node_modules if polling is required #3982
Conversation
What if fsevents failed to install? I imagine chokidar would also switch to polling. |
Good point and it is true, missed that Chokidar falls back to the polling in that case on OSX: https://github.com/paulmillr/chokidar/blob/master/index.js#L89 Not quite sure what the strategy catching that would be. Just checking that |
Yes but you’d need to make sure you’re trying to resolve it from the same folder. So you might need to recursively resolve the package chain. Sounds kinda complicated. |
Also what happens on windows? Does it need polling? |
On Windows Chokidar docs state that
So Windows shouldn't use polling unless forced (which is also the impression I got from a quick dive to The resolving thing does sound kinda complicated, let me try something on that. Thanks for the comments @gaearon 👍 |
@gaearon I did a test of diving into the the cache and confirmed that something like the following does work, tested by first having const watchOptions = {};
// While Create React App does not use polling for watching files by default,
// polling can occur if CHOKIDAR_USEPOLLING environment variable is
// set to a truthy value. Excessive polling can cause CPU overloads
// on some systems (see https://github.com/facebookincubator/create-react-app/issues/293),
// which is why we ignore node_modules if polling is enforced.
let shouldIgnoreNodeModules = false;
const envForceUsePolling = process.env.CHOKIDAR_USEPOLLING;
if (envForceUsePolling) {
const usePollingLower = envForceUsePolling.toLowerCase();
// Chokidar rules https://github.com/paulmillr/chokidar/blob/master/index.js#L99
if (
usePollingLower === 'true' ||
usePollingLower === '1' ||
!!usePollingLower
) {
shouldIgnoreNodeModules = true;
}
}
if (process.platform === "darwin") {
// check if fsevents is loaded
const cacheKeys = Object.keys(require.cache);
const cachedFsEvents = require.cache[cacheKeys.find(i => i.includes("/fsevents/fsevents.js"))];
if (cachedFsEvents && cachedFsEvents.loaded) {
// fsEvents is loaded, check if its WebpackDevServers
let parentIsWebpackDevServer = false;
let parent = cachedFsEvents.parent;
while (parent && !parentIsWebpackDevServer) {
if (parent.id.includes("webpack-dev-server")) {
parentIsWebpackDevServer = true;
}
parent = parent.parent;
}
if (!parentIsWebpackDevServer) {
shouldIgnoreNodeModules = true;
}
} else {
shouldIgnoreNodeModules = true;
}
}
if (shouldIgnoreNodeModules) {
watchOptions.ignored = /node_modules/;
} Not sure if that just |
I don't mind something like this as long as it's hidden in |
Cool 👌 Did some measurements on my machine and rolling the whole check takes ~500000ns on my machine so it shouldn't be a worry (we can double check on that later). I'll move the check to |
Not sure why the tests flaked 🤔 |
@petetnt you need to add the |
Ah, of course. Thanks @viankakrisna |
let parent = cachedFsEvents.parent; | ||
|
||
while (parent && !parentIsWebpackDevServer) { | ||
if (parent.id.includes('webpack-dev-server')) { |
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.
I'm not super happy about this in particular. In the future we'll migrate off WDS. Do we need to hardcode this at all?
Can you explain more about why this check is necessary?
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.
Like mentioned somewhere about, the check is most likely not necessary, but anyway: consider case where ModuleX and WebpackDevServer both load Chokidar, and due to something ModuleX properly loads fsevents
but WDS fails to do so -> WDS polls eventhough it didn't successfully load the module.
That said,
- I don't know if that's even possible 🤔
- Nothing else in the CRA stack currently depends on Chokidar, so the check is currently rather moot anyway.
I am totally okay with removing it if you are 🆗
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.
Is it WDS require-ing fsevents, or webpack? I would assume that webpack should be somewhere on the stack because WDS doesn't (afaik) do any watching manually, it just tells webpack to watch.
I'd be fine to change this line if it referenced just webpack.
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.
Sadly its WDS that requires chokidar
to which the watchOptions
are passed in WDS's own implementation of something similar to watchpack
which eventually requires fsevents
.
Signed-off-by: petetnt <[email protected]>
Signed-off-by: petetnt <[email protected]>
Signed-off-by: petetnt <[email protected]>
Signed-off-by: petetnt <[email protected]>
Signed-off-by: petetnt <[email protected]>
Fixes the most common case of #2956.
This PR changes WebpackDevServer settings to only ignore
node_modules
if the resource intensiveCHOKIDAR_USEPOLLING
environment variable is set. AFAIK using the said environment variable is the only way to end up poll watching, as CRA itself doesn't explicitly setpolling
related options. (edit: wrong, check below)The PR also ignores the special
ignoredFiles
set, as CRA now supports monorepos natively. Instead we ignore allnode_modules
folders with a/node_modules/
RegExp. Removing the special case also removes the tests fromreact-dev-utils
as they were the only related tests to that package.Not sure if we should also have an escape hatch (like
IGNORE_NODE_MODULES_WATCHING
env variable) for cases where native file watching could be too intensive anyway?Also should we warn the users if polling is enable that the node_modules folder is ignored or is the README notice enough?