开发团队必备的现代前端开发指南
长按上图识别二维码报名济南源创会
前端开发从未像现在这样复杂和令人兴奋。基本上每隔一天就会出现新的工具、库、框架和插件。要学习的东西越来越多。
好在我们的 Grab web 团队(译者注:Grab 是东南亚的一家打车平台)一直遵循着最新、最佳的方法,并将现代 JavaScript 生态系统纳入了我们的 web 应用。
这样也导致,我们的新员工或后端工程师,他们可能会不熟悉这些现代 JavaScript 生态系统,为了在 web app 中完成某项功能或修复某些 bug , 他们不得不去学习,最终被不断涌现的新事物所“淹没”。
为了指导他们快速接受前沿技术的演进,轻松熟悉生态系统,并尽可能快地输出代码。我们发布了这样一本学习指南,介绍我们做了什么和为什么要这样做。
本指南的灵感来源于“治疗 JavaScript 疲劳的学习计划”(A Study Plan to Cure JavaScript Fatigue),并在基于目前最适合 Grab 发展的基础上,对下面这些适用于前端开发的库和框架进行推荐。
文中还会解释选择某某库和某某框架的原因,并提供学习资源链接,以便读者能够自由选择。以及在某些情况下可能效果更好的替代选择,以供参考和进一步自我探索。
如果您非常熟悉前端开发,并且一直有跟进最新的技术,本指南可能对您用处不大。它偏向针对前端新手。如果您的公司正在探索现代 JavaScript 堆栈,您会发现本指南可能对您的公司也有用!
请注意,本指南也有在 GitHub (http://github.com/grab/front-end-guide)上发布,我们将定期更新。
对核心编程概念有一定理解。
可使用基本的命令行操作并熟悉源码版本控制系统(如 Git )。
有 Web 开发经验。 使用 Ruby on Rails、Django、Express 等框架构建过 Web 应用。
了解 Web 工作原理。 熟悉 Web 协议和约定,如 HTTP 和 RESTful API 。
单页应用(Single-page Apps)
现代 JavaScript( New-age JavaScript)
用户界面(User Interface)
状态管理(State Management)
规则编码(Coding with Style)
测试(Testing)
JavaScript 检测(Linting JavaScript)
CSS 检测(Linting CSS)
类型(Types)
系统构建(Build System)
包管理(Package Management)
持续集成(Continuous Integration)
托管(Hosting)
部署(Deployment)
如果您已有相关经验,可选择跳过部分内容。
单页应用(SPAs)
Web 开发人员现在将其构建的产品称为 Web 应用,而不是网站。虽然这两个术语之间没有严格的区别,但 Web 应用往往是高度互动和动态的,允许用户执行操作并接收响应。
传统上,浏览器从服务器接收 HTML 并呈现。当用户定位到另一个 URL 时,需要进行全页刷新,并且服务器为新页面发送新的新 HTML 。这被称为服务器端渲染。
然而,在现代的 SPAs 中,已被客户端渲染取代。浏览器从服务器加载初始页面,以及整个应用所需的脚本(框架、库、应用代码)和样式表。当用户定位到其他页面时,不会触发页面刷新。通过 HTML5 History API 更新页面的 URL 。浏览器通过 AJAX 请求检索新页面(通常以 JSON 格式)所需的新数据。然后, SPA 通过 JavaScript 动态更新已经在初始页面加载中已经下载好的新页面。这种模式类似于原生手机应用的工作原理。
优势:
应用感更强,用户不会看到由于全页刷新导致页面之间的闪烁。
对服务器进行的 HTTP 请求较少,因为不必为每个页面加载重复下载相同的资料。
明确分离客户端与服务器之间的关系;可以轻松地为不同的平台构建新的客户端而无需修改服务器代码。只要 API contract 不被破坏,还可以独立地修改客户机和服务器上的技术栈。
劣势:
需加载多个页面所需的框架、应用代码和初始页面加载需要的成本。
在服务器上会有一个额外的步骤,即将其配置为将所有请求被路由到单个入口点,并允许客户端路由从那里接管。
SPAs 依赖于 JavaScript 来呈现内容,但并不是所有的搜索引擎在爬行期间都会执行 JavaScript ,而且可能会在您的页面上看到空的内容。这在无意中会影响应用的 SEO 。
虽然传统的服务器端呈现的应用仍然是可行的选择,但是由于客户端和服务器代码可以独立开发和发布,因此清晰明了的客户端和服务器分离可以更好地扩展到较大的工程团队。
由于 Web 开发人员构建的是应用而不是页面,因此客户端 JavaScript 架构变得越来越重要。在服务器端呈现的页面中,通常使用 jQuery 的代码片段将用户交互性添加到每个页面。但是,当构建大型应用程序时,光有 jQuery 还不够。毕竟,jQuery 主要是一个用于 DOM 操作的库,它不是框架;无法为应用定义清晰的结构和组织。
JavaScript 框架往往被构建以便在 DOM 上提供更高级别的抽象,从而允许将内存中的状态保留在 DOM 之外。使用框架还带来了一些适合应用的重用建议的推荐和最佳做法的好处。团队中不熟悉代码基础但具有框架经验的新工程师将会更容易理解代码,因为它是以一种他们熟悉的结构组织起来的。流行框架通常会有很多教程和指南,利用同事和社区的知识和经验,可帮助新工程师快速上手。
学习链接
单页应用:优缺点分析(http://stackoverflow.com/questions/21862054/single-page-app-advantages-and-disadvantages)
Web 开发的演进(http://blog.isquaredsoftware.com/presentations/2016-10-revolution-of-web-dev/)
选择客户端渲染的原因(https://medium.freecodecamp.com/heres-why-client-side-rendering-won-46a349fadb52)
现代 JavaScript
在深入了解构建 JavaScript Web 应用的各个方面之前,熟悉 Web-JavaScript 或 ECMAScript 的语言非常重要。 JavaScript 是一种非常通用的语言,可以用它来构建 Web 服务器,也可以构建原生移动应用和桌面应用。
在 2015 年之前,最后一次重大更新是 2011 年发布的 ECMAScript 5.1 。然而,近年来,JavaScript 在短时间内突然出现大幅度改善。2015 年,ECMAScript 2015(以前称为 ECMAScript 6 )发布,引入大量的语法结构,使得编写代码不再那么笨重。如果你对这段历史感兴趣,Auth0 有写一篇关于 history of JavaScript 的文章。直到现在,也并非所有的浏览器都完全实现了 ES2015 规范。类似 Babel 这类的工具使开发人员能够在其应用中编写 ES2015 ,随后 Babel 将其转换为 ES5 以兼容浏览器。
熟悉 ES5 和 ES2015 都至关重要。 ES2015 现在依然很新,很多开源代码和 Node.js 应用仍然是使用 ES5 编写。如果您是在浏览器控制台中进行调试,可能无法使用 ES2015 语法。另一方面,稍后将介绍的许多现代库的文档和示例代码都是用 ES2015 写的。在 Grab ,我们使用 babel-preset-env 来享受 JavaScript 的不断改进的语法来提升生产力。 babel-preset-env 能智能地确定哪些 Babel 插件是必需的(哪些新的语言特性不被支持,需被翻译),以让浏览器更好地对 ES 的各种语言特性提供原生支持。如果您喜欢使用已经稳定的语言特性,那么 babel-preset-stage-3(一个完全可以在浏览器中实现的规范)可能会更适合您。
花一两天的实际去修正 ES5 并摸索 ES2015 。 ES2015 中使用最多的特性包括“箭头函数”、“Classes”(语法糖)、“字符串模板”、“解构”,“Default/Rest/Spread 操作符”以及“导入和导出模块”。
预估时间: 3–4 天. 可在学习其他库并尝试构建应用时学习/查找语法。
学习链接
Learn ES5 on Codecademy(https://www.codecademy.com/learn/learn-javascript)
Learn ES2015 on Babel(https://babeljs.io/learn-es2015/)
ES6 Katas(http://es6katas.org/)
Free Code Camp(https://www.freecodecamp.com/)
你不知道的 JS (高阶内容,初学者可选)(https://github.com/getify/You-Dont-Know-JS)
用户界面 — React
如果要说近年来给前端生态带来风暴式影响的 JavaScript 项目,当属 React 。 React 是一个由 Facebook 开发的库。 在 React 中,开发人员为其 Web 界面编写组件并将其组合在一起。
React 带来了许多激进的想法,并鼓励开发人员重新思考最佳实践。 多年来,Web 开发人员被灌输分开编写 HTML、JavaScript 和 CSS 的理念 ,但 React 恰恰相反,鼓励在 JavaScript 中编写 CSS 。这听起来很疯狂,但在尝试之后,会发现其实并不奇怪。作为影响前端发展正转向基于组件的发展模式的关键,React 的特点如下:
声明式 — 描述想在 View 中看到的,而不是如何实现它。在 jQuery 时代,开发人员必须提出一系列的步骤来操纵 DOM ,从一个应用状态到下一个应用状态。在 React 中,只需更改组件中的状态,View 将根据状态进行更新。也可通过查看 render()方法中的标记来确定组件的外观。
函数式— View 是基于 state 和 props 的纯函数。多数情况下,React 组件由 props(外部参数)和 state(内部数据)定义。相同的 props 和 state ,会构成相同的视图。纯函数易于测试,功能组件也大多相同。由于组件的界面定义良好,可通过提供不同的 props 和 state 来对组件进行测试并比较,从而轻松完成测试。
可重用性 — 以基于组件的方式编写 View 就是鼓励重用性。我们发现定义一个组件的 propTypes 能让 React 代码自我记录,以让用户可以清楚地知道使用该组件需要什么。此外,您的视图和逻辑在组件中是独立的,不会受到影响也不影响其他组件。只需向组件提供相同的 props ,就可轻松地在大规模重构过程中 shift 组件。
高性能— 您可能已经听说 React 使用的是 virtual DOM(请勿与 shadow DOM 混淆),并且在状态发生变化时重新呈现所有内容,那你知道为什么需要 virtual DOM 吗?虽然现代 JavaScript 引擎很快,但从 DOM 读取和写入速度很慢。 React 在内存中保持 DOM 的轻量级虚拟渲染。重新渲染一切本身就是一句有误导性的术语。在 React 中它实际上是指重新渲染 DOM 的内存中呈现,而不是实际的 DOM 本身。当组件的底层数据发生变化时,将创建一个新的虚拟呈现,并与先前的进行比较。然后将差异(所需的最小变化集)修补到真正的 browser DOM 。
易于学习 — 学习 React 非常简单。与 this 相比,React API surface 相对较小; 只有很少的几个 API 可以学习,并且不会经常变化。React 社区是最大的社区之一,同时也是一个充满活力的工具生态系统,有开放的 UI 组件,以及一大批在线资源可供学习。
优秀的开发体验 —有许多工具可以改善 React 的开发体验。React Developer Tools 是一个浏览器扩展,可检查组件,查看和操作其 props 和 state 。使用 webpack 进行热更新可让您在浏览器中查看代码的更改,而无需刷新浏览器。Facebook 还提供了一个 codemod 脚本,以帮助您在有库更新时将代码迁移到新的 API ,使升级过程相对无痛。
经过多年发展,其实也出现了比 React 更出色的新视图库。React 可能不是最快的库,但在生态系统、整体使用体验和效率方面,它仍然是最强大的库之一。 Facebook 正在通过重写基础协调算法,力图使 React 更快。 React 让我们知道如何编写更好的代码和更好维护的 Web 应用,并让我们成长为更好的工程师。
我们建议您在 React 主页上浏览一个关于建立 tic-tac-toe 游戏的教程,以先了解 React 是什么及能做什么。想要进一步深入学习,可查看 React Router 的创始人、React 社区专家发布的高级免费课程“ React Fundamentals ”,里面还涵盖了 React 官方文档未写入的更高级的概念。Facebook 的 Create React App 是以最小配置支持 React 项目的工具,也强烈建议在您新的 React 项目中启用。
React 是一个库,而不是一个框架,并不处理视图层以下的层次 - 应用状态。后面会说到。
估计时间: 3–4 天. 尝试构建类似待办事项列表这种简单的项目,去 Hacker News 克隆一些纯 React 经验。 你会慢慢收获和成长,期间可能会面临一些也许无法用 React 解决的问题,下面的主题会讲到…
学习链接
React Official Tutorial(https://facebook.github.io/react/tutorial/tutorial.html)
React Fundamentals(https://reacttraining.com/online/react-fundamentals)
Simple React Development in 2017(https://hackernoon.com/simple-react-development-in-2017-113bd563691f)
Presentational and Container Components(https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.5iexphyg5)
替代方案
Angular
Ember
Vue
Cycle
状态管理 — Flux/Redux
随着您的应用越来越大,可能会发现应用结构变得有点混乱。应用中的组件可能要共享和显示常见数据,但 React 中却没有很优雅的方式来处理这些情况。 毕竟,React 只是视图层,它并没有明确规范如何在传统的 MVC 范例中构建应用的其他层,如 model 和 controller 。为了解决这个问题,Facebook 发明了 Flux ,一款应用架构,通过使用单向数据流来补充 React 的可组合视图组件。点此可阅读关于 Flux 如何运作的介绍。 总而言之,Flux 范式(Flux pattern)具有以下特点:
单向数据流 — 使应用更可预测,以轻松跟踪更新。
关注点分离 — Flux 架构中的各个部分都有明确的职责,并且高度分离。
适用于声明式编程 — store 可将更新发送到 view ,而无需指定如何在状态之间转换视图。
由于 Flux 本身不是一个框架,开发人员尝试提出各种 Flux 范式的实现。最后,出现了一个最亮眼的赢家,那就是 Redux 。 Redux 将来自 Flux、Command pattern 和 Elm 架构的想法融合在一起,已然成为目前 React 开发者最常使用的状态管理库。其核心概念是:
应用状态(state)是由单个普通的 JavaScript 对象(POJO)描述。
调度一个 action (也是 POJO) 来修改状态。
Reducer 是一种纯函数,它利用当前状态和动作来产生新的状态。
这些概念听起来很简单,但功能强大,因为它们使应用能够:
在服务端呈现状态,在客户端启动
跟踪、记录和回溯整个应用的更改
轻松执行撤消和重做
Redux 创始人 Dan Abramov 非常仔细地为 Redux 撰写了详细的文档,同时为初阶和高阶的 Redux 使用者创建了全面的视频教程。这些是学习 Redux 非常有用的资源。
View 和 State 相结合
虽然 Redux 并不是一定要和 React 一起使用,但我们强烈推荐。 React 和 Redux 有很多相似的理念和特点:
函数式组合范式 — React 由 views (纯函数) 构成,而 Redux 由 pure reducers (也是纯函数) 构成。在指定输入组合时,输出都是可预见的。
易于 Reason About — 这个词您可能听过很多次,但实际上是什么意思?我们将其解释为对代码的控制和理解 - 代码以我们期望的方式行事,当有问题时,可以轻松发现问题。据已有的经验,React 和 Redux 会使调试更简单。由于数据流是单向的,因此跟踪数据流(服务器响应、用户输入事件)更容易,并且可以直接定位问题发生在哪一层。
结构分层 — 应用/ Flux 架构中的每一层都是一个纯函数,具有明确的职责。为纯函数编写测试相对容易。
开发体验 — 在开发过程中,诸如 Redux DevTools 之类的开发工具,可帮助调试和检查应用。
此外,您的应用可能需要处理异步调用,例如进行远程 API 请求。redux-thunk 和 redux-saga 就是用来解决这些问题的。理解他们可能需要一些时间,因为需要理解函数编程和生成器。建议只在有需要的时候处理它。
react-redux 是一个官方的封装库,非常简单易学。
预估时间: 4 days. 下面的 Egghead 课程可能有点耗时,但值得花时间。 学完 Redux 后,您可以尝试将其纳入已构建好的 React 项目中。 Redux 是否解决了您在纯 React 中遇到的一些状态管理问题?
学习链接
Flux 主页(http://facebook.github.io/flux)
Redux 主页(http://redux.js.org)
Egghead Course — Redux 入门(https://egghead.io/courses/getting-started-with-redux)
Egghead Course — 使用惯用的 Redux 构建 React 应用(https://egghead.io/courses/building-react-applications-with-idiomatic-redux)
React Redux Links(https://github.com/markerikson/react-redux-links)
You Might Not Need Redux(https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367)
替代方案
MobX
规则编码— CSS Modules
CSS(层叠样式表)是描述 HTML 元素布局的规则。写好 CSS 很难。编写可维护和可扩展的 CSS ,通常需要多年的经验和积累。具有全局命名空间的 CSS 基本上是为 Web 文档而设计的,并不是真正用于支持组件架构的 Web 应用。因此,经验丰富的前端开发人员总结了设计方法学,指导人们如何为复杂项目编写合理的 CSS ,例如使用 SMACSS、BEM、SUIT CSS 等。
CSS 方法学所带来的样式封装是由公约和纲要强制执行的,打破了开发者不遵守约定的时代。
正如您可能已经意识到的那样,前端生态系统的工具十分丰富,甚至趋于饱和,因此当发现已经有一些工具来分块解决大规模编写 CSS 问题时,应该也不会感到奇怪。 “At scale” 意味着有大量开发人员正在开展同一个大型项目,并触及相同的样式表。目前在 JS 中编写 CSS 还没有社区认可的最佳方式 ,我们希望有一天,能像 Redux 一样,在所有的 Flux 实现中出现赢家。目前,我们在使用的是 CSS Modules 。 CSS modules 是对现有 CSS 的改进,旨在解决 CSS 中全局命名空间的问题;它允许编写默认情况下的局部样式并封装到组件中。使用 CSS modules ,大型团队可以编写模块化和可重用的 CSS ,而不用担心冲突或覆盖应用的其他部分。不过,CSS modules 最终仍然需要编译成浏览器可识别的正常全局命名空间的 CSS ,因此学习和理解原始 CSS 仍然很重要。
如果您是一个 CSS 初学者,Codecademy 的 HTML & CSS 课程将是不错的开始。然后,攻读 Sass preprocessor ,这是 CSS 语言的扩展,在基础上增加了语法改进,并鼓励样式可重用性。再去研究上面提到的 CSS 方法学,CSS modules 放到最后去学。
预估时间: 3–4 days. 尝试使用 SMACSS / BEM 理论 和/或 CSS modules 来设计应用。
学习链接
Learn HTML & CSS course on Codecademy(https://www.codecademy.com/learn/learn-html-css)
Intro to HTML/CSS on Khan Academy(https://www.khanacademy.org/computing/computer-programming/html-css)
SMACSS(https://smacss.com/)
BEM(https://smacss.com/)
SUIT CSS(http://suitcss.github.io/)
CSS Modules Specification(https://github.com/css-modules/css-modules)
Sass Homepage(http://sass-lang.com/)
前端面试问题答案 — HTML (https://medium.com/@yangshun/clearing-your-front-end-job-interview-html-706f8b2c7dca)
前端面试问题答案 — CSS (https://medium.com/@yangshun/clearing-your-front-end-job-interview-css-95bdd82871f2)
替代方案
JSS
Styled Components
可维护性
代码读取的频率往往比编写的频率更高。在 Grab 尤其如此,团队规模庞大,有多名工程师在多个项目中工作。我们非常重视代码的可读性、可维护性和稳定性,有几种方法可实现:“大量的测试”,“一致的编码风格”和 “类型检查”(Typechecking)。
测试 — Jest + Enzyme
Jest 是 Facebook 的一个测试库,旨在使测试过程无痛。 与 Facebook 的其他项目一样,它提供了一个很好的、开箱即用的开发体验。 测试可以并行运行,从而缩短整体持续时间。 默认情况下,在监视模式期间,仅需运行针对更改文件的测试。我们尤为喜欢的一个功能是——“快照测试”(Snapshot Testing)。 Jest 可以保存您的 React 组件和 Redux 状态的生成输出,并将其保存为序列化文件。 Jest 还附带内置的 mocking、assertion 和 test coverage 。一个库搞定一切!
React 带有一些实用测试工具,但 Airbnb 的 Enzyme 能让您更容易进行 generate、assert、manipulate 和 traverse。 建议使用 Enzyme 来测试 React 组件。
Jest 和 Enzyme 让书写前端测试更加有趣和简单。试想,当编写测试变得愉悦时,开发者自然会更多的进行测试。明确的职责和界面,有助于 React 组件和 Redux actions / reducer 更容易被测试。对于 React 组件,我们可以测试指定的一些 props ,渲染所需的 DOM ,以及在某些模拟用户交互时触发的回调。对于 Redux reducer ,我们可以测试指定一个前状态和一个动作,以及产生的结果状态。
Jest 和 Enzyme 的文档都非常简洁,看完应该就能懂。
预估时间: 2–3 天. 尝试为您的 React + Redux 应用编写 Jest + Enzyme 测试!
学习链接
Jest Homepage(http://facebook.github.io/jest/)
Testing React Applications with Jest(https://auth0.com/blog/testing-react-applications-with-jest/)
Enzyme Homepage(http://airbnb.io/enzyme/)
Enzyme: JavaScript Testing utilities for React(https://medium.com/airbnb-engineering/enzyme-javascript-testing-utilities-for-react-a417e5e5090f)
替代方案
AVA
Karma
Linting JavaScript — ESLint
linter 是一个静态代码分析并发现问题的工具,使用该工具可能会阻止潜在的问题/运行时错误,同时加强编码风格。在评审者不需要对编码风格进行挑剔评论时,可在 pull 请求时节约时间。ESLint 是一种高度可扩展和可自定义的 JavaScript 代码的工具。团队可以编写自己的 lint 规则来执行自定义样式。在 Grab 中,我们使用了 Airbnb 的 eslint-config-airbnb 预设,它已经按照 Airbnb JavaScript 样式指南配置了通用的优良编码风格。
在大多数情况下,使用 ESLint 就像在项目文件夹中调整配置文件一样简单。如果你不需要为其编写新的规则,就没有什么关于 ESLint 需要学习的了。只要知道他们的明面上的错误,并用 Google 来查找下推荐的风格。
估计时间:1/2天。这里没有什么需要学习的。将 ESLint 添加到你的项目并修复 linting 错误即可!
学习链接
ESLint 主页(http://eslint.org/)
Airbnb JavaScript Style Guide(http://eslint.org/)
替代方案
Standard
JSHint
Linting CSS — stylelint
如前所述,优异的 CSS 是非常难写的。在 CSS 上使用静态分析工具有助于维护我们的 CSS 代码质量和编码风格。对于 linting CSS ,我们使用 stylelint 。和 ESLint 一样,stylelint 是以模块化的方式设计的,允许开发人员打开/关闭规则,并为其编写自定义插件。除了 CSS 之外,stylelint 还能够解析 SCSS ,并且为 Less 提供试验性支持,这样可以降低采用大多数现有代码库的门槛。
如果你已经学习了 ESLint ,考虑到它们之间的相似性,学习 stylelint 就会轻松。 stylelint 目前正在被大型公司所使用,例如 Facebook、Github 和 Wordpress 。
stylelint 的一个缺点是自动修复功能尚未完全成熟,只能处理有限数量的规则。但是,这个问题应该随着时间的推进得到改善。
估计时间:1/2天。 没什么太多东西需要学习的。 将 stylelint 添加到您的项目中并修复 linting 错误!
学习链接
stylelint 主页(https://stylelint.io/)
使用 stylelint 来检查你的 CSS 代码(https://css-tricks.com/stylelint/)
替代方案
Sass Lint
CSS Lint
类型 — Flow
静态类型在编写应用时会带来很多好处。它们可以早早地发现代码中的常见 bug 和错误。类型还可以作为代码的文档,提高代码的可读性。随着代码库的增长,类型会越来越重要,因为它们会在重构时给予我们足够的底气。清楚每个对象持有什么样的值以及每个函数回调和返回的参数,也有助于团队的新成员快速上手。
将类型添加到代码中会增加细致程度和语法学习曲线。但这种成本是预支的,并且会随时间推移而摊销。在复杂的项目中,代码和工作人员的可维护性会随着时间的推移而变化,为代码添加类型带来的好处远比缺点多。
最近,我不得不在代码库中修复一个我几个月没有再碰到过的 bug 。感谢类型,我可以轻松地了解代码正在做什么,让我有信心完成修复。
往 JavaScript 添加静态类型的两个最大竞争者是 Flow(Facebook 出品)和 TypeScript(Microsoft 出品)。截至目前,二者并没有明显的优胜者。不过,我们选择的是使用 Flow 。因为我们发现,与 TypeScript 相比,Flow 具有较低的学习曲线,并且将现有代码库迁移到 Flow 更为简单。同样是由 Facebook 构建,Flow 与 React 生态系能更好地整合。Flow 的作者之一 James Kyle 有撰写一篇 Flow 和 TypeScript 对比。
不管孰优孰劣,由于语法和语义非常相似,从 Flow 转移到 TypeScript 也不会特别困难,我们将在后续对此重新评估。反正在最开始,使用其中一个总比一个都不要要好。
Flow 最近重做了主页,现在很漂亮!
预估时间: 1 天. Flow 非常易于学习,因为类型注释的感觉很像 JavaScript 语言的自然扩展。将 Flow 注释添加到您的项目中,体验类型系统带来的强大能力。
学习链接
Flow Homepage(https://flow.org/)
TypeScript vs Flow(https://github.com/niieani/typescript-vs-flowtype)
替代方案
TypeScript
系统构建 — webpack
这部分会保持简短,因为设置 webpack 是一个繁琐的过程,已经被前端开发必学的新兴事物所淹没的开发人员可能会直接忽略。简而言之,webpack 是一个模块绑定工具,它将前端项目及其依赖项编译成绑定包提供给用户。通常,项目已经设定好了 Webpack 配置,开发人员不用过多改动。从长远来看,了解 Webpack 仍然是一件好事,因为 webpack 也有类似热加载和 CSS modules 的功能。
我们认为 SurviveJS 的 webpack 演练是学习 webpack 的最佳资源。这是对官方文档很好的补充,建议先进行演练,然后在需要进一步定制时参考文档。
预估时间: 2 天 (可选).
学习链接
webpack Homepage(https://webpack.js.org/)
SurviveJS — Webpack: From apprentice to master(https://survivejs.com/webpack/foreword/)
替代方案
Rollup
Browserify
包管理 — Yarn
如果您仔细观察 node_modules 目录,您会为其中包含的目录数量而感到震惊。每个 babel 插件、lodash 函数,都是一个独立的包。当有多个项目时,这些软件包在每个项目中都重复存在,而且在很大程度上相似。每次新项目运行 npm install 时,即使这些软件包已经存在于计算机中的某些项目中,仍然会被一次又一次地重新下载。
通过 npm install 安装的软件包中也存在 non-determinism 的问题。我们的一些 CI 构建失败是因为在 CI 服务器安装依赖关系的时候,它会将一些包含破坏性改变的包进行次要升级。如果库的作者慎重对待 semver ,工程师不再自认为一直有着重盯着 API contracts ,那这种情况就不会发生。
Yarn 解决了这些问题。已安装软件包的 non-determinism 是通过一个名为 yarn.lock 的文件来处理的,这样可以确保每次的安装都能在所有机器上的 node_modules 中生成完全相同的文件结构。Yarn 在机器中使用全局缓存目录,之前下载的软件包不必再次下载。这也使得可离线安装依赖性!
最常见的 Yarn 命令可在这里找到。我们最喜欢的命令之一是 yarn upgrade-interactive ,这使得更新依赖性变得轻而易举,特别是当现代 JavaScript 项目需要这么多依赖关系时。
npm 5.0.0 已于 2017 年 5 月发布,似乎涉及到 Yarn 旨在解决的许多问题。多多关注!
预估时间: 2 小时.
学习链接
Yarn Homepage(https://yarnpkg.com/)
Yarn: A new package manager for JavaScript(https://code.facebook.com/posts/1840075619545360)
替代方案
Good old npm
持续集成
我们使用 Travis CI 进行连续集成(CI)pipeline 。Travis 是 Github 上非常受欢迎的 CI ,其 build matrix 功能对于包含多个项目的存储库很有用。我们配置 Travis 来执行以下操作:
项目检测
项目单元测试
如果测试通过:Jest 生成的测试覆盖率将上传到 Codecov ;生成一个包含 webpack 的包到 build 目录中。将构建目录 tar 命名为 <hash> .tar ,并将其上传到存储所有 tar 构建的 S3 存储区;向 Slack 发送通知以告知 Travis 构建结果。
学习链接
Travis Homepage(https://code.facebook.com/posts/1840075619545360)
Codecov Homepage(https://codecov.io/)
替代方案
Jenkins
CircleCI
Hosting — Amazon S3
传统来说,接收网页请求的 Web 服务器将呈现服务器上的内容,并返回一个包含用于请求者的动态内容的 HTML 页面。这也被称为服务器端渲染。如前面在单页应用程序部分中所述,现代 Web 应用不涉及服务器端呈现,而是使用提供静态资源文件的 Web 服务器。 Nginx 和 Apache 是可行的选择,并不需要太多的配置来安排和运行。请注意,Web 服务器必须配置为将所有请求路由到单个入口点,并允许客户端路由接管。前端路由的流程如下所示:
Web 服务器接收指定路由的 HTTP 请求,例如 / users / john。
无论服务器接收到哪条路由,都可以从静态 assets 目录中发送 index.html 。
index.html 将包含一个加载着处理客户端路由的 JavaScript 框架/库的脚本。
客户端路由库读取当前路由,并与当前路由的 MVC(或相关的)框架进行通信。
MVC JavaScript 框架基于路由呈现所需的视图,如果需要的话也可能会在从 API 获取数据之后(呈现)。举个例子,加载 UsersController ,将用户名为 john 的用户数据提取为 JSON ,再将数据与视图合并,并将其呈现在页面上。
提供静态内容的优质做法是使用缓存并将其放在 CDN 上。我们使用的是亚马逊简易存储服务(S3),因为它可以承载和充当静态网站内容的 CDN 。我们认为它是一个价格合理又可靠的解决方案,可以满足我们的需求。 S3提供了一个 “Use this bucket to host a website” 选项,基本上能将所有的路由请求定向到 bucket 的根目录,这也意味着我们不需要自己搭建需要特殊路由配置的 Web 服务器。
我们在 S3 上有托管 Hub 这样一个 Web 应用。此外,还托管了从每个成功的 Travis 构建生成的 .tar 文件。
学习链接
Amazon S3 Homepage(https://codecov.io/)
Hosting a Static Website on Amazon S3(https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html)
替代方案
Google Cloud Platform
Now
部署
将产品送达到用户手上的最后一步是部署。我们使用的是一个强大的自动化软件 Ansible Tower ,能够轻松部署我们的构建。
如前所述,在成功构建之后,我们的所有提交都将被上传到一个中央的 S3 bucket 进行构建。跟随我们的发行版本,有命令自动生成最新版本的发行说明。当到发布的时间时,我们会运行一个命令来标记最新的提交,并推送到代码托管平台。Travis 将在该标记的提交进行 CI 步骤,并将一个 tar 文件与版本号一起上传进行构建。
在 Tower, 上,我们只需指定要部署到 hosting bucket 的 .tar 的名字,Tower 将执行以下操作:
从 S3 bucket 下载所需的 .tar 文件
提取指定环境的配置文件中的内容并替换
将内容上传到 hosting bucket
向 Slack 发送消息通知部署成功
整个过程在 30 秒内完成,并且使用 Tower 会让部署和回滚更容易。当意识到错误部署时,可以简单地找回以前的稳定标签并进行部署。
学习链接
Ansible Tower Homepage(https://www.ansible.com/tower)
恭喜您一路学习到这!如今的前端开发比较难,但也比以前有意思。到目前为止,我们已经帮助所有的 Grab Web 团队的新工程师快速掌握技术。虽然还会有更多的东西需要学习,但建立坚实的基础将有助于学习其他技术。这张有用的前端 Web 开发人员路线图展示了可用于各个方面的替代技术。
本文最初发布于 Grab 的工程师博客。最原始的学习指南可在 Github 上找到,后续也将在那进行更新。
更多精彩翻译请前往公众号菜单栏“读我”->“干货分享”查看。