paulmillr / chokidar

Minimal and efficient cross-platform file watching library
https://paulmillr.com
MIT License
11.05k stars 586 forks source link

Chokidar 4.0.1 not responding to add change or unlink events in Bun 1.1.27 #1382

Open ridhwaans opened 4 weeks ago

ridhwaans commented 4 weeks ago

Describe the bug

A clear and concise description of what the bug is.

Versions (please complete the following information):

To Reproduce:

Steps to reproduce the behavior. Include filename and chokidar config.

Ideally prove a problem by isolating and making it reproducible with a very short sample program, which you could paste here:

// apps/server
import { env } from '@project/env';
import { fileWatcher } from '@project/core';

fileWatcher(env.DIR1_PATH, env.DIR2_PATH, env.DIR3_PATH);

const PORT = 3004;
app.listen(PORT, () => {
  console.log(`Listening on http://localhost:${PORT}`);
});

The above is from apps/server and runs via bun --watch run src/index.ts
It uses chokidar wrapper from packages/core below

// packages/core
import chokidar from 'chokidar';

var fileSystem = [] as any;
var ready: any;

const fileWatcher = (dir1Path, dir2Path, dir3Path) => {
  if (new Set([dir1Path, dir2Path, dir3Path]).size != 3) {
    throw 'Each directory must be in a different subdirectory and cannot share the same directory path(s)';
  }

  const watcher = chokidar.watch(
    [dir1Path as string, dir2Path as string, dir3Path as string],
    {
      ignored: /(^|[\/\\])\../, // ignore dotfiles
      persistent: true,
    },
  );

  watcher.on('ready', () => {
    console.log('Initial scan complete. Ready for changes');
    ready = true;
    ready && sync();
  });

  watcher
    .on('add', (path) => {
      console.log(`File ${path} has been added`);
      fileSystem.push(path);
      ready && sync();
    })
    .on('change', (path) => {
      console.log(`File ${path} has been changed`);
    })
    .on('unlink', (path) => {
      console.log(`File ${path} has been removed`);
      fileSystem = fileSystem.filter((e: any) => e !== path);
      ready && sync();
    });

    const sync = async () => {
         fileSystem && (await upsertRow(fileSystem[fileSystem .length - 1]))
         ...
      };
  return watcher;
 }

However, when I add new files, rename existing files or remove existing files from any of the three directories in the chokidar array, it does not initiate the watch events I know because there is no console log when there is filesystem activity

It was working before, not sure when it broke. Havent tested in a while

Most valuable could be one or more test cases for test.js to demonstrate the problem.

Expected behavior when I add new files, rename existing files or remove existing files from any of the three directories in the chokidar array, it should call the add, unlink or change events (watcher.on())

ridhwaans commented 4 weeks ago

Is my ignore pattern wrong? I used it from the docs from the previous version (^3.6.0) However when I removed the ignored property, it starts delisting all previously watched files which is wrong
The three target directories in the chokidar array can have subdirectories. Which means any files added/removed recursively should be picked up by chokidar

ridhwaans commented 4 weeks ago

Reverted to ^3.6.0 but does not work still (on Bun 1.1.27 / bun --watch run )

43081j commented 3 weeks ago

I tried your code locally and cant seem to reproduce it

I'm on Linux fwiw. I copied the code across, and made 3 directories with one existing file in each

I then tried a rename, remove and addition. all 3 triggered the right events for me

it could be OS specific, maybe 🤔

ridhwaans commented 3 weeks ago

@43081j are your directories on a volume mount? In my system I have Ubuntu installed in windows on \\wsl.localhost\Ubuntu, a windows network then, the three directories are on another drive and my chokidar array is [ '/mnt/d/gas', '/mnt/d/solid', '/mnt/d/liquid' ]

The interesting part is that watcher.on('ready' works, but the other ones fail

using bun

43081j commented 3 weeks ago

I've found wsl filesystem events to be very sketchy in general

I used to use a similar setup (code on the windows mount, but running commands in wsl). Native watch would miss a lot of events (without chokidar).

I moved to having my code in wsl and accessing it from windows (i.e the reverse)

You could try throw a script together to fs.watch one of those directories recursively and log the events out. See if node itself even sees them

ridhwaans commented 3 weeks ago

the code is in wsl, sorry if that wasnt clear. i also run within wsl (i think?) in linux terminal

i created a test which targets three folders within ubuntu rather than three directories on windows or an external drive (NTFS). then, chokidar and everything works as expected

in my case i cant change the directories because the ubuntu partition is too small to hold all the data

43081j commented 3 weeks ago

Yes sorry that's what I meant

Within WSL, if you watch a directory on the windows mount, node seems to miss a lot of events

If you can test it using fs.watch directly, you will know if that is true. e.g create an fs watcher with recursive: true and just log any events that fire. If some never turn up, it is what I suspected. If they all trigger as expected, it may be chokidar's problem

ridhwaans commented 2 weeks ago

I recently tried on a mac filesystem (15.1 Sequoia ) . The target directories were on /Volumes/volume/... .

 watcher.on('ready', () => {

The chokidar client would not detect the 'ready' event, and it couldnt be tested. weird.

Edit: mac on mac (app & watch directory)

43081j commented 2 weeks ago

I suspect WSL just isn't very reliable cross filesystem still

I moved all my code to the Linux container for this reason (both rollup and webpack barely triggered in watch mode since the events go missing inside windows)