跳转到主要内容
Chinese, Simplified

原帖可以在Github上找到。未来的学习指南将在那里更新。如果你喜欢你正在阅读的东西,给它打一颗星吧!?

公司是东南亚(SEA)领先的运输平台,我们的使命是利用公司最新的技术和人才,推动SEA前进。截至2017年5月,我们每天处理230万次乘车,我们正在快速增长和招聘。

为了跟上Grab惊人的增长,我们的网络团队和网络平台也必须增长。幸运的是,或者不幸的是,在Grab上,web团队已经跟上了最新的最佳实践,并在我们的web应用程序中集成了现代JavaScript生态系统。

的结果是,我们的新员工或后端工程师,他们并不一定了解现代JavaScript的生态系统,可能会感到被接二连三的新事物,他们必须学习只是为了完成他们的特性或web应用程序的bug修复。前端开发从未像今天如此复杂和令人兴奋的。每隔一天就会出现新的工具、库、框架和插件,还有很多东西需要学习。必须引导web团队的新成员接受前端的这种演化,学会轻松地在生态系统中导航,并尽可能快地向用户交付代码。我们提出了一个学习指南,介绍我们为什么要做我们所做的,以及我们如何处理前端的规模。

本学习指南的灵感来自于“治愈JavaScript疲劳的学习计划”,在某种意义上,我们建议针对前端开发的每个方面学习特定的库/框架,这些库/框架基于当前认为最适合于Grab的内容。我们解释了为什么选择某个库/框架/工具,并提供了学习资源的链接,让读者能够自己学习。对于其他用例可能更好的备选方案也提供了参考和进一步的自我探索。

如果您的公司也在探索现代的JavaScript堆栈,那么您可能会发现本学习指南对您的公司也很有用!您可以根据自己的需要随意调整它。我们将根据最新的工作和选择,定期更新本学习指南。

-抓取Web团队

必备条件

  • 理解核心编程概念。
  • 熟悉基本的命令行操作,熟悉源代码版本控制系统,如Git。
  • 有网络开发经验。使用Ruby on Rails、Django、Express等框架构建了服务器端呈现的web应用程序。
  • 了解网络是如何工作的。熟悉web协议和约定,如HTTP和RESTful api。

表的内容

  • 单页面应用程序(温泉)
  • 新时代的JavaScript
  • 用户界面
  • 状态管理
  • 编码与风格
  • 可维护性
  • 构建系统
  • 包管理

某些主题可以跳过,如果你有之前的经验。

单页面应用程序(SPA)

如今,Web开发人员将他们开发的产品称为Web应用程序,而不是网站。虽然这两个术语之间没有严格的区别,但web应用程序往往是高度交互和动态的,允许用户执行操作并接收其操作的响应。传统上,浏览器从服务器接收HTML并呈现它。当用户导航到另一个URL时,需要刷新整个页面,服务器为新页面发送新的HTML。这称为服务器端呈现。

但是在现代的SPAs中,使用的是客户端呈现。浏览器从服务器加载初始页面,以及整个应用程序所需的脚本(框架、库、应用程序代码)和样式表。当用户导航到其他页面时,不会触发页面刷新。页面的URL通过HTML5 History API更新。新页面所需的新数据(通常为JSON格式)由浏览器通过对服务器的AJAX请求检索。然后,SPA通过JavaScript动态地更新页面,它在初始页面加载时已经下载了这些数据。这种模式与本地移动应用程序的工作方式类似。

好处:

  1. 这款应用的响应速度更快,而且由于页面刷新,用户在页面导航之间看不到flash。
  2. 服务器需要的HTTP请求更少,因为对于每个页面加载,不必再次下载相同的资产。
  3. 清晰地分离客户端和服务器之间的关注点;您可以轻松地为不同的平台(如移动平台、聊天机器人、智能手表)构建新客户端,而无需修改服务器代码。您还可以独立地修改客户端和服务器上的技术堆栈,只要API契约没有被破坏。

缺点:

  1. 由于加载多个页面所需的框架、应用程序代码和资产,初始页面加载较重。
  2. 在您的服务器上还需要完成另一个步骤,即将其配置为将所有请求路由到单个入口点,并允许客户端路由从那里接管。
  3. SPAs依赖于JavaScript来呈现内容,但并不是所有搜索引擎都在爬行期间执行JavaScript,它们可能会在您的页面上看到空的内容。这无意中损害了你的应用程序2的SEO。

虽然传统的服务器端呈现应用程序仍然是一个可行的选择,但清晰的客户机-服务器分离更适合大型工程团队,因为客户机和服务器代码可以独立开发和发布。当我们有多个客户端应用程序访问同一个API服务器时,这一点在Grab上尤其明显。

随着web开发人员现在构建的是应用程序而不是页面,组织客户端JavaScript变得越来越重要。在服务器端呈现的页面中,通常使用jQuery片段向每个页面添加用户交互性。然而,在构建大型应用程序时,jQuery是不够的。毕竟,jQuery主要是一个用于DOM操作的库,它不是一个框架,它没有为你的应用定义一个清晰的结构和组织。

JavaScript框架的创建是为了在DOM上提供更高层次的抽象,允许您将状态保存在内存中,而不是DOM中。使用框架还可以重用推荐的概念和构建应用程序的最佳实践。团队中有框架经验但没有应用程序经验的新工程师会发现更容易理解代码,因为代码是按照他熟悉的结构组织的。流行的框架有很多教程和指南,利用来自同事和社区的知识和经验可以帮助新工程师快速上手。

研究的链接

新时代的JavaScript

在深入了解构建JavaScript web应用程序的各个方面之前,熟悉web语言—JavaScript或ECMAScript非常重要。JavaScript是一种非常通用的语言,您还可以使用它来构建web服务器、本地移动应用程序和桌面应用程序。

在2015年之前,最后一次主要更新是2011年的ECMAScript 5.1。然而,近年来,JavaScript在短时间内突然出现了巨大的改进。2015年,ECMAScript 2015(以前称为ECMAScript 6)发布了,并引入了大量的语法结构,以减少编写代码时的笨拙。Auth0编写了很好的JavaScript历史。到目前为止,并不是所有的浏览器都完全实现了ES2015规范。Babel等工具使开发人员能够在他们的应用程序中编写ES2015,而Babel将这些工具转换为ES5,以便与浏览器兼容。

熟悉ES5和ES2015是至关重要的。ES2015仍然相对较新,很多开源代码和Node.js应用程序仍然是用ES5编写的。如果在浏览器控制台中进行调试,则可能无法使用ES2015语法。另一方面,我们将在下面介绍的许多现代库的文档和示例代码都是用ES2015编写的。在Grab,我们使用ES2015(与Babel Stage-0预置一起)来支持JavaScript未来提供的语法改进,到目前为止我们一直很喜欢它。

花一两天时间复习ES5和探索ES2015。ES2015中使用较多的特性包括“箭头和词法This”、“类”、“模板字符串”、“析构”、“缺省/Rest/Spread操作符”和“导入和导出模块”。

预计持续时间:3-4天。您可以像学习其他库并尝试构建自己的应用程序一样学习/查找语法。

研究的链接

 

用户界面-React

React Logo

如果最近几年有任何JavaScript项目在前端生态系统中掀起了一场风暴,那就是React。React是一个由Facebook的聪明人创建的开源库。在React中,开发人员为他们的web界面编写组件并将它们组合在一起。

React带来了许多激进的想法,并鼓励开发人员重新思考最佳实践。多年来,web开发人员一直被教导要分别编写HTML、JavaScript和CSS。React的做法正好相反,建议您用JavaScript编写HTML和CSS。这听起来像一个疯狂的想法,但经过尝试后,它实际上并不像听起来那么奇怪。作为前端开发场景的原因正在向基于组件的开发范式转变。React的特点:

  • 说明性的——你描述你想在视图中看到什么,而不是如何实现它。在jQuery时代,开发人员必须想出一系列操作DOM的步骤,才能从一个应用程序状态切换到下一个应用程序状态。在React中,只需更改组件中的状态,视图就会根据状态更新自身。通过查看render()方法中的标记也很容易确定组件的外观。
  • 功能-视图是一个纯粹的道具和状态的功能。在大多数情况下,React组件由支柱(外部参数)和状态(内部数据)定义。对于相同的道具和状态,会产生相同的视图。纯函数易于测试,功能组件也是如此。在React中进行测试很容易,因为组件的接口定义良好,可以通过向组件提供不同的道具和状态并比较呈现的输出来测试组件。
  • 可维护性——以基于组件的方式编写视图可以促进可重用性。我们发现定义组件的proptype可以使React代码自文档化,因为读者可以清楚地知道使用组件需要什么。最后,您的视图和逻辑在组件中是自包含的,不应该受到影响,也不应该影响其他组件。这使得在大规模重构过程中很容易对组件进行移位,只要向组件提供相同的支持即可。
  • 高性能——您可能听说过React使用虚拟DOM(不要与影子DOM混淆),当状态发生变化时,它会重新呈现所有内容。为什么需要虚拟DOM?虽然现代JavaScript引擎速度很快,但从DOM读写却很慢。React在内存中保持DOM的轻量级虚拟表示。重新呈现一切是一个误导的术语。在React中,它实际上是指重新呈现DOM在内存中的表示,而不是实际的DOM本身。当组件的底层数据发生更改时,将创建一个新的虚拟表示,并与以前的表示进行比较。然后将差异(所需的最小更改集)打补丁到实际的浏览器DOM。
  • 易学-学习反应很简单。与此相比,React API表面相对较小;只有几个api需要学习,而且它们不经常更改。React社区是最大的社区之一,随之而来的是充满活力的工具生态系统、开源的UI组件以及大量的在线资源,可以帮助你开始学习React。
  • 开发人员经验—有许多工具可以改进React的开发经验。React Devtools是一个浏览器扩展,允许您检查组件、查看和操作其道具和状态。使用webpack热重载允许您在浏览器中查看代码更改,而不必刷新浏览器。前端开发包括大量的代码调整、保存和刷新浏览器。热重新加载帮助您消除最后一步。当有库更新时,Facebook提供codemod脚本来帮助您将代码迁移到新的api。这使得升级过程相对轻松。向Facebook团队致敬,感谢他们的奉献精神,使React的开发体验变得非常棒。

多年来,出现了比React性能更好的新视图库。React可能不是最快的库,但就生态系统、整体使用体验和好处而言,它仍然是最好的库之一。Facebook也在努力加快反应速度,重写了底层的和解算法。React引入的概念教会了我们如何编写更好的代码、更易于维护的web应用程序,并使我们成为更好的工程师。我们像这样。

我们建议在React主页上阅读关于构建井字游戏的教程,以了解React是什么以及它的功能。更多深入学习,请查看评价较高的免费课程,React Router的创建者提供的React基础知识,他们是React社区的专家。它还涵盖了React文档中没有涵盖的更高级的概念。Facebook的Create React应用程序是一个工具,可以用最少的配置搭建一个React项目,强烈推荐用于启动新的React项目。

React是一个库,而不是框架,它不处理视图下面的层——应用程序状态。稍后再详细介绍。

预计持续时间:3-4天。尝试建立简单的项目,如待办事项列表,黑客新闻克隆与纯反应。你会慢慢地对它产生好感,并可能在这个过程中遇到一些问题,而这些问题不是React能够解决的,这就引出了我们的下一个话题……

研究的链接

选择

状态管理-Flux/Redux

Redux Logo

随着应用程序越来越大,您可能会发现应用程序结构变得有点混乱。整个应用程序的组件可能不得不共享和显示公共数据,但没有优雅的方式来处理React。毕竟,React只是一个视图层,它并没有规定如何在传统MVC模式中构建应用程序的其他层,比如模型和控制器。为了解决这个问题,Facebook发明了Flux,这是一个应用架构,通过利用单向数据流来补充React的可组合视图组件。在这里阅读更多关于Flux的工作原理。综上所述,流量分布具有以下特点:

单向数据流-使应用程序更可预测的更新可以很容易地跟踪。

关注的分离——通量体系结构中的每个部分都有明确的职责,并且是高度解耦的。

在声明式编程中工作得很好——存储可以向视图发送更新,而不需要指定如何在状态之间转换视图。

由于Flux本身不是一个框架,开发人员已经尝试了很多Flux模式的实现。最终,一个明显的赢家出现了,那就是Redux。Redux结合了Flux、Command pattern和Elm体系结构的思想,是目前开发人员与React一起使用的事实上的状态管理库。其核心概念是:

应用程序状态由一个简单的旧JavaScript对象(POJO)描述。

发送一个操作(也是一个POJO)来修改状态。

减速器是一个纯函数,它采用当前状态和动作来产生一个新的状态。

这些概念听起来很简单,但是它们非常强大,因为它们使应用程序能够:

在服务器上呈现它们的状态,在客户端启动它们。

跟踪、记录和回溯整个应用程序中的更改。

轻松实现撤销/重做功能。

Redux的创建者Dan Abramov非常仔细地为Redux编写了详细的文档,并为学习基本和高级Redux创建了全面的视频教程。它们是非常有用的学习资源。

视图和状态的结合

虽然Redux不一定要与React一起使用,但强烈推荐使用Redux,因为它们彼此配合得很好。React和Redux有很多共同的想法和特点:

功能组合范式- React组合视图(纯函数),而Redux组合纯还原剂(纯函数)。给定相同的输入集,输出是可预测的。

很容易推理——你可能听过这个词很多次,但它到底是什么意思呢?根据我们的经验,React和Redux简化了调试。由于数据流是单向的,因此更容易跟踪数据流(服务器响应、用户输入事件),并且很容易确定问题发生在哪个层。

分层结构——app / Flux架构中的每一层都是纯功能,职责明确。为它们编写测试非常容易。

开发经验——在开发过程中,我们花了很多精力来创建工具来帮助调试和检查应用程序,比如Redux DevTools。

您的应用程序可能必须处理异步调用,如发出远程API请求。redx -thunk和redx -saga就是为了解决这些问题而创建的。它们可能需要一些时间来理解,因为它们需要理解函数式编程和生成器。我们的建议是,只有在你需要的时候才去处理它。

React - Redux是Redux的官方React绑定,非常简单易学。

预计时间:4天。egghead课程可能有点耗时,但值得花时间。在学习了Redux之后,您可以尝试将其合并到您已经构建的React项目中。Redux是否解决了您在pure React中遇到的一些状态管理问题?

Alternatives

用样式- CSS模块编码

CSS Modules Logo

编写好的CSS是困难的。在能够编写可维护和可伸缩的CSS之前,需要多年的经验和挫败感来解决问题。具有全局名称空间的CSS基本上是为web文档设计的,而不是真正为偏爱组件体系结构的web应用程序设计的。因此,有经验的前端开发人员设计了一些方法来指导人们如何为复杂的项目编写有组织的CSS,比如使用SMACSS、BEM、SUIT CSS等。然而,这些方法所带来的样式的封装是由约定和指导方针强制执行的。一旦开发人员不遵循它们,它们就会中断。

幸运的是,前端的生态系统中充斥着各种工具,而不出意料的是,人们发明了一些工具来部分解决大规模编写CSS的一些问题。“大规模”意味着许多开发人员都在同一个项目中工作,并且使用相同的样式表。目前还没有社区同意用JS编写CSS的方法,我们希望有一天能像Redux一样在Flux实现中脱颖而出。现在,我们指望CSS模块。CSS模块是对现有CSS的改进,旨在解决CSS中全局命名空间的问题;它使您能够编写默认情况下是本地的并封装到组件中的样式。此功能通过工具实现。用CSS模块,可以编写大型团队的模块化和可重用的CSS,而不必担心冲突或覆盖应用程序的其他部分。然而,在一天结束的时候,仍在CSS模块编译成正常globally-namespaced CSS的浏览器识别,它仍然是重要的学习生的CSS。

如果你是一个完全的CSS初学者,Codecademy的HTML和CSS课程将是一个很好的介绍你。接下来,阅读Sass预处理器,这是CSS语言的扩展,增加了语法改进,并鼓励了样式的可重用性。学习上面提到的CSS方法,最后学习CSS模块。

预计持续时间:3-4天。尝试使用SMACSS/BEM方法和/或CSS模块设计应用程序的样式。

Alternatives

可维护性

读代码比写代码更频繁。在Grab尤其如此,在那里团队规模很大,我们有多个工程师在多个项目中工作。我们高度重视代码的可读性、可维护性和稳定性,有几种方法可以实现这一点:“广泛的测试”、“一致的编码风格”和“类型划分”。

测试- - Jest + Enzyme

Jest是Facebook的一个测试库,旨在让测试过程无痛苦。与Facebook项目一样,它提供了一种开箱即用的良好开发体验。测试可以并行运行以获得更快的速度,并且在监视模式下,只运行更改文件的测试。我们喜欢的一个特性是“快照测试”。Jest可以保存React组件和Redux状态生成的输出,并将其保存为序列化文件,这样您就不必自己手动生成预期的输出。Jest还具有内置的模拟、断言和测试覆盖率。一个图书馆来统治他们所有人!

React附带了一些测试工具,但是通过类似于jquery的API,通过Airbnb提供的酶可以更容易地生成、断言、操作和遍历React组件的输出。建议用酶测定反应组分。

Jest和酶使编写前端测试变得有趣和容易。因为定义了明确的职责和接口,所以React组件和Redux操作/缩减器相对容易测试也很有帮助。对于React组件,我们可以测试给定一些道具,呈现所需的DOM,并在某些模拟用户交互时触发回调。对于Redux还原器,我们可以测试给定的一个先验状态和一个动作,会产生一个结果状态。

Jest和ase的文档非常简洁,通过阅读它们应该就足够了。

预计持续时间:2-3天。尝试为你的React + Redux应用程序编写Jest +Enzyme!

Alternatives

Linting JavaScript - ESLint

ESLint Logo

linter是一个静态分析代码并发现代码问题的工具,它可以潜在地防止bug /运行时错误,同时强制执行一种编码风格。在拉请求审查期间,当审查人员不必对编码风格留下挑剔的评论时,可以节省时间。ESLint是一个用于linting JavaScript代码的工具,具有高度可扩展性和可定制性。团队可以编写自己的lint规则来执行自定义样式。在Grab中,我们使用Airbnb的eslin -config- Airbnb预置,它已经在Airbnb的JavaScript风格指南中配置了通用的良好编码风格。

在大多数情况下,使用ESLint就像调整项目文件夹中的配置文件一样简单。如果您不为ESLint编写新的规则,那么就没有什么可学习的。当错误出现时,请注意它们,并将其谷歌,以找到推荐的样式。

预计持续时间:1/2天。没什么可学的。添加ESLint到您的项目,并修复linting错误!

Alternatives

Linting CSS - stylelint

stylelint Logo

正如前面提到的,好的CSS是出了名的难写。在CSS上使用静态分析工具有助于保持我们的CSS代码质量和编码风格。对于linting CSS,我们使用stylelint。与ESLint一样,stylelint以一种非常模块化的方式设计,允许开发人员打开/关闭规则并为其编写自定义插件。除了CSS之外,stylelint还能够解析SCSS,并且对Less提供了实验支持,这降低了大多数现有代码库采用它的障碍。

stylelint Demo

一旦你学会了ESLint,考虑到他们的相似之处,学习stylelint将是毫不费力的。手写笔目前被Facebook、GitHub和Wordpress等大公司使用。

手写笔的一个缺点是,自动修复功能还没有完全成熟,只能修复有限数量的规则。然而,这个问题应该随着时间的推移而改善。

预计持续时间:1/2天。没什么可学的。将stylelint添加到项目中并修复linting错误!

Alternatives

Types - Flow

Flow Logo

静态类型在编写应用程序时带来了许多好处。它们可以在早期捕获代码中的常见bug和错误。类型还可以作为代码文档的一种形式,提高代码的可读性。随着代码库的增长,我们看到了类型的重要性,因为它们在我们进行重构时给了我们更大的信心。当清楚每个对象持有什么类型的值和每个函数期望什么时,将团队的新成员加入到项目中也更容易。

向代码中添加类型需要在增加冗长性和语法学习曲线之间进行权衡。但这种学习成本是预先支付的,并随着时间的推移摊销。在复杂的项目中,代码的可维护性很重要,并且处理代码的人员会随着时间的推移而变化,向代码中添加类型带来的好处要多于坏处。

向JavaScript添加静态类型的两大竞争者是Flow (Facebook)和TypeScript(微软)。到目前为止,还没有明确的赢家。现在,我们已经做出了使用流的选择。我们发现与TypeScript相比,Flow的学习曲线更低,并且将现有的代码库迁移到Flow所需的工作相对较少。Flow由Facebook打造,与React生态系统的整合性更好。无论如何,从Flow转移到TypeScript并不十分困难,因为语法和语义非常相似,我们将在以后重新评估这种情况。毕竟,使用一个总比不使用强。

Flow最近更新了他们的文档站点,现在已经很整洁了!

预计持续时间:1天。流非常容易学习,因为类型注释感觉像是JavaScript语言的自然扩展。向您的项目中添加流注释,并利用类型系统的强大功能。

Alternatives

Build System - webpack

webpack Logo

这一部分将会很简短,因为设置webpack可能是一个冗长乏味的过程,而且可能会让那些已经被前端开发中需要学习的大量新内容压得喘不过气来的开发人员感到厌烦。简单地说,webpack是一个模块绑定器,它将前端项目及其依赖项编译成一个最终的包,然后提供给用户。通常,项目已经设置了webpack配置,开发人员很少需要更改它。从长远来看,理解webpack仍然是一件好事。这是由于webpack的功能,如热重载和CSS模块是可能的。

我们发现由生存js的webpack演练是学习webpack的最佳资源。这是对官方文档的一个很好的补充,我们建议先进行演练,然后在需要进一步定制时参考文档。

预计持续时间:2天(可选)。

Alternatives

Package Management - Yarn

 

Yarn Logo

如果您查看一下node_modules目录,您会对其中包含的目录数量感到震惊。每个babel插件lodash函数都是一个独立的包。当您有多个项目时,这些包在每个项目中都是重复的,它们在很大程度上是相似的。每次在新项目中运行npm安装时,这些包都会被一次又一次地下载,即使它们已经存在于计算机中的其他项目中。

在通过npm安装安装的包中也存在不确定性的问题。我们的一些CI构建会失败,因为在CI服务器安装依赖项时,它会对一些包含中断更改的包进行小的更新。如果库作者尊重semver,而工程师假设API契约一直受到尊重,就不会出现这种情况。

纱线解决了这些问题。通过纱线安装包的不确定性问题。锁定文件,并确保在所有机器上的node_modules中,每个安装都得到完全相同的文件结构。纱线在您的计算机中使用了一个全局缓存目录,以前下载过的包不必重新下载。这也支持离线安装依赖项!

最常见的纱线命令可以在这里找到。大多数其他的纱线命令类似于npm,可以使用npm版本。我们最喜欢的命令之一是纱线升级-交互式,这使得更新依赖项变得非常容易,特别是在现代JavaScript项目需要如此多的依赖项的时候。一定要去看看!

npm@5.0.0于2017年5月发布,它似乎解决了纱线想要解决的许多问题。一定要注意!

预计持续时间:2小时。

Alternatives

旅程才刚刚开始

祝贺你走到这一步!今天的前端开发是困难的,但它也比以前更有趣。到目前为止,我们所介绍的内容将帮助任何新工程师快速掌握我们的技术。还有更多的东西需要学习,但是在本质上建立一个坚实的基础将有助于学习其余的技术。这个有用的前端web开发人员路线图显示了各个方面可用的替代技术。

我们的技术决策是基于快速成长的Grab工程团队所看重的——前端代码库的可维护性和稳定性。这些决策可能适用于较小的团队和项目,也可能不适用于较小的团队和项目。评估什么对你和你的公司最有效。

随着前端生态系统的发展,我们正在积极探索、试验和评估新技术如何使我们成为一个更高效的团队,并提高我们的生产力。我们希望这篇文章能让你了解我们在Grab使用的前端技术。如果你对我们正在做的事情感兴趣,我们正在招聘!

感谢Joel Low, Li Kai和Tan Wei Seng审阅了本文的草稿。

原帖可以在GitHub上找到。未来的学习指南将在那里更新。如果你喜欢你正在阅读的东西,给它打一颗星吧!?

More Reading

General

Other Study Guides

Footnotes

  1. This can be solved via webpack code splitting

  2. Universal JS to the rescue! 

 

原文:https://engineering.grab.com/grabs-front-end-study-guide

本文:https://pub.intelligentx.net/node/804

讨论:请加入知识星球或者小红圈【首席架构师圈】

Article
知识星球
 
微信公众号
 
视频号