*“我们”指的是前端开发人员
这是我在2019年Jamstack Conf London的演讲稿的文字版,我专门为参会者整理的。因为,在我登上前往伦敦的航班的前一天,我骑山地自行车摔倒了,两条胳膊都骨折了。我感到很遗憾,无法进行演讲,所以我既录制了演讲,也整理了这份文字稿。我把它放到这里是因为我喜欢将我的大部分写作内容集中在一个地方,并利用WordPress Gutenberg玩玩。
👋 嗨!我整个职业生涯都将自己定位为**前端开发人员**,并努力帮助其他人变得更擅长此领域。
而且我的胳膊已经累坏了

我运营着网站 CSS-Tricks (最近迎来了它的 12岁生日),这是一个关于网站建设的资源网站。
我还与人共同创立了网站 CodePen,这是一个关于使用前端技术构建事物的社交编码平台。
我还与人共同主持了一个名为 ShopTalk Show 的播客,现在已经播出了近400期。
我确信多年来我和成千上万的其他开发人员交流过,这帮助我了解了这个行业以及网站建设所需要的工作范围。
什么是前端开发人员?
✅ 这是一份工作,也是一个常见的职位名称。
这一点很重要,因为它不仅仅是语义。这是一份人们被雇用去做,并在工作中担任的职位。没有比金钱更私人的东西了。
我们如何定义这份工作以及对它的期望是**个人**的。
看看任何包含科技类工作的招聘网站,你都会看到关于**前端开发人员**的招聘信息。
什么是前端开发人员?
✅ 它直接与浏览器、设备和用户打交道。
每个在网站上工作的人可能整天都打开着浏览器,但前端开发人员**生活**在里面。他们打开了DevTools。他们打开了多个浏览器,并在不同版本和平台上进行测试。
至关重要的是,他们关心与这些浏览器和辅助技术交互的用户。

Mina Markham 解释了前端开发人员在高层次上的定义

与后端开发人员有所区别。并不是说后端开发人员不关心用户,而是责任被委派了。
Monica Dinculescu 说得很好

浏览器是前端开发工作核心。无论你在做什么,如果你的关注点是最终如何在浏览器中显示和运行,那就是前端开发。

这项工作比人们给它的评价要难。
什么是前端开发人员?
✅ 涉及大量工具,但最终归结为HTML、CSS和JavaScript。
这些是浏览器使用的语言。当然,还有SVG、PNG和其他一些东西,但你知道我的意思。
无论你使用什么其他工具,最终都取决于什么被交付给浏览器,而前端开发人员对此负责。

并非所有前端开发人员都对所有语言都同样精通。事实上,有很多开发人员几乎不写任何JavaScript,但他们仍然是非常成功的

我的文章 The Great Divide 深入探讨了那些深入研究JavaScript的前端开发人员和那些没有深入研究JavaScript的前端开发人员之间的分歧。
它不仅仅是我的想法,还收集了来自许多其他感受到这种分歧的人的引言。

Brad Frost 创造了“前端的前端”和“前端的后端”这两个术语,用来描述另一种分歧。他指出,这并不是弱点,而是将这些不同的人聚集在一起的优势。
在 Google,这种分歧得到了认可,并通过职位名称进行了区分。此外,这两个职业阶梯 薪资相同。


毫无疑问,特别是在2015年左右,JavaScript 作为一种语言蓬勃发展。



(如果你需要放大这些内容,请使用DevTools或其他工具。来吧,你们都是前端开发人员,对吧?)

我们的工作已经非常迷人了!所以我们都处理浏览器、用户和设备。这是核心。但我们每个人都知道不同的东西,并真正将这些知识应用到工作中。
我们中有些人是设计师。我们中有些人是摄影师。我们中有些人非常了解法律。我们中有些人对性能很感兴趣。我们中有些人专注于无障碍性。我们中有些人拥抱社交媒体。
比喻地说,你可以将我们映射成这棵树。

这个比喻可能并不完全适用,但这种分歧看起来有点像这样。我们仍然有一些共同的基础,我们仍然分支出去,知道很多不同的东西,但其中一方高度专注于JavaScript和“前端的后端”类型的工作,而另一方则没有。

由于这次演讲是关于前端开发人员开始做更多全栈工作,并且这种角色越来越广,我们假设我们讨论的是走上更重 JavaScript 道路的前端开发人员。
构建网站需要做很多事情,这些事情已经开始**跨越栈**了。
后端 → JavaScript
也就是说,从更偏向后端和朋友的技能组合转变为更偏向前端和朋友的技能组合。
组件驱动设计与开发
感谢, 奥巴马 JavaScript。

在我看来,非 JavaScript 服务器端渲染项目从未真正拥抱组件。(有一些例子,不要@我,但我的意思是跨越巨大的 PHP CMS 景观、Ruby on Rails 和大型玩家)。你曾经有模板和包含文件,但它们与真正的组件驱动开发相比相形见绌。
有趣的是,虽然各种基于 JavaScript 的框架在很多事情上都意见不一致,但有一件事他们都同意,那就是组件的概念。即使是原生 Web 组件……这个名称就很明确。

让我们快速看一下 CodePen,它现在主要是一个 React 驱动的网站。

即使是这个小小的 SVG 图标?它也是一个组件。我们称之为 <SVGIcon />
组件,因为它很好地抽象了对我们有用的几件事。

将图标与数字配对是另一个组件,因为它是一种重复模式,可能还具有额外的责任,例如被点击。

整个 MetaItem 组件行可能会成为一个组件,以及其他 Item 显示方面的组件。

因此,当然整个 Item 本身也会成为一个组件。
这些是我们构建 UI 所需的视觉和功能抽象。它下面有语义化的 HTML,但抽象是我们自己设计的构建块。

越来越大的区域变成了组件。在这种情况下,网格化的 Item 成为一个组件是有道理的,这样它就可以处理布局和分页等内容。

没错!组件不仅可以成为前端开发人员用于构建 UI 的智能构建块抽象,而且设计师也已经在很大程度上以这种方式工作了。Figma、Sketch 和 Adobe XD 等工具宣传“符号”,这在精神上是相连的。
我发现其他开发人员会说,**“哇,组件,我懂了”。**
网站级架构 / 路由
后端 → JavaScript

处理 URL 和整体网站结构曾经感觉主要是后端的事情。如今,“路由”正越来越多地成为前端的关注点。
<Suspense fallback={<Spinner />}>
<Route
exact
path={['/', '/picked-pens']}
component={anon ? AnonHomepage : Homepage}
/>
<Route path={['/topics', '/topic']} component={Topics} />
<Route path={['/challenges']} component={Challenges} />
<Route path="/instagram" component={Instagram} />
<Route path="/dashboard" component={Dashboard} />
<Route
path={['/profile_new/:username', '/profile_new/team/:teamname']}
component={Profile}
/>
</Suspense>

回顾 CodePen 的 UI,组件并没有停止在网格处。实际上,一切都变成了组件。选项卡、标题、按钮……

……表单、菜单、边栏……

最终,整个页面都变成了组件。

一旦整个页面都是组件,你实际上做的就是将 URL 变成了组件。
现在 URL 是一个组件,所有的 URL 都是组件,你控制着整个网站。


从某种意义上说,你成为了整个网站的架构师。

这……很多。想想你作为前端开发人员已经需要做的事情。所有这些都没有消失。你现在只是对更多的事情负责了。难怪前端开发人员越来越感到自己是全栈开发人员。
状态管理 + 获取和修改数据
后端 → JavaScript

前端开发人员另一个负责的领域是状态管理。现在状态管理是大多数 JavaScript 框架的核心,它是一个非常棒的概念,消除了过去许多前端代码混乱的问题。
但状态通常是从获取数据填充的,这现在也成了我们的责任。
更复杂的是,在必要时修改这些数据,并在需要时将数据发送回服务器。

GraphQL 为其中一些问题提供了一个很棒的解决方案。GraphQL 是许多事物,对于不同的人意味着不同的事情。但对我来说,它是关于赋能的。
有了强大的 GraphQL 端点,以及像 Apollo 这样的工具在我的 JavaScript 框架中为我提供支持,我可以作为前端开发人员,获取构建 UI 所需的任何数据。
import gql from "graphql-tag";
import { Query } from "react-apollo";
const GET_DOGS = gql`
{
dogs {
id
breed
}
}
`;
const Dogs = () => (
<Query query={GET_DOGS}>
{({ loading, error, data }) => {
if (loading) return `Loading...`;
if (error) return `Error`;
return (
{data.dogs.map(dog => (
<div key={dog.id}>
{dog.breed}
</div>
))}
);
}}
</Query>
);
请注意,我不仅可以获取所有自己的数据,还可以管理组件的异步性。我应该立即显示一个骨架吗?一个加载动画?我应该延迟渲染直到数据准备好?如果超时或出现其他错误会发生什么?

我不但可以获取数据,而且还需要我更新这些数据并以 mutations 的形式通过 GraphQL 发送回服务器。
mport gql from "graphql-tag";
import { Mutation } from "react-apollo";
const ADD_TODO = gql`
mutation AddTodo($type: String!) {
addTodo(type: $type) {
id
type
}
}
`;
const AddTodo = () => {
let input;
return (
<Mutation mutation={ADD_TODO}>
{(addTodo, { data }) => (
<div>
<form
onSubmit={e => {
e.preventDefault();
addTodo({ variables: { type: input.value } });
input.value = "";
}}
>
<input
ref={node => {
input = node;
}}
/>
<button type="submit">Add Todo</button>
</form>
</div>
)}
</Mutation>
);
};

Mutations 并没有比查询复杂太多,但作为前端开发人员,这都是我需要处理的工作。过去,这些工作几乎肯定属于后端开发的领域。
请注意,上面的例子是 GraphQL 的说明,但通过 在 React 中实现的 Apollo Client 完成。

既然我们谈到了组件、查询和 mutations,让我们再加一个东西:样式。
前端开发人员一直负责样式,但在组件在其他方面都是自包含的这种环境中,将样式信息也一起定位开始变得有意义。
在这里,我们使用 CSS modules 将样式范围限定到特定组件。我们仍然可以并且确实拥有全局样式,我们甚至继续使用 Sass 进行有用的全局抽象。
.root {
display: grid;
}
import styles from './styles.scss';
<NewsItems className={styles.root} />

这种组件化和共同定位的结果是,我们有了包含从逻辑到视图模板、查询和 mutations,再到样式的所有内容的精美小文件夹。
这很方便,但也带来了一些有趣的副作用。例如,JavaScript 包可能包含它们需要的东西(代码拆分)。样式不会 膨胀 ,因为当组件不再使用时,它们的样式也会随之消失。更不用说命名变得不再那么令人头疼,因为命名是文件级别的。
GraphQL 的纪录片很有趣。我喜欢 Kyle Mathews 在(大约 20:24)所说的,React 消除了前端开发的一整类问题,GraphQL 也是如此。
每个项目都适用吗?当然不是。但对于我们经常被要求构建和维护的那些比较大、比较复杂的应用程序来说,答案是肯定的。
前端开发人员已经承担了非常繁重的责任
- 实现设计
- 将设计融入系统
- 确保可访问性
- 关注性能
- 跨浏览器测试
- 跨设备测试
- 关注 UX
哦,一大堆新的责任来了
- 组件驱动设计,设计我们自己的抽象
- 站点级架构
- 路由
- 获取我们自己的数据
- 与 API 交互
- 修改数据
- 状态管理

责任的堆栈越来越高。
这并不是说我们所有人都需要了解所有这些内容,并且能够完美地完成所有这些工作,而是说这些任务都属于前端 Web 开发的领域。

Peggy Rayzis 谈到了“前端开发人员”这个词的含义变得多么广泛,以及我们很可能正在走向专业化。
再次,许多任务已经从曾经属于后端工作的领域转移到了 JavaScript 领域。
让我们画一个光谱,看看它随着时间的推移是如何演变的。


LAMP 代表 Linux、Apache、MySQL 和 PHP。这是一个非常古老的堆栈,但仍然非常流行。很多 CMS 都是基于它运行的。LAMP 是人们用来谈论这个堆栈的方式。
如果我是一个在这个堆栈中工作的前端开发人员,我会处于光谱的另一端,很少接触到这个堆栈所指的技术。

MEAN 是另一个堆栈,代表 MongoDB、Express、Angular 和 Node。请注意,操作系统不再被提及。
值得注意的是,Angular 是一个前端框架,因此这个堆栈开始包含了前端框架。如果我是一个前端开发人员,我的工作就会与这个堆栈有重叠。

无服务器将堆栈进一步向右移动。我们甚至不再关心代码运行在哪些服务器上,它只是使用和创建 API 的服务器端代码。
如果我是一个在这个环境中工作的开发人员,我的工作就会有重叠,因为我甚至可能会使用我的 JavaScript 技能来编写这些无服务器函数并消化 API。

Shawn Wang 将 设计系统、TypeScript、Apollo GraphQL 和 React 称为 STAR 应用程序。
这就像......全部都是前端的东西。
在我看来,我们用来谈论为网站提供动力的重要技术的方式,越来越偏向于前端开发人员的光谱。
让我们快速了解一下 无服务器 如何扩展我们的前端能力。

我创建了一个关于无服务器的网站 ,因为我认为它很酷,而且意义重大。

这是一个利用无服务器技术完成所需工作的 JAMstack 网站的完美例子。
---
title: JAMstack_conf_ldn
url: 'https://jamstackconf.com/london/'
cocUrl: 'https://jamstackconf.com/london/code-of-conduct'
date: 2019-07-09T08:00:00.000Z
endDate: 2019-07-10T16:00:00.000Z
location: 'London, England'
byline: 'Learn how to design, develop, and deploy fast, modern web projects that run without web servers.'
---
Following the inaugural [JAMstack_conf in San Francisco](https://2018.jamstackconf.com/) in 2018, we're now also bringing an edition to London where we'll have talks about how to design, develop, and deploy fast, modern web projects that run without web servers.
每个会议都是一个 Markdown 文件,包含 Front Matter 来描述与会议相关的元数据,例如城市和日期。
我并没有刻意想要避免使用数据库,但这个网站似乎很适合使用 静态网站生成器 ,并且数据需求非常简单,因此纯 Markdown 文件是自然的选择。

这个网站是 GitHub 上的公共仓库。这可能看起来很明显,但我觉得这里意义重大。
这意味着
- 整个网站都在这个仓库中。要运行它,你只需要把它拉下来,然后运行一个命令。
- 无需理会登录、权限或凭据。
- 它向公众开放了网站的 内容,以及设计和功能。这对我们帮助很大。


有了 Netlify CMS,我就可以在网站本身获得一个编辑内容的界面。一旦设置好,就不需要代码编辑或 Git 了。
我甚至不需要 Netlify 就能使用 Netlify CMS,但 Netlify Identity 让身份验证部分变得容易了无数倍。
看看会议网站的这个功能。对于每个会议,你都可以点击一个按钮,显示一个电子邮件输入表单。输入电子邮件并提交,网站会发送一封包含会议详细信息的电子邮件。
这是一件后端的事情。你不能只用客户端技术来发送电子邮件。你可以与发送电子邮件的 API 进行通信,但即使这样也需要通过后端代码来保存 API 密钥。
const SparkPost = require('sparkpost');
const client = new SparkPost(process.env.SPARKPOST);
exports.handler = function(event, context, callback) {
client.transmissions
.send({
content: {
from: '[email protected]',
subject: `Conference!`,
html: `
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>`
},
recipients: [{ address: email }]
})
.then(data => {
callback(null, {
statusCode: 200,
body: `Message sent!`
});
});
};
我将使用 Sparkpost 来发送电子邮件。它们提供 API 来发送电子邮件(这是它们的全部目的)。它们还提供一个 Node.js 库,使操作变得非常容易。最终只需要几行代码。
而这些代码?是 JavaScript。我是一个 JavaScript 开发人员。这并不困难。
我如何*运行*它?
这就是无服务器的精髓:云函数。我指的是AWS Lambda、Azure Functions、Google Cloud Functions等等。
Netlify 版本,本质上是 AWS Lamba,叫做Netlify Functions。这简直太容易了。你只需将函数放到 `/functions/` 文件夹中,然后通过访问相对 URL 来运行它们。
让我们带着这些现代技术,重新审视一下技术谱。
能够像这样从头到尾构建整个网站,感觉非常强大。
我真的不需要关心操作系统和服务器了。整个产品可以构建而无需关心这些。

我可能也不需要过多地关心数据库。并不是数据库不重要,而是我处理数据很可能通过 API 完成。也许是一个无头 CMS(例如Contentful)。也许是一个专门通过 API 工作(例如FaunaDB)或页面库(例如Firestore)的数据存储工具。

所以现在我剩下一个技术谱,我可以处理它的所有部分。
所以我已经感觉自己很全栈了。但是,你把所有这些都加起来,再加上
- 我知道 Git
- 我可以编写测试
- 我进行设计
- 我知道构建流程
- 我关心性能
- 我可以使网站无障碍
- 我可以建立一个基本的部署管道
你真是
太对了
我是一个全栈
开发者!
🎉但是

这里的技能堆栈越来越大了。
你可以完全专注于某个领域。你可能也会这样做。这是好事。
“真正的”独角兽,那些在网站构建的整个技术谱中每项任务都非常出色的人:和真正的独角兽一样稀有。
我也不是想暗示后端开发人员正在变得过时。事实上,由于网站构建变得如此复杂,他们比以往任何时候都更重要。
现在,我可以打开 CodePen 问题跟踪器,看到 89 个我无法独自解决的问题。我需要后端开发人员的帮助来深入研究并解决它们。如果我想的话,我可以认为自己是一个全栈,但我清楚,后端是我需要改进的领域。
事情往往会变得更像这样。
或者在我的例子中,更像这样

这并不是为了嘲笑任何人。我的意思是,也许有一点,但这画了一个很好的比喻,非常适合这次演讲。我们就是整匹马!整条龙!但我们有粗糙的边缘。所以呢。
看到围绕我们工作的技术发展到我们能够*触及*整个项目的程度,真是太酷了。当我们觉得网络技术的复杂性正在提高入门门槛时,值得我们关注。这种情况有时会发生,而且并不理想。但是,当网络技术变得足够简单,人们可以独立地从头到尾构建东西时,也值得欢呼。这很酷。
当我们都高效且出色地工作时,让我们记住,**做好工作是每个人的责任。**
- 良好的用户体验是每个人的责任
- 良好的性能是每个人的责任
- 良好的安全性是每个人的责任
- 良好的无障碍性是每个人的责任
- 对使用你网站的人负起责任,是每个人的责任
即使你没有编写直接影响这些事物的代码,你也要关心它们,并努力让它们得到妥善处理。

CodePen PRO(用金钱支持你当地的手工制作软件产品)
感谢你写了这篇文章。了解 SparkPost 使它变得更加棒!
我的天。一针见血,Chris。这帮助澄清了我自己作为面向 js 的开发者在过去六年中的演变。谢谢。
我不同意前端开发者关心用户而后端开发者不关心用户的观点,这只是责任分配的方式,但如果你让每个人都设计一个简洁易用的界面,十次中有九次你会得到一个来自后端开发者的更好的设计,因为他们的设计只专注于完成工作,没有花哨的干扰,没有“营销最佳实践”,他们只会做一个他们自己会很乐意使用的界面,而不是一个他们整天都会咒骂的界面,而这正是很多前端开发者做出来的东西。显然,很多时候这是客户的意愿,但作为一名专业人士,你应该告诉他们这是一个坏主意,如果他们坚持,你应该拒绝发布这样的“怪物”。无论它是移动运营商的网站还是大型社交平台的 Web 应用程序,每当我不得不处理它们时,我的血都会沸腾。
十次中有九次听起来要么你的团队有一群全栈独角兽,要么就是经验不足的设计师,他们经常会将形式置于功能之上。
根据我的经验,比例是五五开。有些后端开发人员对约定俗成的东西有所了解,而有些则会随心所欲地添加按钮等等,然后期待 QA 或我们来收拾残局。例如,前几天我不得不告诉一个后端开发人员,如果他可以将三个主操作按钮减少到两个按钮,并在上面添加一个复选框作为修饰符(两个按钮做同样的事情,一个按钮做的事情稍微多一点,但他甚至无法用那里按钮的有限空间来传达这一点),那么他就不需要在模态窗口中使用三个主操作按钮。他负责处理数据库、API 等,很少参与 UI 构建,因此可以理解他对此并不了解。
我很喜欢读这篇文章。
作为一个前端开发者,我完全能理解你的很多观点。
我认为“全栈开发者”这个词在行业中非常令人困惑。
我知道很多人可以处理整个技术栈并把东西拼凑起来,但说实话,输出的质量并不像你期望的那么好。(例如:糟糕的 HTML 或 CSS,数据库层面的安全问题,或者整个系统的架构糟糕,难以维护/扩展)
无论如何,他们还是称自己为全栈开发者。
我相信市场对全栈开发人员的需求在一定程度上是造成这种情况的原因。
我通常鼓励初级开发者先探索并专注于某一方面,然后再追求全栈。
如果前端是你的激情,那么在追求全栈之前先把基础打牢。正如这篇文章提到的,前端有很多技术/概念需要掌握。
一如既往的精彩帖子,作为一个(会编码的)设计师,意识到前端领域有多少开发工作可以完成,有点令人害怕,但也让人感到兴奋和鼓舞。
简直说出了大多数资深人士的心声……太棒了!
我觉得现在行业里存在两种负面情绪
那些自以为是的“大祭司”全栈大师,他们从 5-10 年前就开始编码,并宣称如果你不是“整条龙”(借用你上一篇文章中的一张图),你就什么都不是;
对职位名称和含义的执着——例如,开发人员、工程师、程序员、编码员,在某些情况下意思差不多,而在另一些情况下则完全不同,所以为什么要陷入将职位名称严格地划分为整齐类别的尝试中呢?现实中根本没有这样的东西,T 型专业人士有时可能会变成 W 型,仅仅因为他们同时喜欢很多事情。不同的公司对“前端开发人员”或“全栈工程师”或任何其他技术职位的具体含义有不同的职位描述,这取决于他们自己的环境和需求。
这种缺乏灵活性有时会向行业中注入有毒的负面情绪和许多判断,这很可惜。
这篇文章真的很棒。它提供了很多信息,并澄清了一些疑问。
这篇文章很好地概述了现代前端开发。感谢您花时间写下这篇内容。
哈哈,我来了。我在工作中是全栈开发人员。我创建了一个数据提供者,将其添加到某些控制器中,然后将 json 数据发送到前端,并使用浏览器中的 Typescript 对其进行处理。而且,说实话,在这方面,我都不是最好的。