使用重构件(Codemod)加速 JavaScript 开发和重构-阿里云开发者社区

开发者社区> 玄学酱> 正文

使用重构件(Codemod)加速 JavaScript 开发和重构

简介: 本文讲的是使用重构件(Codemod)加速 JavaScript 开发和重构,在花园里耕耘乐趣无穷,但如果除草不勤,最后收获可能是一团揪心。漏掉一次除草本身可能并无大碍,但积少成多最后会毁掉整座花园。没有杂草的花园让维护工作神清气爽。这个道理对代码库也类似。
+关注继续查看
本文讲的是使用重构件(Codemod)加速 JavaScript 开发和重构,

使用重构件(Codemod)加速 JavaScript 开发

在花园里耕耘乐趣无穷,但如果除草不勤,最后收获可能是一团揪心。漏掉一次除草本身可能并无大碍,但积少成多最后会毁掉整座花园。没有杂草的花园让维护工作神清气爽。这个道理对代码库也类似。

我通常讨厌除草,经常忘记这事的结果就是一团糟。谢天谢地在编程界有像 ESLint 和 SCSS-Lint 这样的好东西提醒我们勤理代码。但是如果面对的是大段大段的历史代码,光是想想要手动调整成百十千万的空格和逗号,悲伤便逆流成河。

8年来有几百万行 JavaScript 代码进入 Airbnb 的版本控制系统中。同时,前端界风起云涌。新功能,新框架,甚至 JavaScript 本身都在快速进化。尽管遵循良好的代码风格会让变革少些疼痛,但还是很容易累积出不再遵循最新"最佳实践"的巨大代码库。每一处代码风格的不一致都是一棵杂草,唯一归宿就是被铲掉,化作春泥更护花,好让开发团队保持高效。来看看我们花园现在的样子:

我执着于增加团队效率,也深知保持一致性的代码能增速团队反馈和减少无效沟通。我们最近开始了一个整理代码的项目,准备把许多陈旧的 JavaScript 代码转化得符合我们的代码风格,亦使我们的代码检验器有更多用武之地。若全都手动完成,会是件十分无聊和耗时的苦差,所以我们借助工具帮我们自动化此工作。虽说使用 eslint -fix 是个不错的开始,但它现在所能有限。尽管他们最近开始接受修复所有规则的PR,也准备构建 JavaScript 的具体语法树,但等这些功能完成还需要些时间。感谢上苍我们发现了 Facebook 的 jscodeshift,这是一个重构工具(协助大型代码库的自动化重构)。如果代码库是个花园,那么 jscodeshift 就像个除草机器人。

此工具将 JavaScript 解析为一棵 抽象语法树,并在其上进行变换,然后输出符合指定代码风格的新 JavaScript 代码。转换过程是用 JavaScript 本身实现的,所以我们团队很乐意使用此工具。寻找或是创建转换代码能加速我们乏味的重构,让我们团队能够专注于更有意义的工作。

运行几个代码重构件后,我们的花园整洁了点:

策略

鉴于多数重构件能在一分钟内处理上千文件,我发现它是我打发主要工作的等待间隙(例如等代码审查)的不错选择。它帮我最大化提升了工作效率从而让我能在更大和更重要的项目中有所建树。

大规模重构主要面临四大挑战。沟通、正确性、代码审查以及冲突合并。我采取以下策略来应对这些挑战。

重构件不总是能产出我需要的结果,因此对其结果的审查和改动十分重要。以下命令在跑完重构件后很有用:

git diff
git add --patch
git checkout --patch

保持每个提交和 PR 在小的体量是好的做法,对于重构件也不例外。我通常一段时间内进行一类重构,减少代码审查和冲突合并的麻烦。我亦经常让重构件自动提交重构结果,而后若有必要,再手动清理。这样在衍合分支时解决冲突会轻松点,因为我可以使用

git checkout --ours path/to/conflict

然后在那个文件上再运行一次重构件,之后也不会弄乱我自己的手动提交。

有时重构件生成了很大的变动,我觉得在此情况下根据目录或文件名来分成数次提交或 PR 会比较好。例如,一个提交重构 .js 文件,另一个提交重构.jsx 文件。这样之后代码审查和冲突合并会相对轻松一点。谨遵 Unix 哲学,分批进行文件重构简单到仅需调整 find 命令的参数:

find app/assets/javascripts -name *.jsx -not -path */vendor/* | \
  xargs jscodeshift -t ~/path/to/transform.js

为避免和别人的代码冲突,我通常在周五早上才推送我的重构件生成的提交,然后周一赶在大家开始工作之前进行衍合和合并。这样其他人周末放假前不被你的重构件阻碍,能好好整理自己的工作成果。

我们用得顺手的重构件

虽然此工具还比较新,已然有了一些实用的重构件。以下是一些我们成功上手了的。

轻量级重构件

以下是些用着不那么痛苦的,立刻上手感受成效。

js-codemod/arrow-function: 谨慎地把函数转为箭头函数

使用前:

[1, 2, 3].map(function(x) {
  return x * x;
}.bind(this));

使用后:

[1, 2, 3].map(x => x * x);

js-codemod/no-vars: 将 var'_ 安全转化为 _const_ 或 _let`

使用前:

var belong = 'anywhere';

使用后:

const belong = 'anywhere';

js-codemod/object-shorthand: 把对象字面量转为 ES6 的简写表示。

使用前:

const things = {
  belong: belong,
  anywhere: function() {},
};

使用后:

const things = {
  belong,
  anywhere() {},
};

js-codemod/unchain-variables: 分离连续声明的变量。

使用前:

const belong = 'anywhere', welcome = 'home';

使用后:

const belong = 'anywhere';
const welcome = 'home';

js-codemod/unquote-properties: 移除对象属性的引号。

使用前:

const things = {
  'belong': 'anywhere',
};

使用后:

const things = {
  belong: 'anywhere',
};

重量级重构件

以下重构件或是改动很多代码引发合并和冲突之痛,或是需要更多后续的手动更改以保证代码还能看得下去。

react-codemod/class: 把 React.createClass 转为 ES6 class 的实现。

此重构件在有 mixin 的时候不会变换,在类似于 propTypes、默认 props 和 initial state 定义这样的必要转换做得很好,还能将事件回调函数绑定到构造器上。

使用前:

const BelongAnywhere = React.createClass({
  // ...
});

使用后:

class BelongAnywhere extends React.Component {
  // ...
}

react-codemod/sort-comp: 根据 ESLint react/sort-comp rule 重新组织 React component 的方法声明顺序。

这个会调整大量代码,git 不会自动合并冲突。我觉得在使用此重构件前最好最好跟队友打个招呼,在不太容易发生冲突的时候(例如周末)进行重构。当我衍合此重构的提交且遇上冲突的时候,我会:

git checkout --ours path/to/conflict

然后再运行一次重构件。

使用前:

class BelongAnywhere extends React.Component {
  render() {
    return <div>Belong Anywhere</div>;
  }

  componentWillMount() {
      console.log('Welcome home');
    }
  }

使用后:

class BelongAnywhere extends React.Component {
  componentWillMount() {
    console.log('Welcome home');
  }

 render() {
    return <div>Belong Anywhere</div>;
  }
}

js-codemod/template-literals: 把字符串的串联转换为字符串模板字面量表示。

因为我们多处用到字符串串联,而且这个重构件尽其所能把所有字符串都转成模板,我发现很多转换结果其实并不合理。我之所以这个重构件放到"重量级"列表里,是因为它会改动很多文件,而且之后我们还得进行大量的手动修改才能得到满意的结果。

使用前:

const belong = 'anywhere '+ welcomeHome;

使用后:

const belong = `anywhere ${welcomeHome}`;

资源

若你想写自己的重构件,或是看看它能做什么,可以看下下面的资源。

影响

在使用了一些现成的和我们自己写的并贡献给社区的重构件之后,我们的旧代码质量获得很大的提升。我不费吹灰之力便重构了40000行代码,将旧代码调整至符合 ES6 代码风格。花园焕然一新,我们之后的工作也更有效率和乐趣。

使用已有的重构件仅是牛刀小试,只有在你拿起键盘写出自己的重构件时,真正的能量才会释放。无论是对代码风格重构,或是对失效 API 的调整,重构件都能大显身手,你可以尽情想象发挥。这些技术值得学习投入,能省下你和使用你的项目使用者很多时间精力。






原文发布时间为:2016年06月12日

本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《JavaScript开发框架权威指南》——导读
JavaScript社区中正在迈开近乎狂热的创新步伐,虽然充满了无穷的魅力,但也提出了自己的独特的挑战。JavaScript的生态系统包括库、框架以及工具,都在剧烈地成长。过去针对任何给定问题可能只有少量的解决方案,而今已经有许多解决方案可以选择,并且其数目日益增长。
1780 0
基于ThingJS开发的WebGL H5停车场三维可视化管理Demo
随着社会的发展,城市中的汽车越来越多。车辆集中存放管理的场所被人类提出车辆进出的秩序、车辆存放的安全性、车辆存放管理的有偿性等要求。停车场系统应用现代机械电子及通讯科学技术,集控制硬件、软件于一体。随着科技的发展,停车场管理系统也日新月异,目前最为专业化的停车场系统为免取卡停车场。
3198 0
使用重构件(Codemod)加速 JavaScript 开发和重构
本文讲的是使用重构件(Codemod)加速 JavaScript 开发和重构,在花园里耕耘乐趣无穷,但如果除草不勤,最后收获可能是一团揪心。漏掉一次除草本身可能并无大碍,但积少成多最后会毁掉整座花园。没有杂草的花园让维护工作神清气爽。这个道理对代码库也类似。
1871 0
《JavaScript设计与开发新思维》——第1章 (重新)介绍JavaScript 1.1 什么是JavaScript
今天的JavaScript是一种被误解的编程语言,从JavaScript所能做到的,到它不能做到的,再到JavaScript不是什么(JavaScript不是Java),关于这种当今Web的核心技术有许多的混淆。
1672 0
《JavaScript开发框架权威指南》——2.7 小结
本节书摘来自异步社区《JavaScript开发框架权威指南》一书中的第2章,第2.7节,作者:【美】Tim Ambler , Nicholas Cloud著,更多章节内容可以访问云栖社区“异步社区”公众号查看
1403 0
使用IoT Studio经济高效地完成物联网应用开发(含DEMO)
IoT Studio原Link Develop,是阿里云整合在应用开发领域的丰富经验倾力打造的一站式、低成本、高稳定、易定制的物联网生产力工具,旨在帮助用户经济高效的完成物联网应用开发。
11705 0
+关注
玄学酱
这个时候,玄酱是不是应该说点什么...
20710
文章
438
问答
文章排行榜
最热
最新
相关电子书
更多
《Nacos架构&原理》
立即下载
《看见新力量:二》电子书
立即下载
云上自动化运维(CloudOps)白皮书
立即下载