每次打开别人项目都是先看一下package.json看看有什么命令,总想着实现一个小脚本。
创建项目 script-list
,写上 bin
字段,然后 npx script-list
,发现有个模块跟我重名了。。就是说,已经有人写好了,并且取的名字还跟我都是一样的。
这是效果图
正好,我也不用写了,看一下大佬是怎么写的
rousan/sl: An utility tool to list npm scripts from package.json file (github.com)
入口文件
正好用大佬的工具看一下可执行的脚本
yarn test
一下,全过了
发现入口文件是 scr/cli.js
,立即打开看一下
主要看一下解析过程,进入 parser.parse
const logger = require("./logger");
// 解析函数
function parse(modulePaths) {
// 解析参数所有路径
modulePaths.forEach((modulePath) => {
try {
// 将路径放入解析器中解析
const moduleScripts = extractScripts(modulePath);
// 成功打印信息
logger.logScripts(modulePath, moduleScripts);
} catch (err) {
// 失败打印错误
logger.logInvalidModule(modulePath, err.message);
}
});
}
这个才是真正的主程序, extractScripts
只干一件事,就是解析 package.json
逻辑,logger
也只干一件事,就是打印信息,分为错误信息和正确信息。代码抽离的相当干净,具体解析逻辑继续看一下。
const fs = require("fs");
const path = require("path");
const utils = require("./utils");
function extractScripts(modulePath) {
modulePath = path.resolve(modulePath);
// 判断路径存在
if (!fs.existsSync(modulePath)) {
throw new Error(`Path does not exist: ${modulePath}`);
}
// 判断路径是文件夹
if (!utils.isDirectory(modulePath)) {
throw new Error(`Path needs to be a directory: ${modulePath}`);
}
// 直接拼接出 package.json, 验证有效性
const pkgFile = path.resolve(path.join(modulePath, "package.json"));
if (!fs.existsSync(pkgFile)) {
throw new Error(`No package.json file found: ${modulePath}`);
}
// 读出 package.json 内容
const pkgData = utils.readJSONFile(pkgFile);
if (!pkgData) {
throw new Error(`Invalid package.json file found: ${modulePath}`);
}
// 取出 scripts 字段
const { scripts } = pkgData;
if (!scripts) {
throw new Error(`No scripts field found: ${pkgFile}`);
}
return scripts;
}
在执行真正逻辑之前,做了大量判断,使用 报错立即返回
的方式,代码显得干净整洁,健壮性很高。
剩下的格式化输出就不看了。。