TypeScript——Web前端开发的救赎

JavaScript代码有多烂?
    入职到现在做了6年js开发了(包括之前的2年一共写了8年js),现在我们团队有10几20号人写js(纯js开发),需要维护的js代码有40-50万行,不得不承认js代码的维护成本很高,或者直接说“js代码就是垃圾代码”,现在我们仍每天在制造大量的垃圾。
    javascript开发要克服很多缺陷,作为团队建设,尽管我们经常组织走读代码、抓函数变量命名、抓各种规范,希望使大家写代码的风格一致,但还是会产生很多垃圾代码,原因大家都知道(项目工期是最大的敌人);而这些垃圾很难会有重构的机会,不一定是有bug,只是难以读懂,很难由别人去添加或者修改功能。由于JS是弱类型且运行时编译的脚本,从工具层面上很难对代码重构提供帮助:一个函数或变量,很难知道它被什么地方调用着(新晋IDE Webstorm做的不错但是远远不够),所以即使是重命名一个变量(你敢不敢用全文批量替换?),都会有很大风险,你会畏惧这种改动;开发工具甚至无法帮你检查拼写错误,也就是说,你改动的代码至少必须运行一次(代码要高度覆盖运行),否则你根本就不能确定重构代码没有产生影响。完整的重构流程可以减少风险,但是规划版本、建立分支、分配测试资源等都是成本。所以简单到像函数命名这么小的问题,但也就那样吧,只要没人追究就不必改了,久而久之……
    曾经觉得,只要贯彻大家写单元测试,写好注释生成文档,就能使项目可维护度大大提示(确实也有帮助),但是这些测试代码、注释本身也有很大的编写成本,在工期紧张的时候根本无暇顾及(除非你本身非常熟悉写单元测试和优雅的代码结构及注释,但是这个素质培养周期太长了),而这些工作很难从后期补救(垃圾代码的特征就是很难被程序测试,很难组织成文档T_T),还有一个问题更是纠结,测试代码也需要维护,也有垃圾的测试代码,这就变成一个死循环无解了。
    JavaScript的替身
   JS“烂”,引发业界的各种吐槽,很多团队在发明JS的替身,如:coffeescript,google的dart,以及微软的typescript等等,这三种代码都可以直接编译成js。这其中,coffeescript语法简捷(同时使用缩进替代花括号),受到Ruby、Python开发人员的追捧。Google的Dart,只能说它是一门全新的语言,Google为它开发虚拟机(内置在Chrome中),也可以作为服务端开发语言,但是对js的兼容程度比较差,一个hello world编译成js居然会有3万行代码(前端js可是惜字如金),所以Dart作为前端web开发,只能算是它的业余爱好。微软的typescript(下面简称ts)则完全另辟蹊径,目前没有直接运行ts的虚拟机(以后可能会有),只能编译成js运行,也就是说它适用于任何能运行js代码的场景作为开发语言。
     微软的“阴谋”?
    微软对操作系统的把持,以至于她失去了互联网时代的第一桶金,直到现在微软都不是一家互联网公司。早期微软对js这门语言有自己的独特见解:“js是一门简洁,c风格语法的脚本工具,js能做的vbscript也能做,所以ie里的静态脚本和asp的动态脚本都可以同时用vbs和js来写(可是vbs是微软的亲儿子啊),到后来.net生态都有JS.NET这种东西”。对于web前端开发,在微软强大的visual studio开发环境下,js的支持度却如屎一样渣,甚至像Dreamweaver这种业余编码工具都能够爆掉vs(调试功能除外),直到vs2012才有了飞跃性的改变。
    不可否认,微软仍是这个星球上开发工具做的最好的公司。2009年开始的HTML5潮流使得微软不得不重视JS开发,所以后来windows 8选择js作为默认的app开发语言,vs2012对js的支持度终于达到专业选手的级别(从无数细节上反映),可是微软内部不会不知道js存在缺陷,它不适合构建大规模应用开发。所以我猜想:TypeScript的发明是在2010年就开始了(甚至更早),而ts的诞生,象征着微软对js的态度从暧昧->拥有->到超越的3级跳跃。
     TypeScript的闪亮登场
    2012年10月首度对外公布typescript(当时已经是0.7?的版本)同时开源,ts的编译器是用js编写的(后来改成ts?),可以在线编写。
    与coffeescript这些屌丝开发语言不同,ts的团队是由C#之父安德斯·海尔斯伯格带领,响应内部呼声而创建的工具语言(内需转出口),从无数细节和舒适度上,可以让你的js项目完美迁移到ts上。1年前刚推出的时候,我只是觉得眼前一亮,然后就没有然后了,过了一年,在我休假的这段时间内重新研究,有了翻天覆地的改观,让我用一句话形容TS: Typescript是微软内部出品的,用actionscript的语法在写js的一门新语言,vs用类似对c#的支持度来服务ts的开发,ts团队做了很多努力可以让你的js项目无痛升级到ts环境,使用ts开发,可以大量减少你检查语法、查阅API、调试代码的时间,ts能将你从开发js的痛苦深渊中解脱。以下从各方面描述ts为我们带来的便利。
     JS的初学者吐槽
    js普及,支持的开发工具众多,大多数开发人员使用他们最熟悉的编辑器来写js代码(有用vim的,美工用dreamweaver,有的java开发人员用eclipse,.net开发人员用vs……),学生时代我用windows记事本写js(大多数人不会懂机器慢的人喜欢用记事本体验流畅感那种心情,后来换了电脑,用vs开发让我有种暴发户的感觉,主要原因还是因为我写c#),当然所有开发工具都不会告诉你哪个变量拼写错误,当你花几个小时才定位到是拼写问题的时候……可能论坛上骂js垃圾的人就有你的身影,我刚开始学的时候也不知道怎么调试,硬是一行行的alert(),现在知道那叫插桩代码(某些情况我现在还会用),以前哪有chrome这么强大的东西,当然我没工作前也不知道vs能调试js代码。
   总结一下初学者的吐槽原因:1.工具支持度差,容易犯低级错误;2.什么BOM DOM API基本不熟,标准化的东西文档差劲,并且需要花大量时间学习各种浏览器下的差异化,大多数人觉得那是浪费生命;并且很多年过去了,工具、类库支持度日益强大的今天,仍有不少人对js还是原来最初的印象。ts是“强类型”的js,不会让你为这些低级错误浪费时间。
   写ts你 不用烦恼用什么开发工具了,直接就是vs(当然这也是硬伤,用linux的人伤不起,对微软反感的人伤不起,机器配置差伤不起,window xp伤不起,vs2012要win7以上才能安装,不过现在Webstorm和vim都已经添加了对Typescript的支持,虽然可能不及vs强大,但是对于ts的支持度肯定好于现在任何编辑器对js的支持度),最低的配置当然是windows记事本+编译器,编译器是js写的,跨平台。可以直接从官网下载msi安装包,或者直接用npm命令安装。(安装vs2012+ts扩展最好了,vs2012从微软官网下载安装,貌似也不会提示你需要注册什么的,直接能用,不然用免费版的简装vs也支持ts)
    
  Typescript的学习门槛
   学习js的前提是,建议是你至少有一年以上js的开发经验,然后:
   如果你学过actionscript3,那么你大概半天就可以学会基本的ts开发,因为ts的语法和as非常接近;
   如果你学过java,C#,PHP(同时有js基础),那么大概一天可以掌握基本的ts开发;
   如果你没有as和java,c#的开发经验,那么其实说明你专注于js开发,你可以一边写ts一边查看编译后的js代码,更能很快了解整个ts的工作原理。
    Javascript代码就是Typescript代码
   js和as的语法都源自ECMAScript标准,所以二者高度兼容,ts同样符合ECMAScript的标准,ts是js的超集,甚至你把xxx.js文件名改成xxx.ts,那么它就是ts代码文件了。

    不用记API了——强类型的DOM API,jQuery,Backbone,NodeJs
   资深js开发都了解,js语言层面上的知识量很少,然后就是记海量的API,做web开发记浏览器API,HTML5 API以及API支持程度,浏览器差异性等;做游戏开发要记住游戏引擎的API;做nodejs开发要记住node的api;因为编辑器的支持力弱,所以一个JS开发人员体现效率的一方面,就是看他记住了多少常用的API:包括浏览器内置的API、第三方的(比如google map),jquery再易用你也得记住一些API(常备一个api文档),而我用了jquery五六年能记住的API肯定没有50%。另一方面一门追求效率,代码要精简(带宽需要)的弱类型脚本,各种非OO式的api设计以及文档的可读性肯定会非常差劲,这也是众多吐槽点之一(这里在强烈鄙视nodejs的官方文档)。
   那么做ts开发,我是否需要准备一个强类型的Typescript代码写的jQuery类库?但是像jQuery这种大众化类库,追求代码精简程度是必要的,不可能用ts重写一遍(ts编译后的js虽然不臃肿,但也不是超级精简)。Typescript团队提供了一套 虚构声明语法,可以把现有的代码API用头文件的形式描述出来,xxx.d.ts(d.ts命名提醒vs这种文件不需要编译)这套虚构定义语法,让你不需要去实现函数体里的代码,类似定义interface和抽象类。
    

    

   按照这种方式,可以把你目前的js项目里的api全部定义出来(不改动原来的代码),然后项目里新增加的代码就可以用ts来开发了(我现在也是这样干)。
   这个地址有常用js类库的ts接口定义头文件,阅读这些头文件甚至比直接读这些类库官方提供的文档更有效率。

   更有价值的是ts内置了DOM和BOM API的接口定义文件(默认引用):lib.d.ts,你再也不用记住海量的DomAPI和其它HTML5 API了  
   

   

   

  高级特性之函数重载(常量参数重载)—— 事件驱动强类型化
  Javascript在各种环境都是被设计成事件驱动的开发方式,但是不同于c#,js里面没有强类型的事件,大部分都是通过函数加特定的事件名一起工作的,比如window.addEventListener("事件名",func),jQuery.bind("事件名",func),Backbone.View.on("事件名",func),但是作为一个类库提供者,你怎么让别人知道你的对象支持多少种事件呢?每个事件回调函数的参数列表又是怎样? 上面两个截图就很清晰的告诉你,addEventListener这个函数是重载的,有62种参数方式,很直接地告诉你window对象支持绑定多少种事件,且回调函数也强类型化了,这样,甚至是初学者也不需要去查阅w3c的dom api文档也能开发了。我们的团队使用Backbone开发,大量地使用了backbone的事件驱动,所以这个特性真是令人鸡冻不宜。


   强类型JSON, 可视化WebAPI
  ts实际上也鼓励你把JSON强类型化,那么你在做web开发的时候再也不用记忆一些数据实体的属性拼写,vs内置支持把一段JSON自动转化为声明好的interface(复制一段json->在编辑器里右键->选择性粘贴->把JSON粘贴为类,这里不确定是不是Web Essentials这个vs插件给你添加的功能),我用nodejs写了一个代理脚本,自动抓取接口数据,然后自动生成所有json的interface声明,这些json声明真正是一次编写到处引用,因为interface只是作为你开发和编译时候的类型检查依据,生成js以后毫无痕迹,所以不管前端js(pc或手机)还是后台nodejs都能使用。
 
    

   编译成js后

    

 如何将目前的js项目代码迁移到ts上?
  1、先用伪声明(xxx.d.ts)把项目的公共类库定义好;(可以进行微重构,屏蔽私有属性和方法,屏蔽不建议使用的方法)
  2、新模块的代码全用ts来写;(新代码与老的js隔离,不产生相互依赖,拥有很大的重构性)
  3、慢慢把老的模块重写成ts,然后替换xxx.d.ts;
  4、全新的项目完全可以直接用ts开发。
   自动化构建你ts项目里的脚本,以至在打包的时候能全局性的再次编译(单个编译的方式容易在依赖代码更新后产生编译错误)
   可以借鉴以下文章:百度《我用TypeScript 语言的七个月》

   最终之言:可以重构的代码胜于一切
   以上我略过了很多ts的基础知识,你可以从官网中学习如何开始ts的体验:安装vs2012 -> 安装Typescript for vs2012的插件 -> 创建一个Typescript HTML App工程,然后开始你的ts体验之旅,也可以直接用在线版的ts编辑器进行ts编码体验: http://www.typescriptlang.org/Playground/
   vs对于ts的支持非常强大,不过最方便的还是转到定义(F12)和查找所有引用的功能以及全局自动重命名对象,这个是弱类型语言无法具备的功能,是重构代码的重要依靠。
   用ts写代码,你可以尽快把功能完成,然后不断地迭代重构代码,这种开发模式可以响应快速的需求,又能保证程序后续的生命力。

    再安装一个vs插件,2.9版本,就可以左右分栏,左边是ts,右边是js,保存自动编译(必须是2.9版本,3.0版本作者已经移除了ts的支持,由于ms的要求详见 http://vswebessentials.com/changelog
    http://vswebessentials.com/nightly/webessentials2012-2.9.vsix
    如果不安装插件,也可以让ts在保存的时候自动编译,需要对vs进行一下配置。

   
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值