Why?
- cli安装速度慢,所有package都集成在cli里面,多进程进行性能优化&本地包缓存
- init命令只能使用@mac-mw-cli-dev/init包,其实各个bu的包init命令可能都不一样,
实现动态init命令, 脚手架支持a使用a-init包 b使用b-init包
what?
How?
核心流程点分析
封装Package类
让每一个npm包对应一个Package实例,这样我们可以封装出包最新版本,包是否在本地缓存等方法.作用:优先使用本地缓存的Init命令的npm包,且支持自动升级包版本
class Package{
/** 在命令行指定了init包的路径 */
this.targetPath = options.targetPath;
/** 缓存在.mac-mw-cli-dev的init包路径目录 */
this.storeDir = options.storeDir;
/** npm包的name */
this.packageName = options.name;
/** npm包的version */
this.packageVersion = options.version;
/** 缓存目录前缀 */
this.cacheFilePathPrefix = this.packageName.replace("/", "_");
/** 判断当前包是否存在于本地的缓存目录 */
async exits(){
}
/** 安装npm包到本地的缓存目录 */
async install(){
}
/** 如果本地安装了包,会去对比npm最新版本,同时本地包更新到最新版本 */
async update(){
}
/** 获取包的入口文件 */
async getRootFilePath(){
}
}
封装Command类
将脚手架的每个命令对应于我们的Command类,内部封装命令的准备阶段和执行阶段,采用promise方式按序执行.准备阶段执行node版本和参数初始化等前置操作,执行阶段真正执行命令
class Command {
constructor(){
promise.then(()=>fun1)
promise.then(()=>init())
promise.then(()=>exec())
}
async init(){
}
async exec(){
}
}
本地包缓存
if(pkg,exits()){
await pkg.update(); //先测试一下是否是最新版本
}else{
pkg.install(); //下载包到本地缓存目录
}
// 直接使用本地包
const rootFile = pkg.getRootFilePath()
// 执行包里面到处的方法
onst code = `require('${rootFile}')(${JSON.stringify(options)})`;
await execSync("node", ["-e", code], {
stdio: "inherit",
cwd: process.cwd(),
});
Node多进程-childprocess
将安装依赖和执行npm install等方法用spawn子进程执行
const exec = (command, args, options) => {
const win32 = process.platform === "win32";
const cmd = win32 ? "cmd" : command; // windows 下 cmd才是可执行文件
const cmdArgs = win32 ? ["/c"].concat(command, args) : args; //// windows 下 /c表示 静莫执行
return require("child_process").spawn(cmd, cmdArgs, options || {});
};
const execSync = (command, args, options) => {
return new Promise((resolve, reject) => {
const p = exec(command, args, options);
p.on("error", (e) => reject(e));
p.on("exit", (c) => resolve(c));
});
};
// eg
const code = `require('${rootFile}').call(null, ${JSON.stringify(
argsTemp
)})`;
const child = spawn("node", ["-e", code], {
cwd: process.cwd(),
stdio: "inherit",
});
支持各方Init包
配置好各方init包的npm名字,通过Package类的install去安装和缓存,最后通过Node多进程去执行main里到处的函数
const SETTINGS = {
init: "@mac-mw-cli-dev/init", // important 这里可以根据不同的公司用不同的init包 然后不指定targetPath 那么脚手架会把这个包缓存到本地 然后用这个包去执行方法 而且会判断是否有新版本更新
};
pkg = new Package({
targetPath,
name: npmPackageName,
version: packageVersion,
storeDir,
});
if (await pkg.exits()) {
await pkg.update();
} else {
await pkg.install();
}
End
代码链接在这里: github.com/bangbang6/m…
规划->变化->Buffer->目标.
我们的努力,都是向着金钱看齐.
Time