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. vim在文件末尾增加内容

    1.跳到文本的最后一行:按“G”,即“shift+g” 2.跳到最后一行的最后一个字符 : 先重复1的操作即按“G”,之后按“$”键,即“shift+4”.3  o:在当前行下面插入一个新行O:在当前 ...

  2. JAVA 基础编程练习题4 【程序 4 分解质因数】

    4 [程序 4 分解质因数] 题目:将一个正整数分解质因数.例如:输入 90,打印出 90=2*3*3*5. 程序分析:对 n 进行分解质因数,应先找到一个最小的质数 k,然后按下述步骤完成: (1) ...

  3. C++typedef的详细用法

    转自知乎的一段解释: 作者:知乎用户链接:https://www.zhihu.com/question/29798061/answer/144423125来源:知乎著作权归作者所有.商业转载请联系作者 ...

  4. java数据结构之LinkedList

    一.LinkedList源码注释 //LinkedList源码 jdk版本1.8.0_121 public class LinkedList<E> extends AbstractSequ ...

  5. PhpSpreadSheet 读写excel文件

    phpoffice 系列很好用.PhpSpreadSheet取代了原先的phpexcel,用来处理excel文件 https://phpspreadsheet.readthedocs.io/en/la ...

  6. elasticsearch 常用查询 + 删除索引 + 集群状态诊断

    1.多条件查询 curl -X POST \ http://10.0.0.42:9200/addressbook_user/_search \ -H 'cache-control: no-cache' ...

  7. FTL-SLC&MTC&TLC

    1.博客 SLC.. http://diybbs.zol.com.cn/67/231_661182.html 2.FTL --作者在普及了一些FTL基本知识后,主要分析了在linux上实现的途径 ht ...

  8. IT架构的本质

    老僧三十年前未参禅时,见山是山,见水是水. 及至后来,亲见知识,有个入出,见山不是山,见水不是水. 而今得个休歇处,依前见山只是山,见水只是水. 参禅的三重境界在IT技术圈同样适用,初学者感叹每个产品 ...

  9. #学习笔记:CentOS7学习之十三(2):磁盘介绍与管理

    1.磁盘分区工具与挂载 1.1 硬盘分区符认识: MBR概述:全称为Master Boot Record,即硬盘的主引导记录. 硬盘的0柱面.0磁头.1扇区称为主引导扇区(也叫主引导记录MBR).它由 ...

  10. vsftpd下载文件时内容乱码

    windows客户端访问Linux服务端的ftp并下载文档时,内容会出现乱码,这是由于vsftpd文件服务器不支持转码功能 通过java FTPClient下载 方法为 OutputStream is ...