Skip to content

Commit 694c360

Browse files
committed
feat: replace sane with chokidar
1 parent d393800 commit 694c360

10 files changed

Lines changed: 42 additions & 298 deletions

File tree

.eslintrc.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ module.exports = {
100100
'packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts',
101101
'packages/jest-fake-timers/src/legacyFakeTimers.ts',
102102
'packages/jest-haste-map/src/index.ts',
103-
'packages/jest-haste-map/src/lib/FSEventsWatcher.ts',
104103
'packages/jest-jasmine2/src/jasmine/SpyStrategy.ts',
105104
'packages/jest-jasmine2/src/jasmine/Suite.ts',
106105
'packages/jest-leak-detector/src/index.ts',

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- `[jest-circus]` Fix `testLocation` on Windows when using `test.each` ([#10871](https://github.com/facebook/jest/pull/10871))
2020
- `[jest-console]` `console.dir` now respects the second argument correctly ([#10638](https://github.com/facebook/jest/pull/10638))
2121
- `[jest-environment-jsdom]` Use inner realm’s `ArrayBuffer` constructor ([#10885](https://github.com/facebook/jest/pull/10885))
22+
- `[jest-haste-map]` Replace `sane` with `chokidar` ([#10048](https://github.com/facebook/jest/pull/10048))
2223
- `[jest-jasmine2]` Fixed the issue of beforeAll & afterAll hooks getting executed even if it is inside a skipped `describe` block when it has child `tests` marked as either `only` or `todo` [#10451](https://github.com/facebook/jest/issues/10451)
2324
- `[jest-jasmine2]` Fixed the issues of child `tests` marked with `only` or `todo` getting executed even if it is inside a skipped parent `describe` block [#10451](https://github.com/facebook/jest/issues/10451)
2425
- `[jest-reporter]` Handle empty files when reporting code coverage with V8 ([#10819](https://github.com/facebook/jest/pull/10819))

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@
148148
"@testing-library/dom/pretty-format": "26.6.1",
149149
"@types/jest/jest-diff": "^25.1.0",
150150
"@types/jest/pretty-format": "^25.1.0",
151-
"fbjs-scripts": "patch:fbjs-scripts@^1.1.0#./patches/fbjs-scripts.patch",
152-
"jest-haste-map/fsevents": "patch:fsevents@^2.1.2#./patches/fsevents.patch"
151+
"fbjs-scripts": "patch:fbjs-scripts@^1.1.0#./patches/fbjs-scripts.patch"
153152
}
154153
}

packages/jest-haste-map/package.json

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,23 @@
1818
"@types/graceful-fs": "^4.1.2",
1919
"@types/node": "*",
2020
"anymatch": "^3.0.3",
21+
"chokidar": "^3.4.2",
2122
"fb-watchman": "^2.0.0",
2223
"graceful-fs": "^4.2.4",
2324
"jest-regex-util": "^26.0.0",
2425
"jest-serializer": "^26.6.2",
2526
"jest-util": "^26.6.2",
2627
"jest-worker": "^26.6.2",
27-
"micromatch": "^4.0.2",
28-
"sane": "^4.0.3",
29-
"walker": "^1.0.7"
28+
"micromatch": "^4.0.2"
3029
},
3130
"devDependencies": {
3231
"@jest/test-utils": "^26.6.2",
3332
"@types/anymatch": "^1.3.1",
3433
"@types/fb-watchman": "^2.0.0",
3534
"@types/micromatch": "^4.0.0",
36-
"@types/sane": "^2.0.0",
3735
"jest-snapshot-serializer-raw": "^1.1.0",
3836
"slash": "^3.0.0"
3937
},
40-
"optionalDependencies": {
41-
"fsevents": "^2.1.2"
42-
},
4338
"engines": {
4439
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
4540
},

packages/jest-haste-map/src/__tests__/index.test.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,13 @@ jest.mock('../crawlers/watchman', () =>
7272
const mockWatcherConstructor = jest.fn(root => {
7373
const EventEmitter = require('events').EventEmitter;
7474
mockEmitters[root] = new EventEmitter();
75-
mockEmitters[root].close = jest.fn(callback => callback());
75+
mockEmitters[root].close = jest.fn();
7676
setTimeout(() => mockEmitters[root].emit('ready'), 0);
7777
return mockEmitters[root];
7878
});
7979

80-
jest.mock('sane', () => ({
81-
NodeWatcher: mockWatcherConstructor,
82-
WatchmanWatcher: mockWatcherConstructor,
80+
jest.mock('chokidar', () => ({
81+
watch: jest.fn((patten, opts) => mockWatcherConstructor(opts.cwd)),
8382
}));
8483

8584
jest.mock('../lib/WatchmanWatcher', () => mockWatcherConstructor);

packages/jest-haste-map/src/index.ts

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import {createHash} from 'crypto';
1212
import {EventEmitter} from 'events';
1313
import {tmpdir} from 'os';
1414
import * as path from 'path';
15+
import {FSWatcher as ChokidarFsWatcher, watch as chokidarWatch} from 'chokidar';
1516
import type {Stats} from 'graceful-fs';
16-
import {NodeWatcher, Watcher as SaneWatcher} from 'sane';
1717
import type {Config} from '@jest/types';
1818
import {escapePathForRegex} from 'jest-regex-util';
1919
import serializer from 'jest-serializer';
@@ -24,7 +24,6 @@ import H from './constants';
2424
import nodeCrawl = require('./crawlers/node');
2525
import watchmanCrawl = require('./crawlers/watchman');
2626
import getMockName from './getMockName';
27-
import FSEventsWatcher = require('./lib/FSEventsWatcher');
2827
// @ts-expect-error: not converted to TypeScript - it's a fork: https://github.com/facebook/jest/pull/5387
2928
import WatchmanWatcher from './lib/WatchmanWatcher';
3029
import * as fastPath from './lib/fast_path';
@@ -97,7 +96,7 @@ type InternalOptions = {
9796
};
9897

9998
type Watcher = {
100-
close(callback: () => void): void;
99+
close(): Promise<void>;
101100
};
102101

103102
type WorkerInterface = {worker: typeof worker; getSha1: typeof getSha1};
@@ -780,14 +779,6 @@ export default class HasteMap extends EventEmitter {
780779
this._options.throwOnModuleCollision = false;
781780
this._options.retainAllFiles = true;
782781

783-
// WatchmanWatcher > FSEventsWatcher > sane.NodeWatcher
784-
const Watcher: SaneWatcher =
785-
canUseWatchman && this._options.useWatchman
786-
? WatchmanWatcher
787-
: FSEventsWatcher.isSupported()
788-
? FSEventsWatcher
789-
: NodeWatcher;
790-
791782
const extensions = this._options.extensions;
792783
const ignorePattern = this._options.ignorePattern;
793784
const rootDir = this._options.rootDir;
@@ -798,12 +789,21 @@ export default class HasteMap extends EventEmitter {
798789
let mustCopy = true;
799790

800791
const createWatcher = (root: Config.Path): Promise<Watcher> => {
801-
// @ts-expect-error: TODO how? "Cannot use 'new' with an expression whose type lacks a call or construct signature."
802-
const watcher = new Watcher(root, {
803-
dot: true,
804-
glob: extensions.map(extension => '**/*.' + extension),
805-
ignored: ignorePattern,
806-
});
792+
const useWatchman = canUseWatchman && this._options.useWatchman;
793+
const patterns = extensions.map(extension => '**/*.' + extension);
794+
// Prefer Watchman over Chokidar
795+
const watcher = useWatchman
796+
? new WatchmanWatcher(root, {
797+
dot: true,
798+
glob: patterns,
799+
ignored: ignorePattern,
800+
})
801+
: chokidarWatch(patterns, {
802+
alwaysStat: true,
803+
cwd: root,
804+
ignoreInitial: true,
805+
ignored: ignorePattern,
806+
});
807807

808808
return new Promise((resolve, reject) => {
809809
const rejectTimeout = setTimeout(
@@ -813,7 +813,14 @@ export default class HasteMap extends EventEmitter {
813813

814814
watcher.once('ready', () => {
815815
clearTimeout(rejectTimeout);
816-
watcher.on('all', onChange);
816+
817+
if (useWatchman) {
818+
watcher.on('all', onChange);
819+
} else {
820+
(watcher as ChokidarFsWatcher).on('all', (type, filePath, stat) => {
821+
onChange(type, filePath, root, stat);
822+
});
823+
}
817824
resolve(watcher);
818825
});
819826
});
@@ -824,10 +831,7 @@ export default class HasteMap extends EventEmitter {
824831
mustCopy = true;
825832
const changeEvent: ChangeEvent = {
826833
eventsQueue,
827-
hasteFS: new HasteFS({
828-
files: hasteMap.files,
829-
rootDir,
830-
}),
834+
hasteFS: new HasteFS({files: hasteMap.files, rootDir}),
831835
moduleMap: new HasteModuleMap({
832836
duplicates: hasteMap.duplicates,
833837
map: hasteMap.map,
@@ -1043,20 +1047,16 @@ export default class HasteMap extends EventEmitter {
10431047
}
10441048
}
10451049

1046-
end(): Promise<void> {
1050+
async end(): Promise<void> {
10471051
// @ts-expect-error: TODO TS cannot decide if `setInterval` and `clearInterval` comes from NodeJS or the DOM
10481052
clearInterval(this._changeInterval);
10491053
if (!this._watchers.length) {
1050-
return Promise.resolve();
1054+
return;
10511055
}
10521056

1053-
return Promise.all(
1054-
this._watchers.map(
1055-
watcher => new Promise(resolve => watcher.close(resolve)),
1056-
),
1057-
).then(() => {
1058-
this._watchers = [];
1059-
});
1057+
await Promise.all(this._watchers.map(watcher => watcher.close()));
1058+
1059+
this._watchers = [];
10601060
}
10611061

10621062
/**

packages/jest-haste-map/src/lib/FSEventsWatcher.ts

Lines changed: 0 additions & 192 deletions
This file was deleted.

0 commit comments

Comments
 (0)