Closed br1985 closed 5 years ago
Version 0.11.* and below used polling on Linux by default, so setting usePolling: true
to fix it now is basically equivalent.
Which editor are you using to modify your files? Very similar behavior used to exist when using vim because of its "atomic write" behavior. Perhaps you're using an editor that also does something similar, but following a different pattern than what has already been corrected for in chokidar.
Also, if you add .on('raw', console.log)
to your watcher code, it may help uncover what's happening.
While trying to replicate this issue a moment ago I think I found where's the problem... I realized that I'm trying to monitor a symlink!
Here's my test.js
:
require('chokidar').watch(process.argv[2])
.on("change", function(path) { console.log("CHANGE: " + path); })
.on("raw", console.log);
require('http').createServer().listen(8000);
And here's my test:
mkdir a
touch a/doc.txt
ln -s a b
gedit b/doc.txt &
node test.js b/doc.txt
Now, I make some changes with gedit
and here's the output:
change doc.txt { watchedPath: 'b/doc.txt' }
rename doc.txt { watchedPath: 'b/doc.txt' }
rename doc.txt { watchedPath: 'b/doc.txt' }
CHANGE: b/doc.txt
And that's it. Only the first change is detected, subsequent ones are completely ignored.
Should symlinks be supported?
Yes. I think gedit
was actually the most relevant piece of information. Need to look at its save patterns.
Can you try with another editor like - like vim, emacs or sublime for instance.
Actually it would also help if you watch the directory instead of the file directly. If you really only care about the one file you can use a glob pattern like b/[d]oc.txt
to get the benefit of the dir-level watcher, which is probably where the subsequent events are landing.
I've just tried mcedit
, vim
, phpstorm
and netbeans
. With phpstorm
I've got identical issue. The rest works just fine.
Actually, I've got here trying to solve my issue with aglio
(https://github.com/danielgtaylor/aglio). I've already hacked it with usePolling
- it's fine for me.
Yep, polling will work, but it's not the preferable solution.
When using fs.watch
to watch a single file (and atomic: true
) I may change it to just always watch the directory also to catch the events in a situation like this.
Hello. Just to confirm this bug on ubuntu 14.04. Using JetBrains WebStorm (Java IDE). in mcedit everything works fine.
A workaround not mentioned yet in this thread is to use a glob pattern which watches that one file, the effect of which is to force directory-level watching where the events sometimes land.
So instead of watching file.txt
, set it to watch [f]ile.txt
.
Would appreciate feedback from anyone for whom this workaround does not work, as the fix in chokidar will likely apply a similar method.
Thanks for the workaround. I was having this issue with Visual Studio 2013/15 on win 7, where I would only get the first change event.
The [f]ile.txt
does work. However, it will now take a while for first events to dispatch (approx 10sec.).
Let us know if that still happens with the latest chokidar.
it does still happen with 1.6.0 (at least if gulp’s APIdocs are still right and it gulp 4.0 still uses chokidar behind the scenes)
to fix it, we’d have to either
@flying-sheep: Run npm ls | grep 'chokidar'
and paste the output here
as said: 1.6.0: │ ├─┬ chokidar@1.6.0
with grep -B 20
:
├─┬ browser-sync@2.17.0
│ ├─┬ browser-sync-client@2.4.2
│ │ ├── etag@1.7.0
│ │ └── fresh@0.3.0
│ ├─┬ browser-sync-ui@0.6.1
│ │ ├── async-each-series@0.1.1
│ │ ├── connect-history-api-fallback@1.3.0
│ │ ├─┬ stream-throttle@0.1.3
│ │ │ └── limiter@1.1.0
│ │ └─┬ weinre@2.0.0-pre-I0Z7U9OV
│ │ ├─┬ express@2.5.11
│ │ │ ├─┬ connect@1.9.2
│ │ │ │ └── formidable@1.0.17
│ │ │ ├── mime@1.2.4
│ │ │ ├── mkdirp@0.3.0
│ │ │ └── qs@0.4.2
│ │ ├── nopt@3.0.6
│ │ └── underscore@1.7.0
│ ├── bs-recipes@1.2.3
│ ├─┬ chokidar@1.6.0
I'm also still seeing this issue with chokidar 1.6.1
(which is a dependency of nodemon 1.10.2
). I'm also using arch linux and vim. When I save with another program (Libre Office in my case), the watcher work as expected. But when trying to save multiple times with vim, only the first change event is triggered.
The workaround (ie. using glob patterns or polling) still works. Neither is ideal though.
Using Ubuntu and Vim here, and chokidar 1.6.1
. Only using single-operation tools like echo > file
allowed me to change the file without screwing up the single-file watch.
I was able to workaround this by re-watching the file when it's renamed. It's also not ideal, but might be useful when avoiding dir-level handlers is desired.
const startWatching = (watcher, file) => {
debug('Loading ' + file);
reloadFile(file)
.catch(console.error)
.then(() => {
watcher.unwatch(file);
watcher.add(file);
})
;
};
let calledOnce = false;
const watcher = chokidar.watch([], {persistent: true})
.on('change', reloadFile)
.on('raw', (type, filename, details) => {
// trigger only once on a rename, then wait for a moment to re-attach.
if( type === 'rename' && !calledOnce ) {
console.warn(filename + ' rename event caught. Avoid editing the file with an editor. Re-initializing chokidar watcher...');
calledOnce = true;
// wait for edits to be complete, then reload the file.
setTimeout(() => {
calledOnce = false;
startWatching(watcher, details.watchedPath);
}, 500);
}
})
;
startWatching(watcher, '/file');
Same issue here, with ubuntu 17.04 and parcel-bundler (which rely on chokidar for hot reloading). Switching to polling mode with CHOKIDAR_USEPOLLING
environment variable do the trick ...
Please open the issue again.
@paulmillr @es128 Issue still happening in Manjaro (Arch) Linux using latest Neovim. Problem does not happen when globbing, however the advice given in https://github.com/paulmillr/chokidar/issues/237#issuecomment-92803815 about wraping the first letter of file in square brackets leads to error from within chokidar's dependencies.
Please re-open as of 09/2018
This is probably caused by fs.watch
on Linux using inotify which listens for inodes rather then file names. Most editors have a 'save to tmp and replace' strategy to make sure that you dont lose any files when e.g. your disk space is full. The problem is that this creates a new file with a new inode.
On linux chokidar should probably listen for a rename event on the filename. As a proof of concept, save below script as test.js
then if you run node test.js
it will print CHANGED
only once but if you run node test.js 1
it will print CHANGED
twice
const fs = require('fs')
const file = 'tmp.file.tmp'
let watcher
const watch = (file, rewatchOnRename) => {
try {
watcher = fs.watch(file, {
persistent: true
}, (e, f) => {
if (e === 'change') {
console.log('CHANGED')
} else if (rewatchOnRename && e === 'rename') {
watcher.close()
watch(file, rewatchOnRename)
}
})
} catch(e) {
if (e.code === 'ENOENT' && e.path === file) {
setTimeout(() => watch(file, rewatchOnRename), 1)
} else {
console.error(e)
}
}
}
function touch(file) {
if (fs.existsSync(file)) {
fs.unlinkSync(file)
}
fs.writeFileSync(file, '')
}
touch(file) // create the file
watch(file, !!process.argv[2])
setTimeout(() => touch(file), 1)
setTimeout(() => touch(file), 1000)
setTimeout(() => {
watcher.close()
fs.unlinkSync(file)
}, 2000)
So instead of watching
file.txt
, set it to watch[f]ile.txt
.Would appreciate feedback from anyone for whom this workaround does not work, as the fix in chokidar will likely apply a similar method.
I tested this and I prefer solution with @(file.txt)
. And it works for me.
I think I fixed this in #791.
A workaround not mentioned yet in this thread is to use a glob pattern which watches that one file, the effect of which is to force directory-level watching where the events sometimes land.
So instead of watching
file.txt
, set it to watch[f]ile.txt
.Would appreciate feedback from anyone for whom this workaround does not work, as the fix in chokidar will likely apply a similar method.
Hello!
@es128 Does not work for me on Windows with Git Bash: it never triggers using this trick.
Here is the (original) script in package.json
:
"watch-css": "nodemon -e css -w icomoon/style.css -w css/style.css -x \"npm run concat-css\"",
I tried the []
trick on the first letter of the folder, then on the first letter of the file. I also tried both single quote and double quote. In these 4 scenarii, there is not a single trigger.
Before trying the []
hack, I got the "triggered only after the first change of the file" bug that @mikehenrty described in the nodemon
repo.
I couldn't get the @()
trick of @mitar to work either.
I am using the latest version of nodemon
which seems to be using version 2.1.5
of chokidar
.
Then I tried to install the latest version (3.0.0
) of chokidar
, but it gets worse: it does not trigger even once :-/ Maybe it's because I'm a n00b and I should not manually install a newer version than the one intended by nodemon
. But still, at least you know everything I tried.
Thanks for any input in this matter!
Best,
This is still present (chokidar 3.0.2) when using Ubuntu 19.04 in WSL on Windows 10 alongside neovim. Fairly esoteric use case I know but just thought I'd mention it as I saw this had been closed.
The usePolling
options works. I haven't tested the globbing pattern approach as in my scenario I don't know how to do that just yet hehe.
Encountered this on Debian 11, with chokidar 3.3.0, npm 6.13.1, and node 10.17.0.
A code that reproduces this would be great.
It's basically the same as the original example.
const chokidar = require('chokidar');
chokidar.watch('./test.txt', {
usePolling: false
}).on('change', (event, path) => {
console.log('changed');
});
My first save to test.txt
was picked up by chokidar
, but not later ones. Setting usePolling
to true fixes the issue, as others reported.
Which code editor do you use?
Neovim 0.3.8; I tried nano
as well, and the behavior is the same.
Surprisingly, touch 0 > test.txt
triggers change
every time.
I'm having the same issue when using Vim and chokidar-cli. The first time the file is saved, the watch fires. Subsequent saves do nothing. The app is running in docker, with the app directory mounted. Setting polling to true works.
Here on FreeBSD 12.1, using gulp.watch
fires once when writing to a file with neovim.
If I then rm
ove and touch
the file, gulp.watch
doesn't fire.
But if I restart the watcher, and rm
ove and touch the file, it's fired on every change.
If I write to the file with nvim, fires once and stops until I restart.
When I add usePolling: true
to gulp.watch
(which is passed to chokidar as per the docs), it works as it should, firing on every edit (and :w
) from nvim.
BTW, I'm using Yarn 1.22.4, Node 13.10.1 and Gulp 4.0.2.
$ yarn list | grep chokidar
│ ├─ chokidar@^2.0.4
├─ chokidar@2.1.8
│ ├─ chokidar@^2.0.0
I believe Gulp's version is 2.1.8.
You should update to chokidar 3.
I see, didn't checked if chokidar had newer versions. Sorry. Anyway, if someone gets here, looks like Gulp can't upgrade chokidar (for now): https://github.com/gulpjs/glob-watcher/issues/49
Just FYI: chokidar is working fine with neovim 0.4.3 chokidar 3.3.0, npm 6.13.1, and node 10.17.0, so I guess it's neovim that's misbehaving in my prior testing.
in case someone still has it today : check if setTimeout works -.- in my case jsdom hooked setTimeout 🙈 and broke it
Here's a very basic example:
After I run this code and start changing watched files I see the events being fired. The problem is that only the first change for each file is reported!
I have this issue with versions 0.12. and 1.0.0-rc. Versions 0.11.* and below seem to work fine.
I'm using Arch Linux with local Btrfs and Ext4 filesystems (tested both). Kernel: 3.18.6-1-ARCH, node: 0.10.36.
With
usePolling
option everything works fine.