Skip to content

Commit a2e3261

Browse files
committed
make filesystem types compatible with memfs and normal fs
fixes webpack#12400
1 parent 910f5c1 commit a2e3261

File tree

8 files changed

+135
-29
lines changed

8 files changed

+135
-29
lines changed

lib/Compiler.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,10 @@ ${other}`);
724724
return this.outputFileSystem.readFile(
725725
targetPath,
726726
(err, existingContent) => {
727-
if (err || !content.equals(existingContent)) {
727+
if (
728+
err ||
729+
!content.equals(/** @type {Buffer} */ (existingContent))
730+
) {
728731
return doWrite(content);
729732
} else {
730733
return alreadyWritten();

lib/ContextModuleFactory.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -298,11 +298,13 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
298298
const addDirectory = (directory, addSubDirectory, callback) => {
299299
fs.readdir(directory, (err, files) => {
300300
if (err) return callback(err);
301-
files = files.map(file => file.normalize("NFC"));
302-
files = cmf.hooks.contextModuleFiles.call(files);
303-
if (!files || files.length === 0) return callback(null, []);
301+
const processedFiles = cmf.hooks.contextModuleFiles.call(
302+
/** @type {string[]} */ (files).map(file => file.normalize("NFC"))
303+
);
304+
if (!processedFiles || processedFiles.length === 0)
305+
return callback(null, []);
304306
asyncLib.map(
305-
files.filter(p => p.indexOf(".") !== 0),
307+
processedFiles.filter(p => p.indexOf(".") !== 0),
306308
(segment, callback) => {
307309
const subResource = join(fs, directory, segment);
308310

lib/FileSystemInfo.js

+11-7
Original file line numberDiff line numberDiff line change
@@ -1171,8 +1171,9 @@ class FileSystemInfo {
11711171
callback();
11721172
break;
11731173
}
1174-
this.fs.realpath(path, (err, realPath) => {
1174+
this.fs.realpath(path, (err, _realPath) => {
11751175
if (err) return callback(err);
1176+
const realPath = /** @type {string} */ (_realPath);
11761177
if (realPath !== path) {
11771178
resolveFiles.add(path);
11781179
}
@@ -1192,8 +1193,9 @@ class FileSystemInfo {
11921193
callback();
11931194
break;
11941195
}
1195-
this.fs.realpath(path, (err, realPath) => {
1196+
this.fs.realpath(path, (err, _realPath) => {
11961197
if (err) return callback(err);
1198+
const realPath = /** @type {string} */ (_realPath);
11971199
if (realPath !== path) {
11981200
resolveFiles.add(path);
11991201
}
@@ -2405,7 +2407,7 @@ class FileSystemInfo {
24052407
}
24062408

24072409
_readContextTimestamp(path, callback) {
2408-
this.fs.readdir(path, (err, files) => {
2410+
this.fs.readdir(path, (err, _files) => {
24092411
if (err) {
24102412
if (err.code === "ENOENT") {
24112413
this._contextTimestamps.set(path, null);
@@ -2414,7 +2416,7 @@ class FileSystemInfo {
24142416
}
24152417
return callback(err);
24162418
}
2417-
files = files
2419+
const files = /** @type {string[]} */ (_files)
24182420
.map(file => file.normalize("NFC"))
24192421
.filter(file => !/^\./.test(file))
24202422
.sort();
@@ -2501,15 +2503,15 @@ class FileSystemInfo {
25012503
}
25022504

25032505
_readContextHash(path, callback) {
2504-
this.fs.readdir(path, (err, files) => {
2506+
this.fs.readdir(path, (err, _files) => {
25052507
if (err) {
25062508
if (err.code === "ENOENT") {
25072509
this._contextHashes.set(path, null);
25082510
return callback(null, null);
25092511
}
25102512
return callback(err);
25112513
}
2512-
files = files
2514+
const files = /** @type {string[]} */ (_files)
25132515
.map(file => file.normalize("NFC"))
25142516
.filter(file => !/^\./.test(file))
25152517
.sort();
@@ -2624,7 +2626,9 @@ class FileSystemInfo {
26242626
return callback(err);
26252627
}
26262628
const set = new Set(
2627-
elements.map(element => join(this.fs, path, element))
2629+
/** @type {string[]} */ (elements).map(element =>
2630+
join(this.fs, path, element)
2631+
)
26282632
);
26292633
callback(null, set);
26302634
});

lib/serialization/FileMiddleware.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ class FileMiddleware extends SerializerMiddleware {
441441
reject(err);
442442
return;
443443
}
444-
let remaining = stats.size;
444+
let remaining = /** @type {number} */ (stats.size);
445445
let currentBuffer;
446446
let currentBufferUsed;
447447
const buf = [];

lib/util/fs.js

+48-8
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,57 @@
77

88
const path = require("path");
99

10-
/** @typedef {import("fs").Stats} NodeFsStats */
1110
/** @typedef {import("../../declarations/WebpackOptions").WatchOptions} WatchOptions */
1211
/** @typedef {import("../FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */
1312

13+
/**
14+
* @typedef {Object} IStats
15+
* @property {() => boolean} isFile
16+
* @property {() => boolean} isDirectory
17+
* @property {() => boolean} isBlockDevice
18+
* @property {() => boolean} isCharacterDevice
19+
* @property {() => boolean} isSymbolicLink
20+
* @property {() => boolean} isFIFO
21+
* @property {() => boolean} isSocket
22+
* @property {number | bigint} dev
23+
* @property {number | bigint} ino
24+
* @property {number | bigint} mode
25+
* @property {number | bigint} nlink
26+
* @property {number | bigint} uid
27+
* @property {number | bigint} gid
28+
* @property {number | bigint} rdev
29+
* @property {number | bigint} size
30+
* @property {number | bigint} blksize
31+
* @property {number | bigint} blocks
32+
* @property {number | bigint} atimeMs
33+
* @property {number | bigint} mtimeMs
34+
* @property {number | bigint} ctimeMs
35+
* @property {number | bigint} birthtimeMs
36+
* @property {Date} atime
37+
* @property {Date} mtime
38+
* @property {Date} ctime
39+
* @property {Date} birthtime
40+
*/
41+
42+
/**
43+
* @typedef {Object} IDirent
44+
* @property {() => boolean} isFile
45+
* @property {() => boolean} isDirectory
46+
* @property {() => boolean} isBlockDevice
47+
* @property {() => boolean} isCharacterDevice
48+
* @property {() => boolean} isSymbolicLink
49+
* @property {() => boolean} isFIFO
50+
* @property {() => boolean} isSocket
51+
* @property {string | Buffer} name
52+
*/
53+
1454
/** @typedef {function(NodeJS.ErrnoException=): void} Callback */
1555
/** @typedef {function(NodeJS.ErrnoException=, Buffer=): void} BufferCallback */
1656
/** @typedef {function(NodeJS.ErrnoException=, Buffer|string=): void} BufferOrStringCallback */
17-
/** @typedef {function(NodeJS.ErrnoException=, string[]=): void} StringArrayCallback */
57+
/** @typedef {function(NodeJS.ErrnoException=, (string | Buffer)[] | IDirent[]=): void} DirentArrayCallback */
1858
/** @typedef {function(NodeJS.ErrnoException=, string=): void} StringCallback */
1959
/** @typedef {function(NodeJS.ErrnoException=, number=): void} NumberCallback */
20-
/** @typedef {function(NodeJS.ErrnoException=, NodeFsStats=): void} StatsCallback */
60+
/** @typedef {function(NodeJS.ErrnoException=, IStats=): void} StatsCallback */
2161
/** @typedef {function((NodeJS.ErrnoException | Error)=, any=): void} ReadJsonCallback */
2262

2363
/**
@@ -45,20 +85,20 @@ const path = require("path");
4585
* @property {function(string, Buffer|string, Callback): void} writeFile
4686
* @property {function(string, Callback): void} mkdir
4787
* @property {function(string, StatsCallback): void} stat
48-
* @property {function(string, BufferCallback): void} readFile
88+
* @property {function(string, BufferOrStringCallback): void} readFile
4989
* @property {(function(string, string): string)=} join
5090
* @property {(function(string, string): string)=} relative
5191
* @property {(function(string): string)=} dirname
5292
*/
5393

5494
/**
5595
* @typedef {Object} InputFileSystem
56-
* @property {function(string, BufferCallback): void} readFile
96+
* @property {function(string, BufferOrStringCallback): void} readFile
5797
* @property {(function(string, ReadJsonCallback): void)=} readJson
5898
* @property {function(string, BufferOrStringCallback): void} readlink
59-
* @property {function(string, StringArrayCallback): void} readdir
99+
* @property {function(string, DirentArrayCallback): void} readdir
60100
* @property {function(string, StatsCallback): void} stat
61-
* @property {(function(string, StringCallback): void)=} realpath
101+
* @property {(function(string, BufferOrStringCallback): void)=} realpath
62102
* @property {(function(string=): void)=} purge
63103
* @property {(function(string, string): string)=} join
64104
* @property {(function(string, string): string)=} relative
@@ -73,7 +113,7 @@ const path = require("path");
73113
/**
74114
* @typedef {Object} IntermediateFileSystemExtras
75115
* @property {function(string): void} mkdirSync
76-
* @property {function(string): import("fs").WriteStream} createWriteStream
116+
* @property {function(string): NodeJS.WritableStream} createWriteStream
77117
* @property {function(string, string, NumberCallback): void} open
78118
* @property {function(number, Buffer, number, number, number, NumberCallback): void} read
79119
* @property {function(number, Callback): void} close
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = () => false;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const memfs = require("memfs");
2+
const fs = require("fs");
3+
4+
/** @type {import("../../../../").Configuration} */
5+
module.exports = {
6+
plugins: [
7+
compiler => {
8+
compiler.outputFileSystem = memfs.fs;
9+
compiler.inputFileSystem = memfs.fs;
10+
compiler.intermediateFileSystem = memfs.fs;
11+
12+
compiler.outputFileSystem = fs;
13+
compiler.inputFileSystem = fs;
14+
compiler.intermediateFileSystem = fs;
15+
}
16+
]
17+
};

types.d.ts

+47-8
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ import {
7777
WithStatement,
7878
YieldExpression
7979
} from "estree";
80-
import { Stats as FsStats, WriteStream } from "fs";
8180
import { JSONSchema4, JSONSchema6, JSONSchema7 } from "json-schema";
8281
import { default as ValidationError } from "schema-utils/declarations/ValidationError";
8382
import {
@@ -3765,6 +3764,43 @@ declare class HttpsUriPlugin {
37653764
*/
37663765
apply(compiler: Compiler): void;
37673766
}
3767+
declare interface IDirent {
3768+
isFile: () => boolean;
3769+
isDirectory: () => boolean;
3770+
isBlockDevice: () => boolean;
3771+
isCharacterDevice: () => boolean;
3772+
isSymbolicLink: () => boolean;
3773+
isFIFO: () => boolean;
3774+
isSocket: () => boolean;
3775+
name: string | Buffer;
3776+
}
3777+
declare interface IStats {
3778+
isFile: () => boolean;
3779+
isDirectory: () => boolean;
3780+
isBlockDevice: () => boolean;
3781+
isCharacterDevice: () => boolean;
3782+
isSymbolicLink: () => boolean;
3783+
isFIFO: () => boolean;
3784+
isSocket: () => boolean;
3785+
dev: number | bigint;
3786+
ino: number | bigint;
3787+
mode: number | bigint;
3788+
nlink: number | bigint;
3789+
uid: number | bigint;
3790+
gid: number | bigint;
3791+
rdev: number | bigint;
3792+
size: number | bigint;
3793+
blksize: number | bigint;
3794+
blocks: number | bigint;
3795+
atimeMs: number | bigint;
3796+
mtimeMs: number | bigint;
3797+
ctimeMs: number | bigint;
3798+
birthtimeMs: number | bigint;
3799+
atime: Date;
3800+
mtime: Date;
3801+
ctime: Date;
3802+
birthtime: Date;
3803+
}
37683804
declare class IgnorePlugin {
37693805
constructor(options: IgnorePluginOptions);
37703806
options: IgnorePluginOptions;
@@ -3831,7 +3867,7 @@ declare abstract class InitFragment {
38313867
declare interface InputFileSystem {
38323868
readFile: (
38333869
arg0: string,
3834-
arg1: (arg0?: NodeJS.ErrnoException, arg1?: Buffer) => void
3870+
arg1: (arg0?: NodeJS.ErrnoException, arg1?: string | Buffer) => void
38353871
) => void;
38363872
readJson?: (
38373873
arg0: string,
@@ -3843,15 +3879,18 @@ declare interface InputFileSystem {
38433879
) => void;
38443880
readdir: (
38453881
arg0: string,
3846-
arg1: (arg0?: NodeJS.ErrnoException, arg1?: string[]) => void
3882+
arg1: (
3883+
arg0?: NodeJS.ErrnoException,
3884+
arg1?: (string | Buffer)[] | IDirent[]
3885+
) => void
38473886
) => void;
38483887
stat: (
38493888
arg0: string,
3850-
arg1: (arg0?: NodeJS.ErrnoException, arg1?: FsStats) => void
3889+
arg1: (arg0?: NodeJS.ErrnoException, arg1?: IStats) => void
38513890
) => void;
38523891
realpath?: (
38533892
arg0: string,
3854-
arg1: (arg0?: NodeJS.ErrnoException, arg1?: string) => void
3893+
arg1: (arg0?: NodeJS.ErrnoException, arg1?: string | Buffer) => void
38553894
) => void;
38563895
purge?: (arg0?: string) => void;
38573896
join?: (arg0: string, arg1: string) => string;
@@ -3863,7 +3902,7 @@ type IntermediateFileSystem = InputFileSystem &
38633902
IntermediateFileSystemExtras;
38643903
declare interface IntermediateFileSystemExtras {
38653904
mkdirSync: (arg0: string) => void;
3866-
createWriteStream: (arg0: string) => WriteStream;
3905+
createWriteStream: (arg0: string) => NodeJS.WritableStream;
38673906
open: (
38683907
arg0: string,
38693908
arg1: string,
@@ -6816,11 +6855,11 @@ declare interface OutputFileSystem {
68166855
mkdir: (arg0: string, arg1: (arg0?: NodeJS.ErrnoException) => void) => void;
68176856
stat: (
68186857
arg0: string,
6819-
arg1: (arg0?: NodeJS.ErrnoException, arg1?: FsStats) => void
6858+
arg1: (arg0?: NodeJS.ErrnoException, arg1?: IStats) => void
68206859
) => void;
68216860
readFile: (
68226861
arg0: string,
6823-
arg1: (arg0?: NodeJS.ErrnoException, arg1?: Buffer) => void
6862+
arg1: (arg0?: NodeJS.ErrnoException, arg1?: string | Buffer) => void
68246863
) => void;
68256864
join?: (arg0: string, arg1: string) => string;
68266865
relative?: (arg0: string, arg1: string) => string;

0 commit comments

Comments
 (0)