gxd-vue-library
Version:
依赖与element Ui插件库,聚福宝福利PC端插件库
701 lines (637 loc) • 18.1 kB
JavaScript
;
const requireContext = require('require-context');
const fs = require('fs');
const https = require("https");
const resolve = dir => require('path').join(__dirname, dir);
const clog = require('./clog');
const path = require('path');
const os = require('os');
const md5 = require('md5');
//https://www.npmjs.com/package/copy-dir
let copyDir = require('copy-dir');
class FileHelper {
/**
* @description 检查变量类型
* @param obj {*} 变量
* @returns {*}
*/
checkVarType(obj) {
let toString = Object.prototype.toString;
let map = {
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object String]': 'string',
'[object Function]': 'function',
'[object Array]': 'array',
'[object Date]': 'date',
'[object RegExp]': 'regExp',
'[object Undefined]': 'undefined',
'[object Null]': 'null',
'[object Object]': 'object'
}
return map[toString.call(obj)];
}
/**
* @description 检查两个数组是否有交集
* @param sourceArray
* @param findArray
* @returns {boolean}
*/
inArray(sourceArray = [], findArray = []) {
if (this.checkVarType(sourceArray) === 'array' && this.checkVarType(findArray) === 'array') {
let sourceArrayLen = sourceArray.length;
let find = JSON.parse(JSON.stringify(findArray));
let temp = [];
for (let i = 0; i < sourceArrayLen; i++) {
let sourceVal = sourceArray[i];
for (let k = 0; k < find.length; k++) {
if (find[k] === sourceVal) {
temp.push(true);
find.splice(k, 1);
break;
}
}
}
return findArray.length === temp.length;
} else {
return false;
}
}
/**
* @description 获取平台下复制命令
* @returns {string}
*/
getPlatformCopyKey(){
return os.type() === 'Windows_NT'? 'copy': 'cp -rf';
}
/**
* @description 获取平台下删除命令
* @returns {string}
*/
getPlatformRmKey(){
return os.type() === 'Windows_NT'? 'rd/s/q': 'rm -rf';
}
repleceDir(path) {
this.replaceDir(path)
}
replaceDir(FilePath){
return path.normalize(FilePath)
}
/**
* @description 获取平台真实路径
* @param FilePath {String} 文件路径
* @returns {string}
*/
getPlatformSurePath(FilePath){
return path.normalize(FilePath);
}
/**
* @description 根据平台去掉路径左右斜杠
* @param pathFile {String} 文件路径
* @returns {string}
*/
trimSep(pathFile){
return path.normalize(pathFile).split(path.sep).filter(item=>{return item !== ''}).join(path.sep);
}
/**
* @description 判断路径下面是否有空文件
* @param dirPath
* @returns {[]}
*/
isPathHasEmptyDir(dirPath) {
let emptyDir = [];
const handle = (__dirPath, rootDir) => {
let files = [];
if (this.existFileSync(__dirPath)) {
files = fs.readdirSync(__dirPath);
//空文件判断
if (files.length === 0) {
emptyDir.push(__dirPath);
}
files.forEach((file, index) => {
let curPath = this.getPlatformSurePath(__dirPath + "/" + file);
if (fs.statSync(curPath).isDirectory()) { // recurse
handle(curPath, `${rootDir}/${file}`);
}
});
}
};
if (this.isDirectory(dirPath)) {
handle(dirPath, '');
} else {
clog('不是一个目录路径', 'red');
process.exit(-1);
}
return emptyDir
}
/**
* @description 获取目录下的所有文件(推荐使用)
* @param dirPath {String} 目录路径
* @returns {{}}
*/
getNodeDirFiles(dirPath){
let filesArr = [];
//判断文件不存在
if(!this.existFileSync(dirPath)) return [];
const handle = (__dirPath, rootDir)=>{
let files = [];
if(this.existFileSync(__dirPath)) {
files = fs.readdirSync(__dirPath);
files.forEach((file, index)=> {
let curPath = this.getPlatformSurePath(__dirPath + "/" + file);
if(fs.statSync(curPath).isDirectory()) { // recurse
handle(curPath, `${rootDir}/${file}`);
} else {
let reg = /^(.+)\.([a-zA-Z]+)$/;
filesArr.push({
systemPath: curPath,
parentDir: this.trimSep(rootDir),
fullPath: this.trimSep(`${rootDir}/${file}`),
fileName: file.replace(reg, '$1'),
path: this.trimSep(`${rootDir}/${file}`.replace(reg, '$1')),
ext: this.trimSep(`${rootDir}/${file}`.replace(reg, '$2')),
networkPath: this.trimSep(`${rootDir}/${file}`).replace(/(\\)/g, '/')
});
}
});
}
};
if(this.isDirectory(dirPath)) {
handle(dirPath, '');
}
else {
clog('不是一个目录路径', 'red');
process.exit(0);
}
return filesArr
}
/**
* @description 获取目录下的所有文件
* @param directory {String} 目录路径
* @param fileType {Array} 返回文件类型 默认:[] 返回所有文件
* @param ignoreFileName {Array} 返回忽略文件 默认: []
* @param isRepeat {Boolean} 是否去重文件名重复 默认: true
* @returns {{}}
*/
getDirFiles(directory, fileType = [], ignoreFileName = [],isRepeat= true) {
//判断文件是否存在
if(!this.existFileSync(directory)) return {};
if (this.isPathHasEmptyDir(directory).length > 0) {
clog(os.EOL);
clog(`文件路径下面有空文件: 其路径:${os.EOL}${JSON.stringify(this.isPathHasEmptyDir(directory))}`, 'red');
clog(os.EOL);
process.exit(-1)
}
let endReg = new RegExp(`^(.+)(\/|\\\\)$`);
let endMatchStr = directory.match(endReg);
if (endMatchStr) directory = endMatchStr[1];
let reg = new RegExp(`\.(${fileType.join('|')})$`);
let regFile = new RegExp(`^(.*)\.(${fileType.join('|')})$`);
if(fileType.length === 0) {
reg = /\.([a-zA-Z]+)$/;
regFile = /^(.+)\.([a-zA-Z]+)$/;
}
let modulesFiles = requireContext(path.normalize(directory), true, reg);
let modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(regFile, '$1');
const extName = modulePath.replace(regFile, '$2');
const moduleNameArr = moduleName.split(path.sep);
let keyName = moduleName;
if(!isRepeat) keyName = moduleName + extName;
modules[keyName] = {
path: moduleName,
fileName: moduleNameArr[moduleNameArr.length - 1],
ext: extName,
fullName: `${moduleName}.${extName}`
};
return modules;
}, {});
//过滤忽略文件
let temp = {};
Object.keys(modules).map((key) => {
let item = modules[key];
if (
!this.inArray(ignoreFileName, [item['fileName']])
&& !this.inArray(ignoreFileName, [item['fullName']])
) {
temp[key] = modules[key];
}
});
return temp;
}
/***
* @description 复制文件到新位置(废弃)
* @param currentFilePath
* @param targetFilePath
*/
copyFile(currentFilePath, targetFilePath) {
currentFilePath = path.normalize(currentFilePath);
targetFilePath = path.normalize(targetFilePath);
if (!this.existFileSync(currentFilePath)) {
clog(`复制文件或者不存在, 路径${currentFilePath}`, 'green');
process.exit(-1);
}
return new Promise((resolve,reject)=>{
if (!fs.existsSync(currentFilePath)) {
reject(`复制文件路径不存在:${currentFilePath}`);
}
let readStream = fs.createReadStream(currentFilePath);
readStream.once('error', (err) => {
reject(err);
});
readStream.once('end', (e) => {
resolve(e);
});
readStream.pipe(fs.createWriteStream(targetFilePath));
})
}
/**
* @description 异步复制文件
* @param fromPath {String} 复制源路径
* @param toPath {String} 目标源路径
* @param options {Object} 设置参数
* @param options.cover {Boolean} 覆盖操作,默认:true
* @param options.utimes {Boolean} 修改时间覆盖,默认:true
* @param options.mode {Boolean} 文件模式,默认:true
* @param options.filter {Function} 文件过滤
*/
copy(fromPath, toPath, options={}){
if (!this.existFileSync(fromPath)) {
clog(`复制文件或者不存在, 路径${fromPath}`, 'green');
process.exit(-1);
}
let opt = Object.assign({}, {
cover: true,
mode: true,
utimes: true
}, options);
return new Promise((resolve, reject)=>{
copyDir(fromPath, toPath , opt, (err)=>{
if(err) reject(err);
else resolve();
})
})
}
/**
* @description 同步复制文件
* @param fromPath {String} 复制源路径
* @param toPath {String} 目标源路径
* @param options {Object} 设置参数
* @param options.cover {Boolean} 覆盖操作,默认:true
* @param options.utimes {Boolean} 修改时间覆盖,默认:true
* @param options.mode {Boolean} 文件模式,默认:true
* @param options.filter {Function} 文件过滤
*/
copySync(fromPath, toPath, options={}){
if (!this.existFileSync(fromPath)) {
clog(`复制文件或者不存在, 路径${fromPath}`, 'green');
process.exit(-1);
}
let opt = Object.assign({}, {
cover: true,
mode: true,
utimes: true
}, options);
copyDir.sync(fromPath,toPath,opt);
}
/**
* @description 删除文件或者目录路径
* @param dirAndPath {String} 文件或者目录路径
* @param isRoot {Boolean} 是否为根目录
* @param isLog {Boolean} 是否显示删除日志 默认:false
*/
removeFileAndDir(dirAndPath, isLog= false, isRoot = true){
dirAndPath = this.getPlatformSurePath(dirAndPath);
//是文件直接进行文件删除
if(this.isFile(dirAndPath) && isRoot){
fs.unlinkSync(dirAndPath);
let isDirName = '文件';
if(isLog) clog(`删除${isDirName}: ${dirAndPath}`, 'green');
return
}
let files = [];
if(this.existFileSync(dirAndPath)) {
files = fs.readdirSync(dirAndPath);
files.forEach((file, index)=> {
let curPath = this.getPlatformSurePath(dirAndPath + "/" + file);
let isDirName = '';
if(fs.statSync(curPath).isDirectory()) { // recurse
this.removeFileAndDir(curPath, isLog, false);
isDirName = '目录';
} else { // delete file
fs.unlinkSync(curPath);
isDirName = '文件';
}
if(isLog) clog(`删除${isDirName}: ${curPath}`, 'green');
});
fs.rmdirSync(dirAndPath);
}
else{
clog('删除路径不存在', 'red');
process.exit(0);
}
}
/***
* @description 删除文件
* @param FilePath {String} 需要删除文件路径
* @returns {Promise<unknown>}
*/
removeFile(FilePath){
return new Promise((resolve, reject)=>{
fs.unlink(this.getPlatformSurePath(FilePath), (err) => {
if (err) {
reject(err);
return;
}
resolve('ok');
});
})
}
/***
* @description 删除文件
* @param FilePath {String} 需要删除文件路径
* @returns {*}
*/
removeFileSync(FilePath){
try {
fs.unlinkSync(this.getPlatformSurePath(FilePath));
return null;
}catch (e) {
throw e;
}
}
/**
* @description 修改文件名字
* @param FilePath {String} 修改源文件路径
* @param newPath {String} 修改后源文件路径
* @returns {Promise<unknown>}
*/
renameFile(FilePath,newPath){
return new Promise((resolve, reject) => {
fs.rename(this.getPlatformSurePath(FilePath), newPath ,(err) => {
if (err) {
reject(err);
return;
}
resolve('ok');
});
})
}
/**
* @description 修改文件名字
* @param FilePath {String} 修改源文件路径
* @param newPath {String} 修改后源文件路径
* @returns {Boolean}
*/
renameFileSync(FilePath,newPath){
try {
fs.renameSync(this.getPlatformSurePath(FilePath), newPath);
return null;
}catch (e) {
throw e;
}
}
/**
* @description 同步判断文件存在
* @param FilePath
* @returns {boolean}
*/
existFileSync(FilePath) {
try{
fs.accessSync(this.getPlatformSurePath(FilePath), fs.constants.F_OK);
return true
}catch (e) {
return false
}
}
/**
* @description 判断文件是否存在
* @param FilePath
* @returns {Promise<unknown>}
*/
existFile(FilePath){
return new Promise((resolve, reject) => {
fs.access(this.getPlatformSurePath(FilePath), fs.constants.F_OK, (err) => {
if (err) {
reject(err);
return;
}
resolve('ok');
});
})
}
/**
* @description 异步读取文件
* @param FilePath
* @returns {Promise<unknown>}
*/
readFile(FilePath){
return new Promise((resolve, reject) => {
fs.readFile(this.getPlatformSurePath(FilePath),(err, data) => {
if (err) {
reject(err);
return;
}
resolve(String(data));
});
});
}
/**
* @description 同步读取文件
* @param FilePath
* @returns {string}
*/
readFileSync(FilePath) {
return String(fs.readFileSync(this.getPlatformSurePath(FilePath)));
}
/**
* @description 异步写文件
* @param FilePath
* @param data
* @returns {Promise<unknown>}
*/
writeFile(FilePath,data){
return new Promise((resolve, reject) => {
fs.writeFile(this.getPlatformSurePath(FilePath), data, (err) => {
if (err) {
reject(err);
return;
}
resolve('ok');
});
});
}
/**
* @description 异步写文件
* @param FilePath
* @param data
* @returns {*}
*/
writeFileSync(FilePath, data) {
return fs.writeFileSync(this.getPlatformSurePath(FilePath), data);
}
/**
* @description 同步创建文件夹
* @param baseDir {String} 文件路径BaseFile
* @param pathFile {String} 创建的文件路径
* @param mode {String} 权限值
*/
mkdirSync(baseDir, pathFile = '', mode='0755'){
let pathArr = this.getPlatformSurePath(pathFile).split(path.sep);
let mkdir = ()=>{
let file = this.getPlatformSurePath(`${baseDir}/${pathArr.shift()}`);
try{
fs.mkdirSync(file, mode);
baseDir = file;
}catch (e) {
baseDir = file;
}
if(pathArr.length >0) {
mkdir();
}
};
mkdir();
}
/**
* @description 处理nodejs请求
* @param res
* @param resolve
* @param type {String} 返回数据格式
*/
handleHttp(res, resolve, type){
let store = "";
res['on']('data', (d) => {
store += d.toString();
});
res['on']('end',()=>{
if(type === 'json') {
try {store = JSON.parse(store);}catch (e) {}
}
resolve(store)
})
}
httpsGet(url, type) {
return new Promise((resolve, reject) => {
https.get(url, (res) => {
this.handleHttp(res, resolve, type);
})
.on('error', (e) => {
reject({
message: '失败',
data: null,
code: 'fail'
})
})
});
}
httpGet(url, type) {
return new Promise((resolve, reject) => {
http.get(url, (res) => {
this.handleHttp(res, resolve, type);
})
.on('error', (e) => {
reject({
message: '失败',
data: null,
code: 'fail'
})
})
});
}
/**
* @description 获取远程文件信息
* @param url {String} 请求地址
* @param type {String} 返回数据格式
* @return {Promise}
*/
get(url, type="json") {
let regHttp = /^(http:\/\/)(.+)$/;
let regHttps = /^(https:\/\/|\/\/)(.+)$/;
if(regHttp.test(url)
|| regHttps.test(url)
){
if (regHttps.test(url)) return this.httpsGet(url, type);
if (regHttp.test(url)) return this.httpGet(url, type);
}
else{
throw Error('请求地址格式有误')
}
}
/**
* @description 同步读取目录下边的文件信息
* @param path
* @returns {[]}
*/
readdirSync(path){
let dirs;
try {
dirs = fs.readdirSync(this.getPlatformSurePath(path));
}catch (e) {
clog('访问文件路径不存在', 'red');
throw new Error(e)
process.exit(-111);
}
let dirsArray = [];
dirs.map(item=>{
let stats = fs.statSync(this.getPlatformSurePath(`${path}/${item}`));
if(stats.isFile()) dirsArray.push({
name: item,
type: 'file',
stats
});
if (stats.isDirectory()) dirsArray.push({
name: item,
type: 'dir',
stats
});
});
return dirsArray;
}
/**
* @description 同步获取文件信息
* @returns {Stats}
*/
getFileStat(path){
let info;
try {
info = fs.statSync(this.getPlatformSurePath(path));
} catch (e) {
clog('访问文件路径不存在', 'red');
process.exit(0);
}
return info;
}
/**
* @description 同步访问文件是否为文件
* @param path
* @returns {boolean}
*/
isFile(path){
let temp = false;
try{
let stats = fs.statSync(this.getPlatformSurePath(path));
temp = stats.isFile();
}catch (e) {
clog('访问文件路径不存在', 'red');
process.exit(0);
}
return temp;
}
/**
* @description 同步访问文件是否为目录
* @param path
* @returns {boolean}
*/
isDirectory(path) {
let temp = false;
try {
let stats = fs.statSync(this.getPlatformSurePath(path));
temp = stats.isDirectory();
} catch (e) {
clog('访问文件路径不存在', 'red');
process.exit(0);
}
return temp;
}
}
module.exports = new FileHelper();