const fs = require("fs");
const nodePath = require("path");
// import * as fs from "fs";
const folder = "./";
const condition = ["node_modules", "compile"];
const monitor = (folder: string, cb: () => void) => {
fs.watch(
folder,
{
recursive: true,
},
(eventType: any, filename: string) => {
if (eventType === "change")
//console.log(`${filename} ${eventType}`); // 输出被修改的文件名及其类型(如created、deleted等)
cb();
}
);
};
const mapFolder = async (folder: string) => {
let fileArr: string[] = [];
await main(folder, (val) => {
if (!/.js$/.test(val)) return;
fileArr.push(val);
});
return fileArr;
};
const loadModules = (fileArr: string[]) => {
fileArr.forEach((src) => {
let srcFile = fs.readFileSync(nodePath.resolve(src)).toString();
const analyseRes = analyzeModule(srcFile);
if (
analyseRes.modulePaths.length === 0 ||
analyseRes.startMark === -1 ||
analyseRes.endMark === -1
)
return;
analyseRes.modulePaths.forEach(
(module) => (srcFile = loadModule(srcFile, module))
);
srcFile = eraseModuleMark(srcFile);
fs.writeFileSync(src, srcFile);
console.log("load modules for: " + src);
console.log(analyseRes.modulePaths);
});
};
// let fileArr: string[] = [];
// main(folder, (val) => {
// if (!/.js$/.test(val)) return;
// fileArr.push(val);
// }).then(() => {
// fileArr.forEach((src) => {
// let srcFile = fs.readFileSync(nodePath.resolve(src)).toString();
// const analyseRes = analyzeModule(srcFile);
// if (
// analyseRes.modulePaths.length === 0 ||
// analyseRes.startMark === -1 ||
// analyseRes.endMark === -1
// )
// return;
// analyseRes.modulePaths.forEach(
// (module) => (srcFile = loadModule(srcFile, module))
// );
// srcFile = eraseModuleMark(srcFile);
// fs.writeFileSync(src, srcFile);
// console.log("load modules for: " + src);
// console.log(analyseRes.modulePaths);
// });
// });
/**
*
* @param filePath file path
* @returns ['common/js/request.js','common/js/test.js', ...]
*/
const startMarkStr = "//@LoadModuleStart@";
const endMarkStr = "//@LoadModuleEnd@";
const analyzeModule = (
file: string
): { modulePaths: string[]; startMark: number; endMark: number } => {
const startMark = file.indexOf(startMarkStr) + startMarkStr.length;
const endMark = file.indexOf(endMarkStr);
if (endMark === -1 || startMark === -1)
return { modulePaths: [], startMark, endMark };
const modules = file.substring(startMark, endMark);
const modulePaths = modules
.split("//")
.map((val) => val.replace(/\n|\r|\/\//g, ""))
.filter((val) => val);
return { modulePaths, startMark, endMark };
};
const loadModule = (src: string, moduleFileSrc: string) => {
const moduleFile = fs.readFileSync(moduleFileSrc).toString();
return (src =
"\n//--------------\n" + moduleFile + "\n//--------------\n" + src);
};
const eraseModuleMark = (file: string): string => {
const start = file.indexOf(startMarkStr);
const end = file.indexOf(endMarkStr) + endMarkStr.length;
return file.substring(0, start) + file.substring(end);
};
async function main(folder: string, callback: (val: string) => void) {
const curDir = path(folder);
await iterate(curDir);
async function iterate(root: string) {
let task;
try {
task = fs.readdirSync(root).map(async (val: string) => {
const tmp = path(root) + val;
if (await isFile(tmp)) filter(tmp) && callback(tmp);
else {
const nextPath = path(tmp);
filter(nextPath) && (await iterate(nextPath));
}
});
} catch (err) {
console.log(err);
}
return Promise.all(task);
}
}
function path(dir: string) {
const temp = dir.replace(/\\/g, "/");
if (temp.endsWith("/")) return temp;
return temp + "/";
}
function isFile(dir: string) {
return new Promise((resolve, reject) => {
fs.stat(dir, (err: object, stat) => {
if (err) reject(err);
resolve(stat.isFile());
});
});
}
function filter(path: string) {
return !condition.find((val) => path.indexOf(val) !== -1);
}
function throttler(time: number, cb: () => void, immediate: boolean) {
var throttleTimer: null | number = null;
immediate && cb();
return function () {
if (throttleTimer !== null) clearInterval(throttleTimer);
throttleTimer = setTimeout(cb, time) as unknown as number;
};
}
//-----------------------------------------------------------------
const mainThread = async () => {
const fileArr = await mapFolder(folder);
const loader = throttler(
1000,
() => {
loadModules(fileArr);
const date = new Date();
console.log(
`${date.getHours()}-${date.getMinutes()}-${date.getSeconds()}`
);
},
true
);
monitor(folder, () => {
loader();
});
};
mainThread();