0
# File System
1
2
Cross-platform file system abstraction with caching, watching, and invalidation support for build operations.
3
4
## Capabilities
5
6
### FileSystem Interface
7
8
Complete file system abstraction with async and sync operations.
9
10
```typescript { .api }
11
/**
12
* Cross-platform file system interface
13
*/
14
interface FileSystem {
15
/** Read file contents as Buffer */
16
readFile(filePath: FilePath): Promise<Buffer>;
17
/** Read file contents as string with encoding */
18
readFile(filePath: FilePath, encoding: Encoding): Promise<string>;
19
/** Read file contents synchronously as Buffer */
20
readFileSync(filePath: FilePath): Buffer;
21
/** Read file contents synchronously as string */
22
readFileSync(filePath: FilePath, encoding: Encoding): string;
23
24
/** Write file contents */
25
writeFile(filePath: FilePath, contents: Buffer | string, options?: ?FileOptions): Promise<void>;
26
/** Copy file from source to destination */
27
copyFile(source: FilePath, destination: FilePath, flags?: number): Promise<void>;
28
29
/** Get file statistics */
30
stat(filePath: FilePath): Promise<Stats>;
31
/** Get file statistics synchronously */
32
statSync(filePath: FilePath): Stats;
33
/** Get file statistics without following symlinks */
34
lstat(filePath: FilePath): Promise<Stats>;
35
/** Get file statistics synchronously without following symlinks */
36
lstatSync(filePath: FilePath): Stats;
37
38
/** Read directory contents */
39
readdir(path: FilePath): Promise<Array<string>>;
40
/** Read directory contents with file types */
41
readdir(path: FilePath, opts: {withFileTypes: true}): Promise<Array<Dirent>>;
42
/** Read directory contents synchronously */
43
readdirSync(path: FilePath): Array<string>;
44
/** Read directory contents synchronously with file types */
45
readdirSync(path: FilePath, opts: {withFileTypes: true}): Array<Dirent>;
46
47
/** Create symbolic link */
48
symlink(target: FilePath, path: FilePath): Promise<void>;
49
/** Delete file */
50
unlink(path: FilePath): Promise<void>;
51
/** Resolve real path of symlink */
52
realpath(path: FilePath): Promise<FilePath>;
53
/** Resolve real path of symlink synchronously */
54
realpathSync(path: FilePath): FilePath;
55
/** Read symbolic link target */
56
readlink(path: FilePath): Promise<FilePath>;
57
/** Read symbolic link target synchronously */
58
readlinkSync(path: FilePath): FilePath;
59
60
/** Check if file or directory exists */
61
exists(path: FilePath): Promise<boolean>;
62
/** Check if file or directory exists synchronously */
63
existsSync(path: FilePath): boolean;
64
65
/** Create directory recursively */
66
mkdirp(path: FilePath): Promise<void>;
67
/** Remove directory and contents recursively */
68
rimraf(path: FilePath): Promise<void>;
69
/** Copy directory recursively */
70
ncp(source: FilePath, destination: FilePath): Promise<void>;
71
72
/** Create readable stream */
73
createReadStream(path: FilePath, options?: ?FileOptions): Readable;
74
/** Create writable stream */
75
createWriteStream(path: FilePath, options?: ?FileOptions): Writable;
76
77
/** Get current working directory */
78
cwd(): FilePath;
79
/** Change current working directory */
80
chdir(dir: FilePath): void;
81
82
/** Watch directory for changes */
83
watch(
84
dir: FilePath,
85
fn: (err: ?Error, events: Array<Event>) => void,
86
opts: WatchOptions
87
): AsyncSubscription;
88
89
/** Get events since last call */
90
getEventsSince(
91
dir: FilePath,
92
snapshot: FilePath,
93
opts: WatchOptions
94
): Promise<Array<Event>>;
95
96
/** Write atomic snapshot of directory state */
97
writeSnapshot(
98
dir: FilePath,
99
snapshot: FilePath,
100
opts: WatchOptions
101
): Promise<void>;
102
103
/** Find first ancestor file matching name */
104
findAncestorFile(
105
filenames: Array<string>,
106
from: FilePath,
107
root: FilePath
108
): Promise<?FilePath>;
109
110
/** Find node_modules package */
111
findNodeModule(moduleName: string, from: FilePath): Promise<?FilePath>;
112
113
/** Find first file matching patterns */
114
findFirstFile(filePaths: Array<FilePath>): Promise<?FilePath>;
115
}
116
```
117
118
### File Statistics
119
120
File system statistics and metadata.
121
122
```typescript { .api }
123
/**
124
* File statistics interface
125
*/
126
interface Stats {
127
/** File size in bytes */
128
size: number;
129
/** Last access time */
130
atime: Date;
131
/** Last modified time */
132
mtime: Date;
133
/** Creation time */
134
ctime: Date;
135
/** Birth time (creation on some systems) */
136
birthtime: Date;
137
/** Device ID */
138
dev: number;
139
/** Inode number */
140
ino: number;
141
/** File mode */
142
mode: number;
143
/** Number of hard links */
144
nlink: number;
145
/** User ID */
146
uid: number;
147
/** Group ID */
148
gid: number;
149
/** Device ID for special files */
150
rdev: number;
151
/** Block size for I/O */
152
blksize: number;
153
/** Number of blocks allocated */
154
blocks: number;
155
156
/** Check if this is a file */
157
isFile(): boolean;
158
/** Check if this is a directory */
159
isDirectory(): boolean;
160
/** Check if this is a symbolic link */
161
isSymbolicLink(): boolean;
162
/** Check if this is a block device */
163
isBlockDevice(): boolean;
164
/** Check if this is a character device */
165
isCharacterDevice(): boolean;
166
/** Check if this is a FIFO */
167
isFIFO(): boolean;
168
/** Check if this is a socket */
169
isSocket(): boolean;
170
}
171
```
172
173
### Directory Entries
174
175
Directory entry information with file types.
176
177
```typescript { .api }
178
/**
179
* Directory entry with file type information
180
*/
181
interface Dirent {
182
/** Entry name */
183
name: string;
184
185
/** Check if this is a file */
186
isFile(): boolean;
187
/** Check if this is a directory */
188
isDirectory(): boolean;
189
/** Check if this is a symbolic link */
190
isSymbolicLink(): boolean;
191
/** Check if this is a block device */
192
isBlockDevice(): boolean;
193
/** Check if this is a character device */
194
isCharacterDevice(): boolean;
195
/** Check if this is a FIFO */
196
isFIFO(): boolean;
197
/** Check if this is a socket */
198
isSocket(): boolean;
199
}
200
```
201
202
### File Options
203
204
Configuration options for file operations.
205
206
```typescript { .api }
207
/**
208
* File operation options
209
*/
210
interface FileOptions {
211
/** File mode permissions */
212
mode?: number;
213
/** File encoding */
214
encoding?: Encoding;
215
/** File flags */
216
flag?: string;
217
}
218
219
/**
220
* Directory reading options
221
*/
222
interface ReaddirOptions {
223
/** Include file type information */
224
withFileTypes?: boolean;
225
/** Encoding for file names */
226
encoding?: Encoding;
227
}
228
229
/**
230
* File encoding types
231
*/
232
type Encoding =
233
| 'ascii'
234
| 'utf8'
235
| 'utf-8'
236
| 'utf16le'
237
| 'ucs2'
238
| 'ucs-2'
239
| 'base64'
240
| 'base64url'
241
| 'latin1'
242
| 'binary'
243
| 'hex';
244
```
245
246
### File Watching
247
248
File system watching and change detection.
249
250
```typescript { .api }
251
/**
252
* File watching options
253
*/
254
interface WatchOptions {
255
/** Ignore patterns */
256
ignore?: Array<FilePath>;
257
/** Include patterns */
258
include?: Array<FilePath>;
259
}
260
261
/**
262
* File system event
263
*/
264
interface Event {
265
/** Event type */
266
type: 'create' | 'update' | 'delete';
267
/** File path that changed */
268
path: FilePath;
269
}
270
271
/**
272
* Async subscription for cleanup
273
*/
274
interface AsyncSubscription {
275
/** Unsubscribe from events */
276
unsubscribe(): Promise<void>;
277
}
278
```
279
280
### Cache Interface
281
282
Build cache abstraction for storing and retrieving build artifacts.
283
284
```typescript { .api }
285
/**
286
* Build cache interface
287
*/
288
interface Cache {
289
/** Ensure cache is ready */
290
ensure(): Promise<void>;
291
292
/** Check if key exists in cache */
293
has(key: string): Promise<boolean>;
294
/** Get cached value */
295
get<T>(key: string): Promise<?T>;
296
/** Set cached value */
297
set(key: string, value: mixed): Promise<void>;
298
299
/** Get cached value as stream */
300
getStream(key: string): Readable;
301
/** Set cached value from stream */
302
setStream(key: string, stream: Readable): Promise<void>;
303
304
/** Get cached blob */
305
getBlob(key: string): Promise<Buffer>;
306
/** Set cached blob */
307
setBlob(key: string, contents: Buffer | string): Promise<void>;
308
309
/** Check if large blob exists */
310
hasLargeBlob(key: string): Promise<boolean>;
311
/** Get large cached blob */
312
getLargeBlob(key: string): Promise<Buffer>;
313
/** Set large cached blob */
314
setLargeBlob(
315
key: string,
316
contents: Buffer | string,
317
options?: {signal?: AbortSignal}
318
): Promise<void>;
319
/** Delete large cached blob */
320
deleteLargeBlob(key: string): Promise<void>;
321
322
/** Get cached buffer (legacy) */
323
getBuffer(key: string): Promise<?Buffer>;
324
325
/** Refresh cache state */
326
refresh(): void;
327
}
328
```
329
330
### File Invalidation
331
332
File change invalidation tracking for cache management.
333
334
```typescript { .api }
335
/**
336
* File creation invalidation types
337
*/
338
type FileCreateInvalidation =
339
| GlobInvalidation
340
| FileInvalidation
341
| FileAboveInvalidation;
342
343
/**
344
* Glob pattern invalidation
345
*/
346
interface GlobInvalidation {
347
type: 'glob';
348
glob: Glob;
349
}
350
351
/**
352
* Specific file invalidation
353
*/
354
interface FileInvalidation {
355
type: 'file';
356
filePath: FilePath;
357
}
358
359
/**
360
* Ancestor file invalidation
361
*/
362
interface FileAboveInvalidation {
363
type: 'file-above';
364
fileName: string;
365
aboveFilePath: FilePath;
366
}
367
```
368
369
**Usage Examples:**
370
371
```typescript
372
import type { FileSystem, Cache, WatchOptions } from '@parcel/types';
373
374
// Basic file operations
375
async function processFiles(fs: FileSystem) {
376
// Read file contents
377
const buffer = await fs.readFile('/path/to/file.js');
378
const text = await fs.readFile('/path/to/file.js', 'utf8');
379
380
// Write processed contents
381
const processed = transformCode(text);
382
await fs.writeFile('/path/to/output.js', processed);
383
384
// Check file existence
385
if (await fs.exists('/path/to/config.json')) {
386
const config = await fs.readFile('/path/to/config.json', 'utf8');
387
console.log('Config:', JSON.parse(config));
388
}
389
390
// Get file statistics
391
const stats = await fs.stat('/path/to/file.js');
392
console.log(`File size: ${stats.size} bytes`);
393
console.log(`Modified: ${stats.mtime}`);
394
}
395
396
// Directory operations
397
async function processDirectory(fs: FileSystem) {
398
// Create directory
399
await fs.mkdirp('/path/to/new/dir');
400
401
// Read directory contents
402
const files = await fs.readdir('/path/to/dir');
403
console.log('Files:', files);
404
405
// Read with file types
406
const entries = await fs.readdir('/path/to/dir', { withFileTypes: true });
407
for (const entry of entries) {
408
if (entry.isFile()) {
409
console.log(`File: ${entry.name}`);
410
} else if (entry.isDirectory()) {
411
console.log(`Directory: ${entry.name}`);
412
}
413
}
414
415
// Copy directory
416
await fs.ncp('/source/dir', '/dest/dir');
417
}
418
419
// File watching
420
async function watchFiles(fs: FileSystem) {
421
const watchOptions: WatchOptions = {
422
ignore: ['node_modules/**', '*.log'],
423
include: ['src/**/*.{js,ts,jsx,tsx}']
424
};
425
426
const subscription = fs.watch('/project/root', (err, events) => {
427
if (err) {
428
console.error('Watch error:', err);
429
return;
430
}
431
432
for (const event of events) {
433
console.log(`${event.type}: ${event.path}`);
434
435
if (event.type === 'create' && event.path.endsWith('.js')) {
436
console.log('New JavaScript file created');
437
}
438
}
439
}, watchOptions);
440
441
// Later: cleanup
442
await subscription.unsubscribe();
443
}
444
445
// Cache operations
446
async function useCache(cache: Cache) {
447
const cacheKey = 'processed-file-hash123';
448
449
// Check if cached
450
if (await cache.has(cacheKey)) {
451
const cached = await cache.get(cacheKey);
452
console.log('Using cached result:', cached);
453
return cached;
454
}
455
456
// Process and cache
457
const result = await expensiveProcessing();
458
await cache.set(cacheKey, result);
459
460
// Cache large blobs
461
const largeBuffer = generateLargeAsset();
462
await cache.setLargeBlob('large-asset-key', largeBuffer);
463
464
return result;
465
}
466
467
// File utilities
468
async function findProjectFiles(fs: FileSystem) {
469
// Find package.json
470
const packageJson = await fs.findAncestorFile(
471
['package.json'],
472
'/project/src/components',
473
'/project'
474
);
475
476
if (packageJson) {
477
console.log('Found package.json at:', packageJson);
478
}
479
480
// Find node_modules package
481
const lodashPath = await fs.findNodeModule('lodash', '/project/src');
482
if (lodashPath) {
483
console.log('Found lodash at:', lodashPath);
484
}
485
486
// Find first existing config file
487
const configFile = await fs.findFirstFile([
488
'/project/.parcelrc',
489
'/project/parcel.config.js',
490
'/project/parcel.config.json'
491
]);
492
493
if (configFile) {
494
console.log('Using config:', configFile);
495
}
496
}
497
```