布景
开发保护规划较大的前端项目,不免时不时需求进行一些代码重构作业。举一个简略的:
- 有一个 npm 包
an-npm-package-containing-constants
,用于保护项目埋点时运用的字符串常量,其代码主要内容如下:
export const Constanteslint插件sForTrack = {
Track1: 'track_in_scene_1',
Track2:eslint标准 'track_in_sceNPMne_2',
...
};
- 调用方以如下方法运用此包:
import { ConstantsForTrack } from 'an-npm-package-containi测验手机是否被监控ng-constants';
track(Coeslint什么意思nstantsForTrack.Track1, ...othgithub中文官网网页erParams);
- 跟着业务迭代,此包体积不断增加,现已开端测验纸怎样看是否怀孕影响到项目的全体功能。一eslint装备切业务的埋点标识字符串都会合于此包中,因而咱们改动代码的导出方法:
export const Track1 = 'track_i女配没有求生欲藤萝为枝n_sceNPMne_1';
export const Track2 = 'track_in_scene_2';
...
- 各业务经过按需引进,控制代码体积:
import { Track1 } from 'an-npm-package-containing-constants/es/constants';
trgithub中文官网网页ack(Track1, ...otherParams);
包内代测验屏幕的图片码的重构不算特别杂乱,可是要对项目内各处引进该包以及埋点调用的方法进eslint怎样读行修改java模拟器,仍是一件比较头疼的工作。IDE 的大局替换功用显着无法担任这一作业;人工替换违背了程序员的 DRY 原则,过程单调且有或许犯错;写一个根据正则的替换脚本倒不是不可行,仅仅这样的脚本一般可保护性和可复用性都不太好,而且或许存在一些 bad case(如或许会匹配到注释或字符串字面量中的内容、需求考虑不同代码风格的状况)。
此刻笔者想起了之前听说到的一个叫作 codemod 的概念,据说是一种对代码进行批量修改github敞开私库操作的方法;而且 react、vue 还有 Ant Design 都java基础知识点供给了自己的官方 codemod,以帮助用户迁移到更女配每天都在为国争光新版别,避免其面对晋级新版别后手动处理接口改测验变的痛苦。这次不妨尝尝鲜,也算是为今后这种类似的重构作业先踩踩坑。
相ESLint关概念简介
Codemod
Codemod is a tool/library to assist you with large-scale codebase refactors that can be partially automated but still require hu女配每天都在抱大腿我要成仙man oversight and occasional intervention.
Codemod 是一女配每天都在为国争光个诞github打不开生于 Facebook 内部的概念,能够理解为 “code modification” 的缩写。如官方介绍所述,codemod 针对的场景是规划较大的代码库中的重构作eslint报错业。当某个在代码中被频繁运用的接口发生了无法向前兼容的严峻改变,codemod 供给了快速且可靠的、半自动的东西来对代码库中全部相关代码进行重构,以帮助开发者对代码进行快速迭代java模拟器。
jscodejavahdxxshift
jscodeshift 是一个根据 codemod 理念的 JavaScript/TypeScript 重构东西,其原理是将 JS/TS 代码解析为笼统语法树(Abstract Syntax Tree,A测验纸怎样看是否怀孕ST),并供给一系列用于拜访和修改 AST 的 API 以完成自动化的代码重构。jscodeshift 将 babel parser、ast-types(用于快速创立新的 AST 节点)和 recast(保护生成代码的代码风女配明天见格信息)三大东西整合在一起,供给了简练便利的操作接口;一起它还供给了多任测验工程师务并行实行的功用,使其关于海量代码文件的重构操作能够并行工作,充分利用多核 CPU 算力,缩短重构使命实行时刻。
笼统语法树
信任咱们GitHub都在编译原理的课程中了解过笼统语法树的概念,这儿先引用一段维基百科上的描述:
在计算机科学中,笼统语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种笼统标明。它github打不开以树状的方法表现编程言语的eslint语法语法结构,树上的每个节点都标明源代码中的一种结eslint标准构。之所以说语法是“笼统”的,是由于这儿的语法并不会标明出实在语法中呈github官网现的每个细节。
咱们再以一段简略代码为例:
if (1 + 1 == 3) {
alert('time to wake up!');
}
来愈加详细地了解一下笼统语法树是什么姿态:(由 http://nhiro.org/learn_language/AST-Visualization-on-browser.html 生成)
在 JavaScript 工程领域中,不github直播渠道永久回家仅仅只需 JavaScript 引擎解析代码会涉及到 AST,在代码转译(babel)、静态剖析(eslint)、打包构建(webpacgithub下载k、rollup…)中,都会将代码解析为 AST 以作进一步的操作。
着手开干,写一个 codemod
jscodeshift 虽然很好很强壮,但Java是官方文档供给的信息关于帮助咱们快速写出一个 codemod测验郁闷症 来说却相对有限。因而了解把握 jscodeshift 最好的方法便是 get hands dirty,参看一些已有的 cod测验怀孕的试纸图片一深一浅emod 脚github官网本和网上的文章,自己写一个 codem测验工程师od。咱们以处理布景一女配每天都在抱大腿节提及的这个问题为例,javahdxx写一个 codemod 来结束 an女配每天都在抱大腿-npm-package-containing-constants
引进和运用方法的修改。
在着手之前java面试题,先介绍一个超强github下载的 AST测验纸怎样看是否怀孕 可视化东西—— AST Explorer。如下图所示,咱们把想要修改的代码粘贴在左边,即可即女配满眼都是钱时在右侧看到解析代码取得的语法树并查看其女配明天见间各个节点的特征。经过这个东西,咱们能够对 AST 有一个愈加直观的知道;在编写 codemod 的过程中,咱们java面试题也能够通测验网速过这个东西快速定位需求修改的节点。翻开 “Transform” 开关,你还能够直接在浏览器里测验纸怎样看是否怀孕书写 codemod 脚本,并即时看到 codemod 转化后的效果。
经过对代码及其 AST 的大致剖析,咱们能够把替换作业拆解为以下几步:
- 遍历文件,挑选出引进了 “an-npm-package-containing-github敞开私库constants” 的代码文件;
- 查找挑选出的文件中全部对
ConstantsForTrack
方针成员的拜访,并将ConstantsForTrack
成员拜访表达式直接替换为常量名的表达式; - 收集代码中运用的常量名,生成新的 import 句子并替换旧句子。
现在咱们能够开端编写 codemod 了!根据官方文档,codemod 代码需导出一个函数,测验郁闷程度的问卷jscodeshift 在工作此函数时会经过参数注入 API 和一些相关信息。由此测验郁闷症咱们能够写出一个 codemod 的开端的框架:
mogithub永久回家地址dule.exports = function (
filGitHubeInfo, // 其时处理文件的相关信息,包含文件途径与内容
api, // jscodeshift 供给的接口
options // 经过 jscodeshift CLI 传eslint语法入的参数
) {
const { source, path } = fileInfeslint插件o;
const { jscodeshift: j } = api;
const rooteslint封闭 = j(source); // 解析代码取测验郁闷症得 AST
// 在这儿编写操作 AST 的代码
return root.toSource({ quote: 'single' }); // 将 AST 转化为代码字符串后回来
}
需求留意的是,代码毕竟的 toSource()
函数能够传入一些代码风格相关的装备。recagithub怎样下载文件st 在解析代码时,会将代码风格相关信息保护在语法树中,在 toSource()
过程中再将代码还原成原本的姿态。而在代码转化为语法树后新刺进的节点并没有这些详细的代码风格信息。详细怎样装备这些代码的风格能够参看这个文件里的接口定义。
第一步:挑选需测验怀孕的试纸图片一深一浅求修改的文件
由于咱们只女配没有求生欲需重视引进了 an-npm-packeslint装备age-containing-constants
的代码文件,所以咱们先在 AST Explorer 里调查解析 import { ConstantsForTrack } from 'an-npm-package-containing-constants';
句子取得的 AST 子树github打不开,能够发现这棵子树的根结点类型是 “Impojava游戏rtDeclaration”,节点中 source 特征的 value 字段便是咱们所寻觅的节点特征 “an-npm-package-containing-constants”。
接下来便是编写代码将这类节点挑选出来。女配满眼都是钱鉴于 A测验怀孕的试纸图片一深一浅ST 的数据github敞开私库结构特征,一般的语法解析器 (parser) 以及 recast 供给的 API 都根据拜访者方法来对 AST 进行遍历 (traversal)。jscodeshift 根据 Collection 的概念对 API 进行了进一步封装,令运用者对 AST 节点的挑选及github中文社区修改操作变github下载得愈加简略。一些常用的 Collection API测验屏幕的图片 咱们会在接下来的实践过程中用到,完好的 API 列表能够参看以下源码:
集结根本操作:github.com/facebook/js…
AST 节点拜访与修改:github.com/facebook/js…
这儿咱们运用 find()
从语法树中取得javahdxx政策节点的集结,若集结为空,则越过此文件。代码如下:
const trackConstantsImportDeclarations = root.find(j.ImportDeclaration, {
source: { value: 'an-npm-package-containing-constants' }
});
if (!trackConstantsImportDeclarations.lgithub打不开ength) {
// 回来 undefined 标明此文件无需修改
return;
}
第二步:收集代码中全部相关常量的拜访并进行替换
咱们再来剖析一下 ConstantsForTrack.eslint怎样读Track2
:
能够看到这个表达式被解析成了一个 MemberExpression 类型的节点,该节点的 object 特征是一个 name 为 “Coeslint什么意思nstantsForjava环境变量装备Track” 的 Identifier 节点,property 是一个 name 为 “Trac女配美炸天k2″ 的 Idengithub是干什么的tifier 节点。
咱们要把全部 ConstantForTrack.[constant nESLintame]
替换为 [constant name]
,只需运用 jscodeshift 供给的 replaceWi测验郁闷程度的问卷th()
接口,把相应的 Me测验郁闷症的20道题mbeeslint装备rExpression 节点替换为其 property 特征中的 Identifier 节点即可。别的为了下一步将这些常量引进进来,咱们需求把这些 Identifier 的 name 特征收集起来。代码如下:
let usedKeys = [];
const trackConstantsMemberExpressions = root.find(j.MemberExpression, {
objectGitHub: { name: 'ConstantsForTrack' }
});
trackConsta测验郁闷症的20道题ntsMembe测验rExpressions.replaceWith((nodePath) => {
// replaceWith 在遍历集结的回调函数中传入的参数类型是 Node女配没有求生欲藤萝为枝Path
// NodePath 除了节点本身的信息测验工程师外eslint报错还包含节点的上下文信息,因而需求先把节点从中取出来
const { nodegithub下载 } = nodePath;
const keyId = node.property;
if (keyId.name) {
usedKeys.push(keyId.name);
retugithub永久回家地址rn keyId;
}
});
if (!usedKeys.length) {
return;
}
第三步:替换 import 句子
这一女配每天都在抱大腿步的政策是将 import { ConstantsForTrack } fromJava 'an-npm-package-ceslint语法ontaining-constants';
替换为 import { Track2测验网速 } from 'an-npm-package-containing-constants/es/constants';
。咱们先剖析一下后者的语法树:
可见 ImportDecljava怎样读aration 的 specifiers 特征记录了 import 句子所引进的内容,以 ImportSpecifier 数组的方法标明。现在咱们能够从头结构一个新的 ImportDeclgithub是干什么的aration 节点,代码如下:
usedKeys = [...new Set(usedKeys)];
const k女配每天都在抱大腿我要成仙eyIds = use女配明天见dKeys.map((key)eslint插件 => j.imESLintportSpecifiejavascriptr(j.identifiereslint怎样读(key)));
const trackConsjavahdxxtantsEsImportDeclaration = j.importDeclaration(
keyIds,
j.literal("an-npm-package-contaiESLintning-constants/es/男配每天都在体内成绩constants")
);
// 替换原来的测验工程师 import 句子
trackConstantsImportDeclarations.at(0).replaceWith(
() => trackConstantsEsImportDeclaration
);
jscodeshift 根据 ast-types 供给了各种节点的构建接口,接github下载口方法如以上代码所Java示,以驼eslint封闭峰命名法(小写字母开端)方法标明,与第一步中用于挑选的github打不开节点类型(帕斯卡github打不开命名法标明,大写字母开端)区别开来。不同节点构建方法的详细参数能够参看源代github官网码,AST Explorer 中也供给了相关代码提示。
至此咱们的 codemod 脚本现已结束,能够测验实行一下:(在工作之前,你需求保证现已经过 npm insgithub永久回家地址tall -g j测验郁闷程度的问卷scodeshift
大局设备上了 jscodeshift)
自动重构顺畅结束!这儿介绍几个常用的github敞开私库 CLI 参数,愈加详细的信息能够参看这儿:
-c, --cpus=N 最多开启 N 个子进程并行工作 codemod 脚本
(默认为 max(CPU 总核心数 - 1, 1))
-d, --(no-)dry 测验工作,不对文件作实践修改(默许封闭)
--extensions=EXT 需求处Java理的文件扩展名(多个用“,”隔开,默认为 js)
--parser=babel|babylon|flow|ts|tsx
解析文件运用的 parser,默认为 babel
-t, --transform=FILE codemod 脚本的途径或 URL,默认为 "./transform.js"
-v, --verbose=0|1|2 展现测验怀孕的试纸图片一深一浅 codemod 实行过程中的相关信息
总结
文章的毕竟,总结一下运用 jsco测验手机屏幕的图片deshift 常用的 API 以及相关的参看文档和源码:
- AST 的查找与挑选:
find()
、filter()
- Collection 拜访:
get()
、at()
(两者区别在于前者回来NodePath
,后者eslint封闭回来Collection
) - 节点的刺进与修改:
replaceWith()
、insertBefore()
、insertAfter()
Collection 常用 API:
https://github.com/faceeslint标准book/jscodeshigithub是干什么的ft/blob/master/src/Collectiojava模拟器n.js
https://g测验手机屏幕的图片ithub.cojavascriptm/facebook/jscodeshift/blob/master/src/collections/Node.jsAST 节点构建参数:
https://github.com/benjamngithub怎样下载文件/ast-types/测验郁闷程度的问卷tree/java基础知识点master/defjscodeshift CLI 参数:
https://github.com/facebook/jscodeshift#usage-cli
希望本文能够为咱们的代码重构作业供给一些启示,帮助咱们从一些重复的代码修改作业中解放出来。
参看
facebook/jscodeshift: Agithub怎样下载文件 Jgithub怎样下载文件avaScript codemod toolkit.
Effective JavaScript Codemods
ChristophNPM Nakazawa: Evolving Complex Systems Incremengithub直播渠道永久回家tally | JSConf EU 2015
Fun with Cgithub怎样下载文件odemod & ASTJava
Write Code to Rewrite Your Code: jscodeshift
jscodeshift 简易教程eslint插件
jscodeshift 入门攻略
欢java面试题迎重视「 字节前端 ByteFE 」
简历投递联络邮箱「tech@bytedance.com」