Watching files for changes on Vagrant, file modifi

2019-05-21 06:54发布

问题:

We're trying out Vagrant. We have a web application directory on the host shared with the guest via NFS. While developing the website we quickly started to hit issues.

We are running gulp-watch to spot changes to stylesheet and javascript files and run tasks, but changes were not being picked up for up to one minute.

Also, Laravel was not noticing that blade templates were being changed, and so was not recompiling them and the old view templates were being shown.

I eventually boiled down the problem to a very short PHP script to demonstrate the error.

<?php
header('Content-Type: text/plain');
$file = 'test.html';

echo "modified: " . date('r', filemtime($file)) . "\n";
echo "contents: " . file_get_contents($file) . "\n";

This gets the modification time of another file test.html and also outputs its contents. This gave strange behaviour. When changing test.html (incrementing its full contents, a single integer) via the host and then refreshing the page, either it would work as expected (new file modification date, and the new file contents) or the contents of the file would update but the file modification date would not. On hitting refresh the modification date would then catch up. Here's an example of the latter case.

I later found that if the "modified" and "contents" lines were switched around so that the contents were retrieved before looking at the modification date, I would get the expected output every time.

The question was what was causing this and how we could get around it, and was it linked to the issues with watching files for changes?

回答1:

They are indeed linked. It appears to be to do with NFS caching details about files.

With gulp-watch running, we could edit a file from the host which was being watched by the guest, and it would not be noticed. But then as soon as the file was accessed by the guest (for instance with cat file.less) the gulp-watch process would see the updated modification date and run its tasks.

The solution in the end was to give Vagrant a hint to mount the NFS share with the lookupcache=none option.

To do this, a line in our Vagrantfile changed from

config.vm.synced_folder "./", "/vagrant", type: "nfs"

to

config.vm.synced_folder "./", "/vagrant", type: "nfs", mount_options: ["lookupcache=none"]

Changes are now picked up immediately.