2015 前端[JS]工程师必知必会

4 年前

上次我写《前端工程师必知必会》已经是三年前了,那是我写过的最火的文章。三年了,我仍然会在Twitter上收到关于这篇文章的消息。

从某些方面来说,从2012年到现在一篇文章都没发过让我觉得有点羞羞哒。三年是一个很长的时间,很多东西都发生了改变。2012年,我鼓励同学们去学习浏览器开发者工具, 学习模块化;CSS预编译,客户端模板引擎还很值得一提,并且也有很多同学会觉得这些玩意儿并不靠谱。还有JSHint,虽然有#getoffmylawn(滚出我的地盘)的忠告,但依然无法阻止JSHint变得越来越受欢迎,准确的说,JSLint真的(只是)存在过。

今年,我觉得这些内容(前端必须掌握的知识)得更新一下了。在开始之前,有两件事我需要先提一下。第一,把这写东西称为“必须掌握的知识”可能是不公平的,如果你还记得我那篇2012年的文章,那么你会发现这篇文章更是如此[check]。也许有同学会说,我们应该把 “能找到一份好工作” 作为 “前端必须掌握的知识”。但是也有各种各样的前端工作可供选择,这样的话也只能得到一个并不适合所有人的 “前端基础知识”。而对于我来说,我需要的不是工作,我想要的是被邀请去做一份牛逼的工作。我想要的不只是去干活而已,而是想和一群牛逼的人一起做牛逼的工作。我不想仅仅满足于用已有的知识来完成现在的工作,而是去掌握更多的知识来解决未来将会面对的问题。

第二,我现在已经完全把Javascript作为我的核心了:CSS知识只有在必须关注性能问题时才会用到,其他场景已经用的越来越少。我知道有很多牛逼的前端同学并不是这样的,但我也意识到,关注JS的同学和关注CSS的同学之间的距离也越来越远。这可能需要在另一篇博客中讨论,不过我想说的是,我不会在这篇文章中介绍CSS的技能标准,因为我还远远没有达到可以这么做的水平。

总之,就算这个技能列表并不适合你的前端工作,没关系,不要有压力,地球也不会爆炸。

JavaScript

回想2009年,那时候当你知道HTML5在2014年才能用的时候,你是不是觉得这辈子基本上都不会用到了?如果是,那么你需要准备好接受进展缓慢但是已经趋于稳定的ES6了,它也是下一代的Javascript(现在叫ES2015了,嗯,这名字至少表示今年就能用了)。根据我现在的情况,ES6,额,ES2015无疑是我现在最关注的Javascript内容。在ES6中将会出现一些比较大的变化:类,真正的私有,经过改进更易用的函数和参数设定,可导入的模块,等等等等。那些掌握和理解新的语法的同学以后将会在JS社区牛逼闪闪。相关阅读:

  • Understanding ES6,Nicholas Zakas 正在写的书。
  • BabelJS,一个可以把你写的ES6的代码编译成ES5并在现代浏览器中运行的工具。他们也有一个不错的介绍ES6的文档
  • ES6 Rocks,里面有大量的文章探索ES6的特性,语义和缺陷。[check]

你也许会问:那我需要成为一个ES6专家么?也许现在不需要,但至少你得和你的同事懂的一样多吧?或者比他们稍微多一点?当然,如果能在你的下一个新项目中作为一个娱乐性的技术尝试也是不错的,做好准备肯定没错的,因为我们永远不知道下一刻会发生什么。

先不说新的语言特性,使用回调和promises管理异步Javascript至少得背的滚瓜烂熟吧。浏览器端应用加载,以及应用间通信策略得形成一套自己的观点吧。而且你应该知道哪种框架最适合你,而不是现在还把时间花在理解各种框架的实现原理和该选择哪种框架上。

模块化和构建工具

毫无疑问,模块化是构建Web客户端应用的基石。回到2012年,关于使用哪种模块化(ADM/CommonJS)方案构建浏览器端应用还存在很多争论。而最近慢慢火起来的UMD则在保证代码可复用的前提下尝试避免这样的问题。 其实也没什么好争得,毕竟这俩玩意儿之间也就差几个字符吧?

我觉得类似这样的争论其实并不都需要有一个答案,这也是我觉得从2012年到现在我们发生的最大的转变,当然,也许只是我自己这么认为。因为我觉得与其说“我再也不用AMD了”之类的话,倒不如多去讨论 “在开发和打包过程中使用CommonJS和npm遇到的各种难题” 来的更有价值。

虽然很感激RequireJS曾经对模块化做出的贡献,不过现在我开始有点迷恋webpack了。webpack的构建配置比RequireJS更加易于理解,也更具访问性[check]。通过它的热插拔特性和内置的本地静态服务器可以让发布更加便捷。它并不强制要求使用AMD或者CommonJS,因为两个它都支持。它还实现了一大堆的加载器用来完成常见的繁琐工作。Browserify也值得去了解一下,不过我个人认为它比Webpack落后很多。一些靠谱的朋友告诉我说systemjs也是这个领域的竞争者,不过我还没有用过,而且它的文档烂的我连看都不想看。不过我觉得它的好基友jspm(包管理器)比较有趣,jspm可以让你从各种包管理服务器加载你需要的各种组件,(组件必须是符合ES6, AMD, CommonJS and globals规范的),包括npm, github等,但是我对于这两个玩意的合体还是有点不太理解。啊,还有,虽然我说了这么多关于模块化之外的内容,但我从来没想过放弃AMD,我们边走边看吧。

我觉得如果要停止对模块化和构建工具的争论,形成统一的模块化系统,并且在这个系统里面,任何项目的代码都可以共享,而且还不需要UMD这样额外的补丁工具,我们还有很长的路要走。理想状况下,ES6 modules的到来会解决这些问题,不过在这一天到来之前,类似UMD之类的转换器会填补这些空缺,不过貌似这样做我们又把事情变得复杂了,好像我们也总喜欢把事情弄得复杂。

与此同时,前端开发人员也需要对构建工具,各种模块化系统有自己的见解和知识储备。不管是好是坏,根据Javascript现在的进度,你的模块化策略对你的项目有比较大的影响的。[check]

测试

客户端的代码测试变得越来越普遍,最近也诞生了一些新的测试框架:KarmaIntern。我发现基于promise的Intern的异步测试方法相当优雅。可能是因为习惯,我大多数情况下还是用Mocha写测试用例。

测试的主要障碍其实是前端开发者的代码编写方式。我在2012年发表过一个关于《编写可测试的Javascript》下载地址的演讲,紧接着几个月后又发表了一篇相关的文章

测试的第二大障碍是工具。Webdriver是一个艰难而巨大的工作。目前在各个浏览器端做持续集成的UI自动化测试基本上是不可能的,更不用说移动端了[check]。我们仍然停留在局限于某一小部分浏览器和设备上做轻量级的自动化功能测试,尽我们所能去研究怎样快速,低成本的进行这种测试的阶段[check]。

如果你对如何改进代码的可测试性感兴趣的话,那么唯一一本最值得看的书是Working Effectively with Legacy Code中译版:《修改代码的艺术》。作者Michael Feathers定义了“遗留代码”的概念:任何未经测试的代码都是遗留代码。在测试领域,最基本的要素就是上面这句话,尽管你可能不这么认为。

流程自动化

你首先会想到Grunt,这也是理所当然的。而GulpBroccoli的自动化构建方式也别具匠心。我没用过Broccoli,只玩过Gulp,我也开始意识到Grunt对于依赖其他服务的复杂任务的自动化工作存在局限性,尤其是当这种任务每天需要运行上千次的时候。

Yeoman是在我写完2012年的那篇文章之后就发布的[check],我承认当时我并没有及时去尝试一下。不过最近我开始启动一些新项目,这些新项目有两个特点 a) 这些项目都是从零开始 b) 尝试用一些不同的技术方案,试图通过这种方式找到Bazaarvoice(提供第三方点评服务)上第三方JS应用的规范化的开发方式[check]。 Yeoman在这两方面做的都很好。一个简单的 yo react-webpack 命令就可以为你初始化好你的项目,然后各种你想要的玩具也都应有尽有:生成测试用例,本地静态服务器,hello world入门程序,等等等等。如果React和Webpack不是你想要的,也许你会在Yeoman的generators(项目生成器)里面找到一个你想要的,当然,自己自定义一个这样的构建包也是比较容易的。

鉴于Yeoman只是一个在项目开始时才会用到的构建工具,并且鉴于我们并不是总是做新项目,所以大多情况下了解一下就够了。除非,你也想去规范整个项目开发过程,那么它可能会更有价值一点。

Broccoli已经得到了ember-cli的采纳,我觉得他们的配对可能会有一个新名字,这样在未来才比较方便和Grunt/Yeoman对抗。而Grunt和Yeoman的开发进度也放缓了,所以未来会发生什么,我们还是静观其变吧。

###代码质量

如果你像我一样,一看见违反代码规范的代码时就开始抓狂,那么JSCSESLint就是老天赐给你的礼物,而2012压根就没这些玩意。他们都提供了自定义代码规范的方式,并且可以在代码提交前对你的代码做自动化校验。这让我想起了...

Git

从2012年到现在,github的使用流程并没有发生很大的变化,比如在pull request页面连个分支名都没有(只是恶搞一下)[check]。

你应该非常清楚和流畅的使用功能分支(feature branches), 使用rebase合并别人的代码干活,使用交互式rebase命令和squash合并提交记录,或者尽可能细颗粒度的划分项目内容,避免引起代码冲突。另一个可用的Git工具是钩子,具体而言,就是你可以在push前,commit前,执行你的各种测试用例,检查代码质量。你可以自己写钩子,也可以使用ghooks,由于ghooks使钩子工作变得非常简单,所以你简直没有理由不用它。

客户端模板

这可能是我在2012年的那篇文章中写的最烂的内容了,某种意义上的“烂”[check]。客户端模板还是很有价值的,而且它已经被内置到ES2015里面了,这不仅仅只是一件好事而已。这些年也有一些惨重的教训,不少团队把所有的渲染工作全部丢到浏览器端去做,结果产生了严重的性能问题,所以 “在浏览器端渲染生成所有HTML” 的做法理所当然的被摒弃了[check]。 而更为聪明的做法则是,把HTML生成放在服务器端,或者通过预编译的方式,先将模板做为静态资源储存起来,在需要时快速的编译成HTML,需要更新时也可以直接在客户端更新模板。

这里会有一些新的展望,不仅是对我自己,也是对所有人,当你在考虑性能问题时,也许没必要把自己完全限定在浏览器范围内。所以,这又让我想起了...

Node

听说你懂Javascript,那么我觉得你也应该懂Node,至少在遇到Node问题是能帮上忙,如果连忙都帮不上,那也至少深入研究一下吧:Node的文件系统,流,服务器,完全不同于前端的一些开发模式等等。对后端敬而远之只会限制我们前端的发展潜力。

即使你的真实生产环境中后端不用Node,当你的工作被后端限制或阻碍的时候,Node也是一个非常有用的工具。最起码,你也应该熟悉怎么去初始化一个Node项目,怎么用Express搭建服务器设置路由,怎么使用请求模块代理请求。

最后

感谢Paul, Alex, Adam, Ralph对本文的Review,感谢他们毫不吝啬的指出我的不足之处,并给我提了很好的意见。

就这样,祝你好运。也许,三年之后我们会再见。

Rebecca Murphey 发表于2015年3月23日

0
推荐阅读