 
 我们知道 eslint 支持 fix,隐藏当添加了 --fix 参数部分 rule 可以自动修复问题。的算 有没有想过,可用这种功能是面试怎么实现的?babel 也能转换代码,它和 eslint 生成代码的法题原理一样么? babelbabel 分为 parse、transform、隐藏generate 3 步。的算  在 transform 阶段转换完 AST 代码之后,可用在 generate 阶段会递归打印 AST 成目标代码。面试 generate 的法题原理就是递归根据每个 AST 的信息拼接字符串:  
 所以我们在插件里面改动了 AST,最终的隐藏代码也会改。 eslinteslint 的的算 rule 可以对 AST 进行检查,然后通过 context.report 报错,可用还可以指定如何修复: 自定义 rule 格式如下: module.exports = {      meta: {          fixable: true      },面试      create(context) {          return {             // 指定 AST 的类型             ObjectExpression(node) {                 // 一系列检查                 context.report({                     node,                     message: xxx 有错误,                     loc: node.loc,                     *fix(fixer) {                         yield fixer.replaceTextRange([rangeStart,rangeEnd], 替换的文本);                     }                 });              }          };      }  };         其中 fix 选项就是用于问题自动修复的,通过 fixer 的法题 api。 fixer 有这些 api 可用: insertTextAfter(nodeOrToken, text); insertTextAfterRange(range, text); insertTextBefore(nodeOrToken, text); insertTextBeforeRange(range, text); remove(nodeOrToken); removeRange(range); replaceText(nodeOrToken, text); replaceTextRange(range, text);         特别容易记,就是增、云服务器删、改 3类,增分为在前面插入和在后面插入,每一类都支持基于 token 来修改 text 或者基于 range(下标范围)。 AST 中每个节点都保留了 range 的信息,也就是在源代码的下标是从哪到哪,这样就可以根据 range 来修改代码,或者根据 AST 查到 range 再去修改代码。  
 那知道了对什么 range 做什么操作之后,是怎么自动修改代码的呢? 下面是 eslint 中 fix 代码的源码: // 源码 const originalText = sourceCode.text; // 第一个 range 的开始 const start = fixes[0].range[0]; // 最后一个 range 的结束 const end = fixes[fixes.length - 1].range[1]; // 替换的文本 let text = ""; let lastPos = Number.MIN_SAFE_INTEGER; for (const fix of fixes) {     if (fix.range[0] >= 0) {         // 截取 range 的左边的字符串,从当前 range 和 上一个 range 的右边位置取大的         text += originalText.slice(Math.max(0, start, lastPos), fix.range[0]);     }     // 拼接上修复的文本     text += fix.text;     // range 右边的位置     lastPos = fix.range[1]; } // 用拼接的字符串替换 range 内的字符串 text += originalText.slice(Math.max(0, start, lastPos), end);         其中比较有意思的一个点是当两端 range 有交集的时候:  
 每一个 fix 都是香港云服务器对一个线段(range)内文本的修复,当有交集的时候怎么处理,这其实可以作为一个算法题来考核候选人了。 从左到右应用 fix,然后记录当前的 rangeRight,应用下一段的时候就取 rangeLeft 和上一个 rangeRight 的最大值作为 rangeLeft。 把这个问题抽象出来之后还是一个比较有意思的算法题,我觉得用来面试比较不错,而且有真实的应用场景。 聊回正题,fix 功能的实现就是对每段 range 修改的文本进行拼接,然后替换源码字符串就可以了。 总结babel 和 eslint 都可以修改代码,babel 是操作了 AST,打印代码的时候就会生成不同的代码,而 eslint 则是一部分 rule 支持自动 fix,当开启了 --fix 的时候就会自动修复。免费信息发布网 babel 生成代码的原理是递归打印 AST,拼接字符串,所以改了 AST,生成的代码就改了。 eslint 修复代码的逻辑是对某段 range 的文本做替换,之后拼接,这个与 AST 无关,所以 eslint 的 fix 功能是可选的。 比较有意思的是 eslint 的多个 rule 返回的对多段range 的修改如何应用到对代码修改上,当有交集的时候怎么办,我觉得这个问题可以作为算法题来考查面试者了。  |