Merge pull request #12415 from webpack/bugfix/typings-compat

make filesystem types compatible with memfs and normal fs
This commit is contained in:
Tobias Koppers 2021-01-13 13:13:11 +01:00 committed by GitHub
commit 3ef285bda9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 135 additions and 29 deletions

View File

@ -724,7 +724,10 @@ ${other}`);
return this.outputFileSystem.readFile( return this.outputFileSystem.readFile(
targetPath, targetPath,
(err, existingContent) => { (err, existingContent) => {
if (err || !content.equals(existingContent)) { if (
err ||
!content.equals(/** @type {Buffer} */ (existingContent))
) {
return doWrite(content); return doWrite(content);
} else { } else {
return alreadyWritten(); return alreadyWritten();

View File

@ -298,11 +298,13 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
const addDirectory = (directory, addSubDirectory, callback) => { const addDirectory = (directory, addSubDirectory, callback) => {
fs.readdir(directory, (err, files) => { fs.readdir(directory, (err, files) => {
if (err) return callback(err); if (err) return callback(err);
files = files.map(file => file.normalize("NFC")); const processedFiles = cmf.hooks.contextModuleFiles.call(
files = cmf.hooks.contextModuleFiles.call(files); /** @type {string[]} */ (files).map(file => file.normalize("NFC"))
if (!files || files.length === 0) return callback(null, []); );
if (!processedFiles || processedFiles.length === 0)
return callback(null, []);
asyncLib.map( asyncLib.map(
files.filter(p => p.indexOf(".") !== 0), processedFiles.filter(p => p.indexOf(".") !== 0),
(segment, callback) => { (segment, callback) => {
const subResource = join(fs, directory, segment); const subResource = join(fs, directory, segment);

View File

@ -1171,8 +1171,9 @@ class FileSystemInfo {
callback(); callback();
break; break;
} }
this.fs.realpath(path, (err, realPath) => { this.fs.realpath(path, (err, _realPath) => {
if (err) return callback(err); if (err) return callback(err);
const realPath = /** @type {string} */ (_realPath);
if (realPath !== path) { if (realPath !== path) {
resolveFiles.add(path); resolveFiles.add(path);
} }
@ -1192,8 +1193,9 @@ class FileSystemInfo {
callback(); callback();
break; break;
} }
this.fs.realpath(path, (err, realPath) => { this.fs.realpath(path, (err, _realPath) => {
if (err) return callback(err); if (err) return callback(err);
const realPath = /** @type {string} */ (_realPath);
if (realPath !== path) { if (realPath !== path) {
resolveFiles.add(path); resolveFiles.add(path);
} }
@ -2405,7 +2407,7 @@ class FileSystemInfo {
} }
_readContextTimestamp(path, callback) { _readContextTimestamp(path, callback) {
this.fs.readdir(path, (err, files) => { this.fs.readdir(path, (err, _files) => {
if (err) { if (err) {
if (err.code === "ENOENT") { if (err.code === "ENOENT") {
this._contextTimestamps.set(path, null); this._contextTimestamps.set(path, null);
@ -2414,7 +2416,7 @@ class FileSystemInfo {
} }
return callback(err); return callback(err);
} }
files = files const files = /** @type {string[]} */ (_files)
.map(file => file.normalize("NFC")) .map(file => file.normalize("NFC"))
.filter(file => !/^\./.test(file)) .filter(file => !/^\./.test(file))
.sort(); .sort();
@ -2501,7 +2503,7 @@ class FileSystemInfo {
} }
_readContextHash(path, callback) { _readContextHash(path, callback) {
this.fs.readdir(path, (err, files) => { this.fs.readdir(path, (err, _files) => {
if (err) { if (err) {
if (err.code === "ENOENT") { if (err.code === "ENOENT") {
this._contextHashes.set(path, null); this._contextHashes.set(path, null);
@ -2509,7 +2511,7 @@ class FileSystemInfo {
} }
return callback(err); return callback(err);
} }
files = files const files = /** @type {string[]} */ (_files)
.map(file => file.normalize("NFC")) .map(file => file.normalize("NFC"))
.filter(file => !/^\./.test(file)) .filter(file => !/^\./.test(file))
.sort(); .sort();
@ -2624,7 +2626,9 @@ class FileSystemInfo {
return callback(err); return callback(err);
} }
const set = new Set( const set = new Set(
elements.map(element => join(this.fs, path, element)) /** @type {string[]} */ (elements).map(element =>
join(this.fs, path, element)
)
); );
callback(null, set); callback(null, set);
}); });

View File

@ -441,7 +441,7 @@ class FileMiddleware extends SerializerMiddleware {
reject(err); reject(err);
return; return;
} }
let remaining = stats.size; let remaining = /** @type {number} */ (stats.size);
let currentBuffer; let currentBuffer;
let currentBufferUsed; let currentBufferUsed;
const buf = []; const buf = [];

View File

@ -7,17 +7,57 @@
const path = require("path"); const path = require("path");
/** @typedef {import("fs").Stats} NodeFsStats */
/** @typedef {import("../../declarations/WebpackOptions").WatchOptions} WatchOptions */ /** @typedef {import("../../declarations/WebpackOptions").WatchOptions} WatchOptions */
/** @typedef {import("../FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */ /** @typedef {import("../FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */
/**
* @typedef {Object} IStats
* @property {() => boolean} isFile
* @property {() => boolean} isDirectory
* @property {() => boolean} isBlockDevice
* @property {() => boolean} isCharacterDevice
* @property {() => boolean} isSymbolicLink
* @property {() => boolean} isFIFO
* @property {() => boolean} isSocket
* @property {number | bigint} dev
* @property {number | bigint} ino
* @property {number | bigint} mode
* @property {number | bigint} nlink
* @property {number | bigint} uid
* @property {number | bigint} gid
* @property {number | bigint} rdev
* @property {number | bigint} size
* @property {number | bigint} blksize
* @property {number | bigint} blocks
* @property {number | bigint} atimeMs
* @property {number | bigint} mtimeMs
* @property {number | bigint} ctimeMs
* @property {number | bigint} birthtimeMs
* @property {Date} atime
* @property {Date} mtime
* @property {Date} ctime
* @property {Date} birthtime
*/
/**
* @typedef {Object} IDirent
* @property {() => boolean} isFile
* @property {() => boolean} isDirectory
* @property {() => boolean} isBlockDevice
* @property {() => boolean} isCharacterDevice
* @property {() => boolean} isSymbolicLink
* @property {() => boolean} isFIFO
* @property {() => boolean} isSocket
* @property {string | Buffer} name
*/
/** @typedef {function(NodeJS.ErrnoException=): void} Callback */ /** @typedef {function(NodeJS.ErrnoException=): void} Callback */
/** @typedef {function(NodeJS.ErrnoException=, Buffer=): void} BufferCallback */ /** @typedef {function(NodeJS.ErrnoException=, Buffer=): void} BufferCallback */
/** @typedef {function(NodeJS.ErrnoException=, Buffer|string=): void} BufferOrStringCallback */ /** @typedef {function(NodeJS.ErrnoException=, Buffer|string=): void} BufferOrStringCallback */
/** @typedef {function(NodeJS.ErrnoException=, string[]=): void} StringArrayCallback */ /** @typedef {function(NodeJS.ErrnoException=, (string | Buffer)[] | IDirent[]=): void} DirentArrayCallback */
/** @typedef {function(NodeJS.ErrnoException=, string=): void} StringCallback */ /** @typedef {function(NodeJS.ErrnoException=, string=): void} StringCallback */
/** @typedef {function(NodeJS.ErrnoException=, number=): void} NumberCallback */ /** @typedef {function(NodeJS.ErrnoException=, number=): void} NumberCallback */
/** @typedef {function(NodeJS.ErrnoException=, NodeFsStats=): void} StatsCallback */ /** @typedef {function(NodeJS.ErrnoException=, IStats=): void} StatsCallback */
/** @typedef {function((NodeJS.ErrnoException | Error)=, any=): void} ReadJsonCallback */ /** @typedef {function((NodeJS.ErrnoException | Error)=, any=): void} ReadJsonCallback */
/** /**
@ -45,7 +85,7 @@ const path = require("path");
* @property {function(string, Buffer|string, Callback): void} writeFile * @property {function(string, Buffer|string, Callback): void} writeFile
* @property {function(string, Callback): void} mkdir * @property {function(string, Callback): void} mkdir
* @property {function(string, StatsCallback): void} stat * @property {function(string, StatsCallback): void} stat
* @property {function(string, BufferCallback): void} readFile * @property {function(string, BufferOrStringCallback): void} readFile
* @property {(function(string, string): string)=} join * @property {(function(string, string): string)=} join
* @property {(function(string, string): string)=} relative * @property {(function(string, string): string)=} relative
* @property {(function(string): string)=} dirname * @property {(function(string): string)=} dirname
@ -53,12 +93,12 @@ const path = require("path");
/** /**
* @typedef {Object} InputFileSystem * @typedef {Object} InputFileSystem
* @property {function(string, BufferCallback): void} readFile * @property {function(string, BufferOrStringCallback): void} readFile
* @property {(function(string, ReadJsonCallback): void)=} readJson * @property {(function(string, ReadJsonCallback): void)=} readJson
* @property {function(string, BufferOrStringCallback): void} readlink * @property {function(string, BufferOrStringCallback): void} readlink
* @property {function(string, StringArrayCallback): void} readdir * @property {function(string, DirentArrayCallback): void} readdir
* @property {function(string, StatsCallback): void} stat * @property {function(string, StatsCallback): void} stat
* @property {(function(string, StringCallback): void)=} realpath * @property {(function(string, BufferOrStringCallback): void)=} realpath
* @property {(function(string=): void)=} purge * @property {(function(string=): void)=} purge
* @property {(function(string, string): string)=} join * @property {(function(string, string): string)=} join
* @property {(function(string, string): string)=} relative * @property {(function(string, string): string)=} relative
@ -73,7 +113,7 @@ const path = require("path");
/** /**
* @typedef {Object} IntermediateFileSystemExtras * @typedef {Object} IntermediateFileSystemExtras
* @property {function(string): void} mkdirSync * @property {function(string): void} mkdirSync
* @property {function(string): import("fs").WriteStream} createWriteStream * @property {function(string): NodeJS.WritableStream} createWriteStream
* @property {function(string, string, NumberCallback): void} open * @property {function(string, string, NumberCallback): void} open
* @property {function(number, Buffer, number, number, number, NumberCallback): void} read * @property {function(number, Buffer, number, number, number, NumberCallback): void} read
* @property {function(number, Callback): void} close * @property {function(number, Callback): void} close

View File

@ -0,0 +1 @@
module.exports = () => false;

View File

@ -0,0 +1,17 @@
const memfs = require("memfs");
const fs = require("fs");
/** @type {import("../../../../").Configuration} */
module.exports = {
plugins: [
compiler => {
compiler.outputFileSystem = memfs.fs;
compiler.inputFileSystem = memfs.fs;
compiler.intermediateFileSystem = memfs.fs;
compiler.outputFileSystem = fs;
compiler.inputFileSystem = fs;
compiler.intermediateFileSystem = fs;
}
]
};

55
types.d.ts vendored
View File

@ -77,7 +77,6 @@ import {
WithStatement, WithStatement,
YieldExpression YieldExpression
} from "estree"; } from "estree";
import { Stats as FsStats, WriteStream } from "fs";
import { JSONSchema4, JSONSchema6, JSONSchema7 } from "json-schema"; import { JSONSchema4, JSONSchema6, JSONSchema7 } from "json-schema";
import { default as ValidationError } from "schema-utils/declarations/ValidationError"; import { default as ValidationError } from "schema-utils/declarations/ValidationError";
import { import {
@ -3765,6 +3764,43 @@ declare class HttpsUriPlugin {
*/ */
apply(compiler: Compiler): void; apply(compiler: Compiler): void;
} }
declare interface IDirent {
isFile: () => boolean;
isDirectory: () => boolean;
isBlockDevice: () => boolean;
isCharacterDevice: () => boolean;
isSymbolicLink: () => boolean;
isFIFO: () => boolean;
isSocket: () => boolean;
name: string | Buffer;
}
declare interface IStats {
isFile: () => boolean;
isDirectory: () => boolean;
isBlockDevice: () => boolean;
isCharacterDevice: () => boolean;
isSymbolicLink: () => boolean;
isFIFO: () => boolean;
isSocket: () => boolean;
dev: number | bigint;
ino: number | bigint;
mode: number | bigint;
nlink: number | bigint;
uid: number | bigint;
gid: number | bigint;
rdev: number | bigint;
size: number | bigint;
blksize: number | bigint;
blocks: number | bigint;
atimeMs: number | bigint;
mtimeMs: number | bigint;
ctimeMs: number | bigint;
birthtimeMs: number | bigint;
atime: Date;
mtime: Date;
ctime: Date;
birthtime: Date;
}
declare class IgnorePlugin { declare class IgnorePlugin {
constructor(options: IgnorePluginOptions); constructor(options: IgnorePluginOptions);
options: IgnorePluginOptions; options: IgnorePluginOptions;
@ -3831,7 +3867,7 @@ declare abstract class InitFragment {
declare interface InputFileSystem { declare interface InputFileSystem {
readFile: ( readFile: (
arg0: string, arg0: string,
arg1: (arg0?: NodeJS.ErrnoException, arg1?: Buffer) => void arg1: (arg0?: NodeJS.ErrnoException, arg1?: string | Buffer) => void
) => void; ) => void;
readJson?: ( readJson?: (
arg0: string, arg0: string,
@ -3843,15 +3879,18 @@ declare interface InputFileSystem {
) => void; ) => void;
readdir: ( readdir: (
arg0: string, arg0: string,
arg1: (arg0?: NodeJS.ErrnoException, arg1?: string[]) => void arg1: (
arg0?: NodeJS.ErrnoException,
arg1?: (string | Buffer)[] | IDirent[]
) => void
) => void; ) => void;
stat: ( stat: (
arg0: string, arg0: string,
arg1: (arg0?: NodeJS.ErrnoException, arg1?: FsStats) => void arg1: (arg0?: NodeJS.ErrnoException, arg1?: IStats) => void
) => void; ) => void;
realpath?: ( realpath?: (
arg0: string, arg0: string,
arg1: (arg0?: NodeJS.ErrnoException, arg1?: string) => void arg1: (arg0?: NodeJS.ErrnoException, arg1?: string | Buffer) => void
) => void; ) => void;
purge?: (arg0?: string) => void; purge?: (arg0?: string) => void;
join?: (arg0: string, arg1: string) => string; join?: (arg0: string, arg1: string) => string;
@ -3863,7 +3902,7 @@ type IntermediateFileSystem = InputFileSystem &
IntermediateFileSystemExtras; IntermediateFileSystemExtras;
declare interface IntermediateFileSystemExtras { declare interface IntermediateFileSystemExtras {
mkdirSync: (arg0: string) => void; mkdirSync: (arg0: string) => void;
createWriteStream: (arg0: string) => WriteStream; createWriteStream: (arg0: string) => NodeJS.WritableStream;
open: ( open: (
arg0: string, arg0: string,
arg1: string, arg1: string,
@ -6816,11 +6855,11 @@ declare interface OutputFileSystem {
mkdir: (arg0: string, arg1: (arg0?: NodeJS.ErrnoException) => void) => void; mkdir: (arg0: string, arg1: (arg0?: NodeJS.ErrnoException) => void) => void;
stat: ( stat: (
arg0: string, arg0: string,
arg1: (arg0?: NodeJS.ErrnoException, arg1?: FsStats) => void arg1: (arg0?: NodeJS.ErrnoException, arg1?: IStats) => void
) => void; ) => void;
readFile: ( readFile: (
arg0: string, arg0: string,
arg1: (arg0?: NodeJS.ErrnoException, arg1?: Buffer) => void arg1: (arg0?: NodeJS.ErrnoException, arg1?: string | Buffer) => void
) => void; ) => void;
join?: (arg0: string, arg1: string) => string; join?: (arg0: string, arg1: string) => string;
relative?: (arg0: string, arg1: string) => string; relative?: (arg0: string, arg1: string) => string;