javascript 元编程之-代码修改代码

引言

重构代码是个体力活,特别是在确定重构方案后,剩下就是按方案调整代码,然后进行测试。

如何有好又快的调整到位代码,这是件不容易的事。

简单的代码,可以使用正则表达示进行,如果稍微复杂一点代码,正则表达示就无能为力了。

如我上一篇中讲的修改方法javascript 元编程之 method_missing,我可以在工程中修改一处,如果要修改 50 次接口呢? 我得想想这次重构值不值得了。

还能不能让我随心所欲的写代码了。。。

于是我找到了 jscodeshift,让我能用代码重构我的代码的工具。

jscodeshift 让我有了用代码操作代码的工具。

实现

实例我就使用我上篇文章中的 method_missing 项目,我想把我项目中的接口调用(用url),都调整成 method_missing 调用方式。

如下:


// old
$.ajax('/api/web/project/content/target/mod', {
type: 'post',
dataType: 'json',
data: {
tid: it.targetId,
targetImgId: img.objectId,
pid: pid
}
}).done(function (data, status, jqXhr) {
self.hideLoading();
if (data && data.code === 200 && data.data) {
it.target = data.data
// self.paginationConf.onChange()
}
}).fail(() => { }).always(() => { }) // new
this.$api.update_project_content_target_mod({
tid: it.targetId,
targetImgId: img.objectId,
pid: pid
}).then(function (data, status, jqXhr) {
self.hideLoading();
if (data && data.code === 200 && data.data) {
it.target = data.data
// self.paginationConf.onChange()
}
}).catch(() => { }).finally(() => { })

可以看出新的代码中,把老代码中的 $.ajax 换成了 this.$api,然后用参数生成调用方法名。

最后不仅调整了参数的个数,还调整了参数的值。

想想正则怎么写?

正则应该无能为力。

这时 jscodeshift 就上场了,它能把代码解析成 ast , 然后我们修改 ast,ast 再变成代码。

我的代码如下:


const adapt = require('vue-jscodeshift-adapter'); // 修改 $.ajax
function transform(fileInfo, api) {
const j = api.jscodeshift return j(fileInfo.source)
.find(j.CallExpression, { callee: { object: { name: '$' }, property: { name: 'ajax' } } })
.replaceWith(p => {
const url = p.node.arguments[0]
const setting = p.node.arguments[1]
const urlStr = url.value.replace('/api/web/', '').split('/')
let method = 'get'
let newSetting setting.properties.forEach(i => {
if (i.key.name.toLowerCase() === 'type') {
if (i.value.value.toLowerCase() === 'post') {
method = 'update'
}
} else if (i.key.name.toLowerCase() === 'data') {
newSetting = i.value
}
}); urlStr.unshift(method); return j.callExpression(
j.memberExpression(
j.memberExpression(j.identifier('this'), j.identifier('$api'), false),
j.identifier(urlStr.join('_')), false
), [newSetting])
})
.toSource();
} // 修改 done
function transform1(fileInfo, api) {
const j = api.jscodeshift return j(fileInfo.source)
.find(j.MemberExpression, { property: { name: 'done' } })
.replaceWith(p => {
p.node.property.name = 'then'
return p.node
})
.toSource();
} // 修改 fail
function transform2(fileInfo, api) {
const j = api.jscodeshift return j(fileInfo.source)
.find(j.MemberExpression, { property: { name: 'fail' } })
.replaceWith(p => {
p.node.property.name = 'catch'
return p.node
})
.toSource();
} // 修改 always
function transform3(fileInfo, api) {
const j = api.jscodeshift return j(fileInfo.source)
.find(j.MemberExpression, { property: { name: 'always' } })
.replaceWith(p => {
p.node.property.name = 'finally'
return p.node
})
.toSource();
} module.exports = adapt(transform);
// module.exports = adapt(transform1);
// module.exports = adapt(transform2);
// module.exports = adapt(transform3);

如何使用


# 使用 bash 循环调用
jscodeshift -t src/myTransforms.js filepath

因为我的代码是 vue 的单文件模块,所以我用的了一个第三方插件 vue-jscodeshift-adapter。

总结

jscodeshift 对于大型工程是重构是很有帮助的。可以让你快速改写大量的代码,而且方便测试。

参考链接

  1. vue-jscodeshift-adapter
  2. write-code-to-rewrite-your-code
  3. jscodeshift
  4. astexplorer

javascript 元编程之-代码修改代码的更多相关文章

  1. ES6入门九:Symbol元编程

    JS第七种数据类型:Symbol Symbol的应用场景 11个Symbol静态属性 Symbol元编程 一.JS第七种数据类型:Symbol 在ES6之前的JavaScript的基本数据类型有und ...

  2. 现代c++与模板元编程

    最近在重温<c++程序设计新思维>这本经典著作,感慨颇多.由于成书较早,书中很多元编程的例子使用c++98实现的.而如今c++20即将带着concept,Ranges等新特性一同到来,不得 ...

  3. Spring+SpringMVC+MyBatis整合进阶篇(四)RESTful实战(前端代码修改)

    前言 前文<RESTful API实战笔记(接口设计及Java后端实现)>中介绍了RESTful中后端开发的实现,主要是接口地址修改和返回数据的格式及规范的修改,本文则简单介绍一下,RES ...

  4. 51ak带你看MYSQL5.7源码3:修改代码实现你的第一个Mysql版本

    从事DBA工作多年 MYSQL源码也是头一次接触 尝试记录下自己看MYSQL5.7源码的历程 目录: 51ak带你看MYSQL5.7源码1:main入口函数 51ak带你看MYSQL5.7源码2:编译 ...

  5. u-boot移植(九)---代码修改---NAND

    一.NAND原理 NAND 无地址空间,地址和数据的发送都依赖于LDATA[0:7]这一串数据总线. 不看随机页编程,看到从高位到低位的页,总共分为64个页面,每个页的组成是2K + 64  个byt ...

  6. 不修改代码就能优化ASP.NET网站性能的一些方法 [转]

    不修改代码就能优化ASP.NET网站性能的一些方法 阅读目录 开始 配置OutputCache 启用内容过期 解决资源文件升级问题 启用压缩 删除无用的HttpModule 其它优化选项 本文将介绍一 ...

  7. IDEA 中项目代码修改后不自动生效,需要执行 mvn clean install 才生效

    问题描述 之前项目运行好好的,代码修改完之后会自动编译,编程体验很好. 有一天发现每次修改代码后需要重新使用mvn clean install命令重新编译,异常麻烦. 检查了 IDEA 的配置,已经配 ...

  8. 自修改代码 on the fly 动态编译 即时编译 字节码

    https://zh.wikipedia.org/wiki/自修改代码 自修改代码(Self-modifying code)是指程序在运行期间(Run time)修改自身指令.可能的用途有:病毒利用此 ...

  9. Android之vector代码修改颜色

    前言:google给了很多material design icon,在开发过程中,可以下载下来直接使用,下载地址为https://materialdesignicons.com/ . 1.下载图标,并 ...

随机推荐

  1. html5 iphone input 输入法 弹窗将页面顶起 解决办法

    给 input 添加失焦事件,然后滚动视图 input.search(type="text",@blur="scrollTop") scrollTop(){ w ...

  2. 架构模式: Saga

    架构模式: Saga 上下文 您已应用每服务数据库模式.每个服务都有自己的数据库.但是,某些业务事务跨越多个服务,因此您需要一种机制来确保服务之间的数据一致性.例如,假设您正在建立一个客户有信用额度的 ...

  3. 并查集 --以cogs259为例

    题目链接:http://cogs.pro:8081/cogs/problem/problem.php?pid=pySmxSVgP [问题描述]     或许你并不知道,你的某个朋友是你的亲戚.他可能是 ...

  4. JS小时倒计时

    let t1 = new Date("2019-11-26 15:51:00");// 从什么时间开始 let t2 = ));// 延迟几个小时 let interval = w ...

  5. Ubuntu18.04.3主力开发机使用记录(一)

    现在是2019年12月02日,在公司使用Ubuntu作为开发机器已经有一段时间了 查看主分区创建时间 安装时间8月26 当时周一,一个新的迭代刚刚开始,早上来到公司发现开不了机:Windows报错蓝屏 ...

  6. TestNG使用教程详解(接口测试用例编写与断言)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/sinat_34766121/artic ...

  7. sd卡挂载方法:

    cd mnt//Sdcard创建目录mkdir -m 777 Sdcard//节点挂载mount /dev/msa1  /mnt/Sdcard//抓包./tcpdump -i eth0 tcp por ...

  8. ./configure配置的参数 交叉编译 host,build target的含义

    交叉编译 host,build target的含义:build就是你正在使用的机器,host就是你编译好的程序可以运行的平台,target就是你编译的程序可以处理的平台.这个 build和host比较 ...

  9. SQL Server中bcp命令的用法以及数据批量导入导出

    原文:SQL Server中bcp命令的用法以及数据批量导入导出 1.bcp命令参数解析 bcp命令有许多参数,下面给出bcp命令参数的简要解析 用法: bcp {dbtable | query} { ...

  10. SpringBoot起飞系列-拦截器和统一错误处理(七)

    一.前言 在前边部分我们已经学会了基本的web开发流程,在web开发中,我们通常会对请求做统一处理,比如未登录的用户要拦截掉相关请求,报错页面统一显示等等,这些都需要配置,可以大大简化我们的代码,实现 ...