vlambda博客
学习文章列表

前端开发者正在被迫成为全栈开发人员

作者 | Chris Coyier
译者 | 王强
策划 | 李俊辰

本文是我之前的文章《当前端等同于全栈》的扩展版本,该文发表在 Stripe 的精品杂志 Increment 上。本文也是我的另外两篇文章《大鸿沟》和《糟糕,我想我们现在是全栈开发人员了》的某种延伸。

当我在 WordPress 主题中发现 style.css 文件时,我就对前端开发一见钟情了。对我来说那就是(现在依然是)所有奇迹的源泉。我可以(并且能做到!)更改其中的几行内容,就完全改变网站的外观。这样的游戏太令人激动了。

前端开发者正在被迫成为全栈开发人员

只要改一改 HTML 和 CSS,我可以 改变读者阅读一篇文章的体验。我可以让你在购买某场活动的门票时更轻松舒适。我可以为你带来更多与朋友分享某些东西的机会。

这都是我成为专业前端开发人员很久以前的事情了,但就算在那个时候,我都感受到了这份工作给人带来的刺激与陶醉感。前端开发就是这样,它是一种艺术表现形式,但往往会受到诸如直接消息通信和业务目标之类的束缚。

前端开发处于 艺术与逻辑 的交汇处、业务和表达 的十字路口。它需要 大脑左半球与右半球 的通力合作,是 设计师的创意与书呆子的技术 调和而成的鸡尾酒。

我喜欢它。

前端开发者正在被迫成为全栈开发人员

回顾从初中到大学的课程,我选的课既有很多专注于计算机的,也有不少艺术类的,所以我自然而然想要从事一种可以同时做这两件事情的职业。

“前端开发人员”这个术语定义得很好,也很容易理解。首先,这是一个职位。我敢打赌,肯定有一些人会在自己的名片上写上这样的名头,或者像“前端设计师”“UX 开发人员”或“UI 工程师”之类的变体。至于围绕这些名号含义的争论我并不感兴趣。我发现不同职位和不同公司之间的角色差异很大,光看职位头衔是不足以知道它都做些什么的。想要获得这份工作,更重要的是要证明你知道自己最清楚在做什么。

前端开发者正在被迫成为全栈开发人员

职位叫什么名字没什么区别。从宏观来看,只要这份工作的内容是构建网站,前端开发人员就得主要和浏览器打交道。不夸张地说:

  • 前端 = 浏览器

  • 后端 = 服务器

虽然过去几十年来这份工作发生了很大变化,但这种差异在相当程度上仍然是成立的。

作为“浏览器人员”,这个领域有一些事实是需要了解的。其中之一是各种浏览器的整体情况:尽管标准机构已经尽力而为了,但不同浏览器的行为仍然有所不同。就在今天我写文章的同时我处理了一个错误:我从一个 API 获取了一个日期字符串,它的格式很奇妙,我试着对它使用.toISOString() JavaScript API 时,Firefox 抛出了一个错误,但在 Chrome 里并不会出问题。作为前端开发人员,这就是我们的日常生活。这就是我们的工作。

就算是桌面 PC 上的浏览器,用户使用浏览器的方式也存在差异。他们的窗口有多大?他们是否在操作系统上激活了黑暗模式?显示器的色域多大?像素密度是多少?网络带宽情况如何?他们在使用键盘和鼠标吗?或者哪个都不用?所有这些问题也都适用于移动设备,在移动设备中浏览器的环境甚至可能更加复杂。要是再仔细看看 HTML 电子邮件,你就会更头疼了。

未知数太多了,针对这种未知情况来开发网站,答案完全掌握在前端开发人员手中。

前端开发者正在被迫成为全栈开发人员

这份工作中哪个方面是最重要的?是使用这些浏览器的人们。他们就是为什么我们要构建所有这些东西的原因所在。我们想要用自己疯狂的 CSS 技能给他们留下深刻印象。我们想要用自己的小部件打动他们。我们所有的业务图表都是以他们为核心。他们的反应可以像摇曳的风铃般打乱我的心情。我们为这些用户着想,视他们为上帝,而他们的世界之大远非浏览器可比。他们在说不同的语言,他们想要的东西各有不同,他们正在尝试解决各种各样的问题,他们的身体条件并非一致,他们的需求有的紧迫有的宽松。同样,帮助他们解决问题的钥匙也牢牢掌握在前端开发人员手中。我们在文本编辑器中输入的代码与我们希望服务的用户直接相通。

身为前端开发人员,我们身处所构建的事物与这些事物服务的人们之间的 分界线 上,而我们有很多人正是喜欢在这一前线发光发热。

感受到肩头的重担了吗?我甚至还没有提到 React 呢。

“我们关心用户”这句话听上去可能有一些动人。我认为,在一家高水平的公司中,从首席执行官到下层员工,每个人都会关心用户。不过在前端这里这句话的含义不太一样。当我们编写<button>这行代码时,实际上真的是将一个按钮放入浏览器窗口中,等待用户直接与其交互。当我们调整颜色时,我们调整的的确是用户看到我们作品时所看到的景象。

前端开发者正在被迫成为全栈开发人员

这就像是陶瓷艺术家用粘土塑造出咖啡杯的手柄一样,只不过我们的手工技艺用在了数字化体验上。尽管后端开发人员也可能会非常关心网站的用户,但正如 Monica Dinculescu 在一次对话中告诉我的那样,他们其实是“将这份责任外包出去了”。

我们知道,前端开发人员就是浏览器人员。这项工作使要让各种事情都能在浏览器中正常运转。因此,我们需要了解浏览器使用的语言,也就是:HTML、CSS 和 JavaScript。之所以这么说,并不是因为我是什么守旧的原教旨主义者。几十年来日复一日的前端开发工作告诉我们,了解这些基础语言是我们做好工作的关键所在。就算我们没在直接和它们打交道(HTML 可能来自另一种语言的模板,CSS 可能是由预处理程序生成的,JavaScript 可能大部分是用某种框架的术语编写的),浏览器最终还是 HTML、CSS 和 JavaScript 的世界,因此大部分调试工作都是围绕它们的,浏览器的大部分能力也是来源于它们的。

CSS 将永远是我的最爱,而 HTML 似乎需要最多的激情——但是 JavaScript 是我们真正需要研究的语言。近十年来,JavaScript 从一种用于少数交互效果的语言,发展成为整个网页设计与开发栈中的主流语言。我们只用 JavaScript 就可以编写出来网站。这是真正的变革。

JavaScript 在浏览器中有着强大的能力。从某种意义上说,它取代了 HTML 和 CSS,因为这两种语言能做的事情 JavaScript 都能做。HTML 由浏览器解析并转换为 DOM,JavaScript 也可以完全创建和处理 DOM。CSS 有自己的模型 CSSOM,这种模型将样式应用于 DOM 中的元素,而 JavaScript 也可以创建和处理这一部分。

不过,这不太公平。HTML 是浏览器在完成网站构建工作的时候最先会解析的文件。首要性是 HTML 所独有的,并且是让网站快速运行的关键一环。

前端开发者正在被迫成为全栈开发人员

实际上,如果我们只通过网络传输 HTML 文件,也足以提供站点的基本信息和功能了。

这种哲学称为渐进增强。我自己是它的粉丝,但我并不会时时刻刻完美遵循这种哲学。例如,当一个<form>的 action 属性指向一个 URL,在其中可以处理这个 form 时,这个 form 放在 HTML 里就足够了。根据渐进增强的方法,我们会先这样来构建。然后,当 JavaScript 开始执行时,它将接管提交过程并通过 Ajax 提交表单,这可能意味着更好的体验,因为页面无需刷新即可提交,我喜欢这一点。更进一步,如果没有 JavaScript,表单之外的任何<button>都是完全没法用的,因此按照渐进增强的精神,我应该等到 JavaScript 执行后才把那个按钮放在页面上(或至少把它显示出来)。可就算是我们当中最坚定的信徒也不一定总是能完美地完成这样的任务。“不就是提前把按钮放进去吗朋友,没人会因为这个挂掉的。”

JavaScript 的强大能力使其成为我们这些 Web 从业者的理想开发目标——特别是随着 JavaScript 这种语言的发展,它变得越来越强大,越来越符合人体工学,并且 JavaScript 内置的框架也越来越受到青睐。早在 2015 年,人们就已经清楚地看到 JavaScript 的使用量正以惊人的速度增长,当时 WordPress 的联合创始人 Matt Mullenweg 给开发人员留了作业:“深入学习 JavaScript”。他的建议再正确不过了。几年过去了,JavaScript 成功统治了前端开发的世界,尤其是前端开发的相关岗位。

虽然 web almanac 的数据显示,在前十亿个站点中只有 5%在使用 React,而用到 jQuery 的比例达到了 85%,但转头去看前端开发招聘市场的职位需求时,两边的比例几乎倒了过来。

我敢肯定,所有这些的背后有着各种各样的经济因素,但是人们都需要工作,工作太重要了,所以这样的数字也非常值得我们关注。

这么说来,我们都是浏览器人员,徜徉在 JavaScript 的海洋中,为人们构建各种事物。如果我们来到微观层面,从日常工作的角度上审视这份工作的话,它差不多是这个样子:

  • 将设计转化为代码;

  • 根据响应式设计的思想来跨设备设计和构建;

  • 系统化地构建内容。构建各种组件和模式,而不是一次性的事物。

  • 将语义应用于内容;

  • 时刻考虑可访问性;

  • 操心网站的性能。优化一切。精简、重用、回收。

对我来说,光是做到第一点就好像是拿下一个本科学位了。总体而言,所有这些工作当然都称得上是一门学问。

这个列表可能有点抽象,所以我们拿一些真实的内容来举例说明。如果下面这个网站是我们当前的项目,我们该怎么办呢?

前端开发者正在被迫成为全栈开发人员

我们的大脑和指尖 化作了脱缰的野马!

  • 用 CSS 网格构建布局吧。

  • 这些是什么字体?我们需要完整加载它们吗,还是分成几个组呢?它们加载时会发生什么事情?这种布局感觉很容易受到字体移位的困扰啊。

  • 这里有一些重复的模式。我们可能应该做一个卡片设计模式。每个网站都需要一个很好的卡片模式。

  • 配色方案很棒嘛。这些颜色在数学上有关联吗?我们应该创建变量分别表示它们吗?或者是不是可以根据需要更改单个色调?我们要在 CSS 中使用自定义属性吗?不过颜色就是颜色,就为了点颜色我们可能并不需要它们的级联功能。我们应该只用 Sass 变量吗?我们是不是要用一个 CSS 预处理器?

  • 这里的源顺序很麻烦。我们需要打理好内容,让用屏幕阅读器的用户看着也能顺眼。我们应该开会讨论内容的顺序,光是在 CSS 网格周围排来排去是不够的。

  • 上面的照片拍得很美。但是其中一些和站点的背景色不搭……这里我们可以不用透明的 PNG 吗?那种文件都太大了。有什么下一代格式能拿来用用吗?还是我们应该试着将 JPG 的背景和网站的背景无缝对接起来。谁该负责给这些照片写 alt 文本呢?

  • 这里用了一些图标。是内联 SVG 对吗?当然是某种 SVG,不是图标字体吧?我们应该建立一个完整的图标系统吗?我想这应该取决于我们是不是要扩展它的使用范围。不过我们有没有一套构建系统呢?

  • 这个项目的整体前端方案是什么样子的?我可以用标准的 HTML、CSS 和 JavaScript 编写代码吗?好吧,这样应该没问题,但是团队的期望呢?客户的期望呢?它是否属于某些使用 React 的生态系统,所以它也得用 React?还是说它应该是 Vue 或 Svelte,或其他什么东西?项目是否涉及到 CMS 呢?

  • 我很高兴设计师考虑的不只是“桌面”和“移动”这两种尺寸,还考虑了介于两者之间的尺寸。这类中间态总是会很麻烦的。但是这里没有交互信息。光标移到搜索框的时候我们该怎么办?轻拍那个汉堡包会显示什么?我们是在这里进行页面级切换吗?

这种问题没个头。至少根据 我的经验 以及 与同行的交流 得出的结论,前端开发人员就是这么思考问题的。

这其中许多事情一直以来都是我们的工作。我们一直在自己构建的每个网站项目中询问并回答这些问题。每个站点上都有不同的挑战,这些挑战很棒,而且可以让这项工作乐趣满满,但是重复的问题也是有很多的。

再来看看本文的标题。

多年来,我们一直在做很多类似的事情,但是我们正在开始期待一大堆新东西,尤其是当我们谈论使用现代 JavaScript 框架构建网站的时候。所有现代框架,尽管对各种事物有那么多不同的观点,却都在一项关键的问题上取得了共识:一切事物都是 组件。你可以根据需要将组件嵌套在一起。甚至原生 JavaScript 也在向着自己的组件模型,Web Components 发展。

前端开发者正在被迫成为全栈开发人员

喜欢 这种 组件 概念。它使你和你的团队可以构建出对你们和你们构建的内容 最有意义 的抽象。

你的 Card 组件可以完成你需要卡片做的所有事情。你的 Form 组件会按照你的网站对表单的需求来实现表单。但这对像我这样的老开发人员来说是个新概念。JavaScript 中的组件获得了成功,这种成功是组件在服务端从未实现过的。我曾经手过许多 WordPress 网站项目,其中我最多也就是将模板分解为一些 include() 语句。我参与一个 Ruby on Rails 网站项目时,在一些部分中使用了一些局部变量。这些东西都可以用来构建可重用的部分,但是与 JavaScript 框架今天为我们提供的强大组件模型相去甚远。

所有这些自定义的组件创建工作,使我成为了以前从未尝试过的网站级架构师。这里有一个例子。当然,我有一个 Button 组件,还有一个 Icon 组件。我将在 Card 组件中使用它们。我的 Card 组件位于 Grid 组件中,后者会将它们布局并分页。整个页面实际上都是由各种组件构建的。Header 组件有一个 SearchBar 组件和一个 UserMenu 组件。Sidebar 组件有一个 Navigation 组件和一个 Ad 组件。假设我完全使用 JavaScript 构建前端的话,整个页面就只是各种组件的一种特定组合方式,组件可能会基于 URL。因此现在我自己来处理 URL,本质上我就是 整个网站的架构师。

就像我前面说的,这可代表的是一大堆新责任。

负责显示内容的组件几乎肯定不会在自己里面硬编码什么数据。它们被构建为模板。它们被构建为接收数据,并基于接收到的数据来构造自己。在过去,当我们制作这种模板时,数据可能已经到达了我们正在处理的页面上。在采用 JavaScript 的应用中,这些数据更有可能由 JavaScript 来获取。也许我会在组件渲染时 fetch 它。我现在正在使用的技术栈中,前端在 React 里,API 在 GraphQL 内,我们使用 Apollo Client 来处理数据。我们在 React 组件中使用一个特殊的“hook”来运行查询以获取所需的数据,并在需要更改数据时使用另一个特殊的 hook。猜猜那是谁做的?是否还有其他专门负责这个数据层的开发人员?不,这些都已经成为前端开发人员的工作领域了。

说到数据,网站经常需要处理的所有其他数据并非来自数据库或 API。这些数据都是真正只和当前网站相关联的。

  • 现在哪个选项卡处于活动状态?

  • 这个模式对话框是打开还是关闭状态的?

  • 这个折叠面板的哪一栏被展开了?

  • 这个消息栏处于错误状态还是警告状态?

  • 你分了多少页?

  • 用户向下滚动了多远的页面?

前端开发人员已经处理这种状态很长时间了,但正是这种状态才让我们陷入了困境。可以使用一个简单的修饰符类(如 <div class="modal is-open"> )打开一个模态对话框,并使用.classList.toggle(".is-open") 轻松切换这个类。但这是纯粹的视觉处理部分。页面上的其他内容如何知道这个模态是打开还是关闭的?它询问 DOM 吗?是的,在过去的许多 jQuery 风格的应用中它都会询问的。从某种意义上说,DOM 成为了我们网站的“真相来源”。这种架构产生了各种各样的问题,可能是一个简单的命名更改以奇怪的方式破坏了什么功能,也可能是难以理解的应用程序逻辑给错误修复带来了重重障碍,诸如此类。


前端开发人员都会这么想:我们是不是应该用更深思熟虑的方式来处理状态呢?于是状态管理这一概念兴起了。JavaScript 框架本身就内置了这个概念,而第三方库已经为它铺平了道路,还在继续向前推进。这是责任膨胀的另一个例子。谁负责状态管理架构?谁来执行和实现它?答案不是别人,正是前端开发人员。

待办事项中的责任在不断增加,此外还有把这些责任拼接在一起的工作。在单个组件级别可以处理多少这种状态,而在更高级别又需要处理多少?在单个组件级别可以获取多少数据,从上层又应该下放多少?设计的工作也掺杂进来了。这个组件的样式中有多少应该固定在自己的范围内,还有多少应该来自更全局的样式?

难怪设计系统在最近几年开始流行了。反正我们都在 构建组件,因此系统地考虑它们是很 自然的选择。

我们再来看一下我们的设计:

又涌进了一大堆新的念头!

  • 假设我们使用的是一个 JavaScript 框架,那么应该选择哪个?为什么?

  • 就算我们使用了 JavaScript 框架来构建,也可以静态渲染这个网站吗?还是用服务端渲染呢?

  • 这些食谱从哪里来?我们可以使用 GraphQL API 吗,这样我们就可以在需要时请求我们所要的东西?

  • 也许我们应该选择一个带有 API 的 CMS,用它简化我们想要的前端构建?也许是无头的 CMS?

  • 我们的路由应该是什么样的?我们选择的框架对这样的事情是 opinionated 还是 unopinionated 的呢?

  • 我们需要哪些组件?Card、Icon、SearchForm、SiteMenu、Img……我们可以将它们搭成支架吗?我们是否应该在基本框架之上从某种设计框架入手?

  • 我们可能需要什么样的客户状态?当前搜索词、当前选项卡、汉堡包是否打开,起码这些该有吧。

  • 这个站点是否有登录系统?登录的用户看到的内容会有什么不同吗?

  • 我们是否可以利用什么第三方组件?

  • 也许我们可以找到一些漂亮的图像组件,负责执行模糊加载和延迟加载之类的花哨功能呢。

在我们以前需要做的所有事情的基础上,如今,上面的这些都归到前端开发人员的领域里面了。设计、语义、可访问性、性能……这一切工作并没有消失。你仍然需要精通 HTML、CSS、JavaScript 以及浏览器的工作机制。成为前端开发人员需要熟悉一大堆在不断发展之中的技能。这是互联网发展壮大的自然结果。使用 Web 的人越来越多,互联网访问量也在不断增长。互联网经济日趋繁荣。浏览器的功能在不断扩张。对互联网可能性的期望也在不断膨胀。在这个世界,没有多少东西是在收缩的。

我们已经到了大多数前端开发人员都无法了解整个责任栈的地步。有许多开发人员仍然擅长自己的本职工作,他们专注于设计,并且精于编写具有创造力和良好实现的 HTML 和 CSS。然而对这类人才的需求在日益减少。

有专注于系统的开发人员,甚至有专门的代理公司,帮助其他公司构建和实现设计系统。有些专注数据的开发人员热衷于让数据流遍整个网站,与业务逻辑深度交汇。尽管所有这些人的名片上都可能有“前端开发人员”的称号,但他们的职责,甚至人们对他们工作的期望可能都会大不相同。这些都不是问题,我们会及时找到谈论所有这一切的方式的。

实际上在过去的十年中,我们构建网站的方式发生了很大变化。我对 Web 开发的早期认识来自于 WordPress。WordPress 需要一个 Web 服务器来运行,它用 PHP 编写,并将其数据存储在一个 MySQL 数据库中。尽管 WordPress 在不断发展,但所有这些仍然没变。我们用 LAMP 这个缩写来指代这个技术栈:Linux、Apache、MySQL 和 PHP。请注意,实际上整个栈中的所有内容都是由后端技术组成的。作为前端开发人员,关于 LAMP 的一切都与我无关。

但是从那以后出现了其他技术栈。流行的一个技术栈是 MEAN(Mongo、Express、Angular 和 Node)。前端技术的内容是不是变多了?Angular 是一个 JavaScript 框架,因此随着这个技术栈的普及,前端也成为了这个栈中愈加重要的部分。Node 和 Express 也都是 JavaScript,尽管它们是服务端的变体。

Node 的存在是这个故事的一个重要组成部分。Node 不是像 JavaScript,它 其实就是 JavaScript。它让已经精通 JavaScript 的前端开发人员能够轻松处理 服务端工作。

“无服务器”是一个更为现代的技术流行语,它的主要内涵是在云服务器上运行少量代码。通常,这些少量代码位于 Node 中,由 JavaScript 开发人员编写。如今,专注于 JavaScript 的前端开发人员可能正在编写自己的无服务器函数,并且实质上成为了自己的后端开发人员。他们会认为自己是全栈开发人员,他们是对的。

Shawn Wang 今年创造了一个新的技术栈术语:STAR,也就是 Design System、TypeScript、Apollo 和 React。我觉得这个术语太震撼了,不只是因为我有点喜欢这个技术栈,而且是因为这种技术栈完全使用前端技术为网站提供动力,这是一场巨变。

如果本文让你感到有些焦虑,我深表歉意。如果你觉得自己学不动了,其实 你不是一个人。

实际上,我接触过的所有前端开发人员都没有对构建网站的整个世界感到完全满意。每个人都有薄弱的地方或不擅长的整个领域。你不仅可以专精,而且成为某个领域的专家是一个很好的主意。我认为无论你是否这么打算,都可以在某种程度上成为一个领域的专家。如果你有幸可以做规划,请选择自己喜欢的东西去投入。你会做的很好。

生活中唯一不变的是变化。——Heraclitus,Motivational Poster,Chris Coyier

延伸阅读

https://css-tricks.com/the-widening-responsibility-for-front-end-developers/