A module used by Jest to create a fast lookup of files in a project
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Real-time file system monitoring for interactive development tools, providing change events and automatic map updates. The watching system supports multiple backends including Watchman, FSEvents, and Node.js fs.watch, with intelligent change detection and batching.
Configure file system watching when creating the haste map.
/**
* Enable file system watching in HasteMap options
*/
interface WatchOptions extends Options {
/** Enable file system watching, defaults to false */
watch?: boolean;
/** Use Watchman for file system monitoring, defaults to true */
useWatchman?: boolean;
/** Whether to throw errors on module name collisions in watch mode, defaults to false */
throwOnModuleCollision?: boolean;
}Subscribe to file system changes through the EventEmitter interface.
/**
* HasteMap extends EventEmitter to provide change notifications
*/
interface IHasteMap extends EventEmitter {
/**
* Subscribe to file system change events
* @param eventType - Event type, currently only 'change' is supported
* @param handler - Function to handle change events
*/
on(eventType: 'change', handler: (event: ChangeEvent) => void): void;
}
/**
* Change event data structure providing access to changed files and updated maps
*/
interface ChangeEvent {
/** Queue of file system events that triggered this change */
eventsQueue: EventsQueue;
/** Updated HasteFS instance with current file system state */
hasteFS: IHasteFS;
/** Updated ModuleMap instance with current module mappings */
moduleMap: IModuleMap;
}
/**
* Queue of individual file system events
*/
interface EventsQueue extends Array<{
/** Absolute path to the changed file */
filePath: string;
/** File statistics, undefined for deleted files */
stat: Stats | undefined;
/** Type of change: 'add', 'change', or 'unlink' */
type: string;
}> {}Methods for managing the watching lifecycle.
/**
* Stop file system watching and cleanup resources
* @returns Promise that resolves when all watchers are closed
*/
end(): Promise<void>;Usage Examples:
import HasteMap from "jest-haste-map";
// Create haste map with watching enabled
const hasteMap = await HasteMap.create({
id: "my-project",
extensions: ["js", "ts", "jsx", "tsx"],
maxWorkers: 4,
platforms: ["ios", "android"],
roots: ["/src"],
retainAllFiles: true,
rootDir: "/project/root",
watch: true, // Enable watching
useWatchman: true, // Prefer Watchman if available
});
// Build initial map
const {hasteFS, moduleMap} = await hasteMap.build();
// Set up change handler
hasteMap.on('change', (event) => {
console.log(`Detected ${event.eventsQueue.length} file system changes:`);
for (const fileEvent of event.eventsQueue) {
console.log(` ${fileEvent.type}: ${fileEvent.filePath}`);
if (fileEvent.stat) {
console.log(` Size: ${fileEvent.stat.size} bytes`);
console.log(` Modified: ${fileEvent.stat.mtime}`);
}
}
// Access updated file system
const updatedFiles = event.hasteFS.getAllFiles();
console.log(`Total files now: ${updatedFiles.length}`);
// Check specific module resolution
const appPath = event.moduleMap.getModule('App');
if (appPath) {
console.log(`App module resolved to: ${appPath}`);
// Get updated dependencies
const appDeps = event.hasteFS.getDependencies(appPath);
console.log(`App dependencies: ${appDeps?.length || 0}`);
}
});
// In a real application, keep the process running
// The change handler will be called whenever files change
console.log("Watching for file changes...");
// Clean up when shutting down
process.on('SIGINT', async () => {
console.log("Shutting down file watcher...");
await hasteMap.end();
process.exit(0);
});The watching system automatically selects the best available backend:
// The backend selection is automatic, but you can control preferences
const hasteMap = await HasteMap.create({
id: "my-project",
extensions: ["js", "ts"],
maxWorkers: 4,
platforms: [],
roots: ["/src"],
retainAllFiles: true,
rootDir: "/project/root",
watch: true,
useWatchman: false, // Disable Watchman, will use FSEvents or NodeWatcher
});The watching system includes intelligent change detection and batching:
// Example of handling batched changes
hasteMap.on('change', (event) => {
const changedFiles = event.eventsQueue.filter(e => e.type === 'change');
const addedFiles = event.eventsQueue.filter(e => e.type === 'add');
const deletedFiles = event.eventsQueue.filter(e => e.type === 'unlink');
console.log(`Batch contains: ${changedFiles.length} changed, ${addedFiles.length} added, ${deletedFiles.length} deleted`);
// Process different types of changes
for (const added of addedFiles) {
console.log(`New file detected: ${added.filePath}`);
// Check if it's a new module
const moduleName = event.hasteFS.getModuleName(added.filePath);
if (moduleName) {
console.log(` New module available: ${moduleName}`);
}
}
for (const deleted of deletedFiles) {
console.log(`File deleted: ${deleted.filePath}`);
// Note: deleted files won't exist in the updated hasteFS
const stillExists = event.hasteFS.exists(deleted.filePath);
console.log(` Still in map: ${stillExists}`); // Should be false
}
});File system watching is particularly useful for development tools:
// Development server integration
class DevServer {
private hasteMap: IHasteMap;
private clients: WebSocket[] = [];
async start() {
this.hasteMap = await HasteMap.create({
id: "dev-server",
extensions: ["js", "ts", "jsx", "tsx", "css", "json"],
maxWorkers: 4,
platforms: [],
roots: ["/src", "/public"],
retainAllFiles: true,
rootDir: process.cwd(),
watch: true,
});
await this.hasteMap.build();
// Watch for changes and notify clients
this.hasteMap.on('change', (event) => {
const changes = event.eventsQueue.map(e => ({
type: e.type,
path: e.filePath,
size: e.stat?.size,
}));
// Notify all connected clients
this.clients.forEach(client => {
client.send(JSON.stringify({
type: 'file-change',
changes,
}));
});
// Rebuild if package.json changed
const packageJsonChanged = event.eventsQueue.some(
e => e.filePath.endsWith('package.json')
);
if (packageJsonChanged) {
console.log('package.json changed, triggering rebuild...');
this.rebuild();
}
});
}
async stop() {
await this.hasteMap.end();
}
private rebuild() {
// Restart the server or rebuild assets
}
}Watch mode automatically handles many error conditions:
// Watch mode error handling
const hasteMap = await HasteMap.create({
id: "my-project",
extensions: ["js", "ts"],
maxWorkers: 4,
platforms: [],
roots: ["/src"],
retainAllFiles: true,
rootDir: "/project/root",
watch: true,
throwOnModuleCollision: false, // Warn instead of throw in watch mode
console: {
// Custom console for handling warnings
log: console.log,
warn: (message) => {
console.warn(`[Haste Warning] ${message}`);
},
error: console.error,
},
});
hasteMap.on('change', (event) => {
// Changes are automatically applied even if some files had errors
console.log('Map updated successfully despite any individual file errors');
});