嗨, 各位好呀, 我是称作小鑫同学的人, 是有着资深程度的 IT 从业者, 还是 InfoQ 的签约作者, 在前端开发上擅长且在这个领域拥有多年时长的经验, 一直致力于去分享我于技术方面的有关见解以及心得。它是我近期开发的 CLI 工具, 其与你于社区所见到的别的 CLI 工具的本质差异在于能够灵活组合, 如此一来, 你既能针对不同项目组合各异的 CLI 功能, 又能借助插件开发去替换已然过时或者不兼容的功能, 灵活组合对 CLI 功能较多或者项目间应用规则不一致的情形而言是一种不错的解决办法。认识借助框架图能够知晓, 在其那个核心地带, 给出了 CLI 命令行注册的功能, 还装了平常要用的, , fix 命令, 并且加以配置文件给予支持。针对别的额外功能, 全都放到插件那里去做, 经由配置文件开展插件的组合, 从而构建出契合某一个或者某一系列项目的 CLI 工具。CLI 基础功能搭建将 cac 用于 CLI 基础功能的搭建工作当中, 全部 CLI 功能借由 setup 函数予以注册。import cac from cac; import { handleError, setup } from /helper; import { plugins } from /index; import pkg from ../package.json; const setupCli async () { const cli cac(codeg); await setup(cli, plugins); cli.help(); cli.version(pkg.version); cli.parse(process.argv, { run: false }); await cli.runMatchedCommand(); }; setupCli().catch(handleError);内置命令与外置命令于自定义配置之际存在些许差异, 故而在 setup 函数里, 内置的命令得在此处予以执行, 且要传入自定义配置, 作为特殊的内置命令,它承担了所有命令借由选项式执行的兜底功能。export async function setup(cli: CAC, plugins: BuiltInPlugins) { const uconfig await loadConfigModule(); const commands: ArrayCommandOptions []; const builtInPluginsIns plugins.map((fn) fn(uconfig?.commands)); for (const pluginIns of builtInPluginsIns.concat(uconfig?.plugins || [])) { if (pluginIns.command pluginIns.describe) { commands.push({ display: pluginIns.name || pluginIns.command, command: pluginIns.command, description: pluginIns.describe, }); } pluginIns.setup(cli); } // 特殊处理 rootInstaller(commands.concat(defaultCommands)).setup(cli); }自定义配置自定义配置所需用到的某一关键技术乃是模块动态加载, 当前仅支持加载 codeg..js、codeg..mjs 文件, 并且务必为 ESM 模块, 要是需要加载更为多样的模块类型, 还得有额外的兼容。export async function loadConfigModule(): Promise CodeGeniusOptions | undefined { let resolvedPath: string | undefined; for (const filename of DEFAULT_CONFIG_FILES) { const filePath path.resolve(process.cwd(), filename); if (!fs.existsSync(filePath)) continue; resolvedPath filePath; break; } if (!resolvedPath) return; const moduleURL pathToFileURL(resolvedPath).href; return (await import(moduleURL)).default; }一样的, 我也针对性地把函数添加给了自定义配置, 如此一来, 于配置的进程当中, 能够将一些并非必要的麻烦给削减掉。export interface CodeGeniusOptions { commands?: CommandsOptions; plugins?: Plugins; } export const defineConfig (config: CodeGeniusOptions): CodeGeniusOptions config;命令命令的主要功能在于, 代理去运行脚本, 此脚本适用于项目存在大量情况之时能去生成单独用来描述每个作用的相关配置文件, 并且还都是经过询问模式随后采取执行与其对应的。export default function scriptRunInstaller() { return { name: script, describe: 代理运行 package.scripts 脚本, command: script, setup: (cli: CAC) { cli .command(script, 代理运行 package.scripts 脚本) .action(async () { await generateScripts(); await scriptRun(); }); }, }; }插件开发此功能是用于进行验证, 验证在编写描述时描述是否契合规范, 当下进行插件开发的演示, 我会以示例来开展演示。