跳到主要内容

判断某个文件名称(带后缀)数组中是否有一个文件是否在某个目录下,如果在,则返回这个文件名称(带后缀),如果不在则返回 undefined

源码解析

"use strict";
const path = require("path");
const fs = require("fs");
const { promisify } = require("util");
const pLocate = require("p-locate");

const fsStat = promisify(fs.stat);
const fsLStat = promisify(fs.lstat);

const typeMappings = {
directory: "isDirectory",
file: "isFile",
};

function checkType({ type }) {
if (type in typeMappings) {
return;
}

throw new Error(`Invalid type specified: ${type}`);
}

const matchType = (type, stat) =>
type === undefined || stat[typeMappings[type]]();

module.exports = async (paths, options) => {
options = {
cwd: process.cwd(),
type: "file",
allowSymlinks: true,
...options,
};
checkType(options);
const statFn = options.allowSymlinks ? fsStat : fsLStat;

return pLocate(
paths,
async (path_) => {
try {
const stat = await statFn(path.resolve(options.cwd, path_));
return matchType(options.type, stat);
} catch (_) {
return false;
}
},
options
);
};

module.exports.sync = (paths, options) => {
options = {
cwd: process.cwd(),
allowSymlinks: true,
type: "file",
...options,
};
checkType(options);
const statFn = options.allowSymlinks ? fs.statSync : fs.lstatSync;

for (const path_ of paths) {
try {
const stat = statFn(path.resolve(options.cwd, path_));

if (matchType(options.type, stat)) {
return path_;
}
} catch (_) {}
}
};

我们来分析一下同步 .sync 的源码部分

1. 定义并检查了 options 的 type

const typeMappings = {
directory: 'isDirectory',
file: 'isFile'
};

function checkType({type}) {
if (type in typeMappings) {
return;
}

throw new Error(`Invalid type specified: ${type}`);
}

...
options = {
cwd: process.cwd(),
allowSymlinks: true,
type: 'file',
...options
};
checkType(options);

检查 type 是否在 typeMappings 中存在,否则爆出错误

2. 遍历查找目录中是否存在文件

const matchType = (type, stat) =>
type === undefined || stat[typeMappings[type]]();
const statFn = options.allowSymlinks ? fs.statSync : fs.lstatSync;

for (const path_ of paths) {
try {
const stat = statFn(path.resolve(options.cwd, path_));

if (matchType(options.type, stat)) {
return path_;
}
} catch (_) {}
}
  • 遍历传入的路径
  • 解析传入的路径与当前遍历路径为绝对路径
  • 通过fs.statSync 或者fs.lstatSync 方法获取文件信息状态
  • 判断文件名称(带后缀)数组中是否有一个文件是否在某个目录下,如果在,则返回这个文件名称(带后缀),如果不在则返回 undefined