Jake规则引擎指南:一条 rule,自动编译整个目录
Jake规则引擎指南一条 rule自动编译整个目录【免费下载链接】jakeJavaScript build tool, similar to Make or Rake. Built to work with Node.js.项目地址: https://gitcode.com/gh_mirrors/ja/jakeJake 是 Node.js 生态里与 Make、Rake 同类的构建工具Jake自动化构建里我最常用的部分就是它的规则引擎Rule Engine只写一条 rule就能覆盖整个目录的重复编译。先抛个问题项目里有 500 个 .c 文件难道每个都要手写一条构建任务手写任务500 个文件500 行胶水代码我接手过一个老项目jakefile 里全是这样的东西file(a.o, [a.c], function () { /* 编译 a.c */ }); file(b.o, [b.c], function () { /* 编译 b.c */ }); // 500 个文件就是 500 行逻辑却一模一样问题不在行数而在每个文件都要重复声明三遍目标、依赖、动作而这三遍的内容几乎完全相同。新增一个 .c 文件还得记得回去补一条任务漏了就出灵异故障。其实这种模式完全可以一句话声明凡是 .o都能由同名的 .c 生成。这就是 Jake 的 rule()核心实现在 lib/rule.js。三行代码让 main.o 自动跟着 main.c 走Jake 规则怎么写三样东西就够。一个能跑的最小 jakefilefile(app, [main.o]); rule(.o, .c, function () { jake.exec(gcc -c ${this.source} -o ${this.name}); });三个参数对应三要素目标模式.o、源模式.c、构建动作回调函数。动作里有两个好用的上下文this.name是当前要构建的目标名main.othis.source是被换算出来的源文件main.c。此时磁盘上既没有 main.o 也没定义过这个任务跑jake app时规则会自动长出这个任务。第一次看到依赖凭空被创建、编译、跑完就是上手规则引擎最有成就感的时刻 ⚡一条规则执行时Jake 模式匹配内部发生了什么入口在 lib/jake.js 的attemptRule任务执行到某个依赖、发现它不是已定义的任务时就拿这个名字去试规则。下面按时间线拆四个问题。它怎么挑出该用哪条规则matchRulelib/namespace.js先在当前命名空间的规则表里逐条调用Rule.match本命名空间没有再向上问父命名空间。match 分三种走法模式是正则就直接test()模式不含%就是后缀规则只检查目标名是否以它结尾含%则把模式拆成目录、前缀、后缀三段逐一比对。main.o 是怎么换算出 main.c 的Rule.getSourcelib/rule.js负责换算。后缀规则很简单把结尾的 .o 换成 .c。%规则稍讲究先把目标模式改写成正则%变成(.*?)捕获中间那段名字再代回源模式。比如bin/%.o←src/%.c遇到 main.o 就得到 src/main.c。源也可以传一个函数自己算源文件路径。源文件不存在会发生什么createTask会逐个检查准备生成的任务的依赖它要么是已定义的任务要么文件已存在于磁盘要么还能被另一条规则生成递归调用 attemptRule。只要有一个依赖无解整条规则就被判无效、安静地返回 null——注意是安静失败不报错。递归深度上限是 16 层防止规则之间互相追出死循环。规则如何变成一个真正的文件任务检查通过后调用jake.createTask(file, ...)现场造一个 FileTask名字是 main.o依赖是 [main.c, 你额外声明的前置项]动作把你的回调包了一层并把this.source指向换算出的源文件。到这一步它就是个普通 file 任务了Jake 不再对它的出身有任何特殊对待。进阶玩法覆盖更复杂的目录结构通配符 目录源文件和产物不在同一处时用bin/%.o配src/%.c两处的%一一对应rule(bin/%.o, src/%.c, function () { jake.exec(gcc -c ${this.source} -o ${this.name}); });正则规则目标名复杂、后缀规则表达不了时模式可以直接传 RegExp匹配走test()源文件按匹配部分替换为源模式换算rule(/\.html$/, .txt, function () { jake.exec(markdown ${this.source} -o ${this.name}); });规则链产物还能继续当原料。tex → dvi → pdf 两条规则就够了Jake 会自动沿依赖链往下追到源文件上一节源文件不存在的递归检查正是让链式成立的原因rule(out/%.pdf, out/%.dvi, function () { /* dvipdf */ }); rule(out/%.dvi, src/%.tex, function () { /* latex */ });大项目里记得把规则包进namespace(release, ...)规则是注册在当前命名空间的这样不同环境的同名模式互不干扰。规则匹配失败怎么排查三个真实案例案例一规则写了却报 Unknown task。我跑jake foo:html得到Unknown task foo.html明明定义了rule(.html, .txt, ...)。原因是 foo.txt 既不在磁盘上也没有任何任务或规则能生成它——依赖无解规则被静默丢弃。解法确保源文件已由别的任务先生成或落盘存在。还有个隐蔽变体目标文件已在磁盘上、源文件缺失时Jake 直接把它当普通 file 任务跳过规则症状同样是规则没生效。这些行为都能在 test/integration/rule.js 里逐条复现。案例二加了目录的通配符怎么就不匹配了。bin/%.o对目录部分是严格检查的bin/main.o匹配sub/bin/main.o和bin/main.oo都不匹配。排查口诀目标模式的目录、前缀、后缀三段和实际任务名逐段对齐% 的位置别放错。案例三两条规则都能匹配到底执行哪条matchRule 会把命中的规则逐个覆盖最后留下的是定义在最后一条。所以同时写rule(.o, .c)和rule(.o, .cc)时后写的赢。建议同一后缀只留一条规则要区分场景就用%模式或正则别赌顺序。️结语一句话总结Jake 的规则引擎本质是把声明变成任务——需要时才现算、算不出就放弃干净利落。想继续深挖把 lib/rule.js 通读一遍再看 test/integration/jakelib/rule.jake.js 里通配符、正则、规则链、命名空间的组合用例就够你应付绝大多数多语言、多目录的自动化构建场景了。【免费下载链接】jakeJavaScript build tool, similar to Make or Rake. Built to work with Node.js.项目地址: https://gitcode.com/gh_mirrors/ja/jake创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻