作者 | Eric Bower
译者 | 弯月
出品 | CSDN(ID:CSDNnews)

在过去的 5 年里,我主要从事构建前端 Web 应用程序的工作。熟练掌握 JavaScript 生态系统可不是一件易事。这个生态系统不断变化,新工具层出不穷,而且还会影响我们构建 Web 应用程序的方式。

我们的技术栈中有很多用于构建生产级 Web 应用程序的工具。我不禁在想,我们是如何从 HTML 中嵌入的 JavaScript 发展到如今拥有构建流水线的?甚至连一行JavaScript 代码都没有写,就要先选择一系列的工具?

软件工程这个职业已经存在了几十年了。如今为了满足产品或服务的业务需求,我们构建了几十种现代编程语言、几千种工具和框架。在成千上万构建软件的人不断吸取前人经验教训后,为什么前端用到的技术依然这么多?为什么前端看起来如此混乱?从 left-pad 事件到工具链的更迭,前端开发几乎成为了软件开发中的“黑天鹅”。

我经常看到网上有些自认为称职的软件工程师对前端 Web 开发唯恐避之不及。为什么这么多专业工程师对前端开发不屑一顾?

而这些问题的答案就是我喜欢前端 Web 开发的原因。虽然 JavaScript 很差劲,但这也正是它吸引我的地方。我想通过本文与你一起探索 JavaScript 的生态系统,同时还想解释一下为什么我会如此喜欢前端开发。

黑天鹅

JavaScript 开发所面临的挑战不同于其他编程世界,其独特地位的主要驱动因素在于 JavaScript 代码需要下载到客户端浏览器上。例如,在服务器上运行的语言不需要将代码发送到客户端机器上,它们只响应浏览器发出的请求。所有处理都在服务器上运行。

传统的桌面应用程序只要求客户端下载一次运行应用程序的代码或可执行文件。而对于 Web 前端,每次都需要下载。这就导致 Web 前端有一个与其他开发完全不同的关键性要求:

Web 前端开发需要考虑总代码量。

一般从事其他开发的工作人员不太需要担心代码的大小,但这却成了我们的首要考虑因素。

这个要求有哪些副作用?

  • 小型库 优于 大型库。

  • 许多工具专注于减少代码量。

下面,我们来看看这两个副作用对整个生态系统的影响。

小型库优于大型库

由于代码量很重要,因此 JavaScript 库非常注重以最少的代码量交付最强大的功能集。每当我想到现代 JavaScript 库时,就会想起 Unix 哲学:只做一件事,并把它做好。

JavaScript 库只做必要的一件事,并把它做好。

这就导致 JavaScript 出现了一些极端的库:只有一行代码。

is-promise 是一种流行的单行 JavaScript 函数,它引入的回归问题导致大量应用程序和库出现了问题。

function isPromise(obj) {
  return (
    !!obj &&
    (typeof obj ==='object' || typeof obj === 'function') &&
    typeof obj.then ==='function'
  );
}

left-pad也是一个类似的例子,它是一个非常小的库,却导致全世界大量项目构建失败。
虽然听起来很不可思议,但是这种副作用确实来自前端 Web 开发的独特性。

许多工具专注于减少代码量

从代码压缩到 tree-shaking,JavaScript 生态系统有大量工具可以帮助我们减少通过网络下载的代码量。前端开发构建流水线需要花时间搞清楚应用程序中实际使用了哪些代码,以及如何压缩代码量。除了前端开发之外,我参加过的其他项目都不会如此关心代码量。

举个例子,一般 Python 项目都不必担心引入大规模依赖项的后果。numpy 是一个非常流行的 pypi 包,多用于数据科学和统计。将这个包添加到项目会导致总体的代码量增加约30MB。你能想象如果前端开发人员开发出如此规模的 JavaScript 包,哪怕比这个小很多,他们会受到怎样的苛责吗?

有时我们确实需要引入大型库,因为这些库可以节省大量的时间,而且对企业来说也具有成本效益。我们必须发挥创造力,而这样做就导致 JavaScript 生态系统中产生了数量惊人的工具。为了满足这一要求,这个生态系统不断地构建新工具。

唯一的语言

对于浏览器编程,我们所需的语言只有一种:JavaScript。虽然也有其他语言,但至少目前绝大多数人都会选择 JavaScript。

不知是好是坏,成千上万的开发人员都必须使用 JavaScript。

由于只有一种语言生态系统,因此需要投入大量的创造力和劳动来解决最棘手的问题。由于为需要满足各种业务的众多需求,所以这个生态系统在不断发展。如果前端能和后端一样拥有相同数量的流行编程语言,那么每个生态系统都不会有如此快速的更迭。

此外,我认为正是因为JavaScript 有许多缺点(任何一门语言都是如此),才有如此多人想出巧妙的解决方案来修补这些问题。

因为开发人员不得不使用JavaScript,所以他们不得不想出创造性的解决方案。

这种创造力催生了很多巧妙的解决方案。所以说,JavaScript 是最有活力和最有趣的编程生态系统之一。近年来,有些工具彻底改变了 JavaScript,特别是:

  • Typescript

  • Prettier

  • ESLint

  • React (view = f(state))

我认为 typescript 中的类型系统为开发更稳定的 Web 应用程序做出了很大的贡献。而且我还认为 typescript 的类型系统出色之处并不在于其设计,而是由于它的应用之广超过了我用过的任何其他类型系统。

Prettier的表现和 gofmt 不相上下,这本身就很有意义,因为 gofmt 是由 golang 语言设计者构建的。

ESLint是我见过的最好的 linter。其他语言中可能也有类似的 linter,但我还没有亲身经历过。

每次尝试另一种编程语言时,我都会想念这三款工具。从事过JavaScript 开发之后再接触 python 就会觉得工具怎么都这么落后。

最后,我认为 React 也是一个彻底改变了构建 UI 应用程序的库。如此之多的应用程序使用 electron 构建是有原因的,而且我认为不是因为人们不知道如何使用 Qt。人们不想使用 Qt 是有原因的,因为与 React 相比,Qt 使用起来更麻烦。对于 UI 开发来说,将视图视为状态的函数具有开创性。

JavaScript 有很多运行方式

JavaScript有一个规范:ECMAScript。该规范在不同的浏览器中的实现方式略有不同。自从 v8 因为其速度和服务器端实现(例如nodejs)主导浏览器市场以来,多年来不同 JavaScript 实现的数量一直在缓慢下降。

然而,JavaScript 的实现方式仍然不是完全一致,新功能的采用仍然非常缓慢。让用户更新浏览器是一项艰巨的任务,多年来这个问题一直困扰着前端开发人员。从 ECMAScript 的新功能到市场的全面采用往往需要长达数年的时间。这就成为了 JavaScript的另一个独特的约束。

这个问题有两个解决方案:

  • ECMAScript 引入的新功能需要向后兼容。

  • 创建工具,将代码从一种规范转换为另一种规范。

由于 ECMAScript 的设计师选择了新功能向后兼容(在大多数情况下),因此我们可以构建新工具,将代码从较晚的规范转换为较早的规范。这类工具称为转译器,例如 babel 可以将 ES6 代码转换为ES5。

有了这些转译器,开发人员就可以编写最新规范的代码,同时无需担心市场的采用。但我们也不得不在构建流水线中加入编译步骤,而这为各种工具打开了闸门。现代JavaScript 代码都是经过编译的,而且这种做法在短时间内不会改变。这不是增加了学习 JavaScript 的难度吗?没错,但好处也是巨大的。

总结

正是因为这么多技术人才被迫使用 JavaScript,正是因为 JavaScript 有完全独特的要求,我们才拥有了如今这个充满活力的生态系统。每一年,整个社区都会推出大量创新。然而,与此同时,这个生态系统也越来越成熟。React 可以说是有史以来最流行的 JavaScript 库之一,而它也已经诞生 7 年多了。如今所有新项目基本上都会考虑 Typescript。

构建现代化生产级的 Web 应用程序很困难,有时这些工具也会让开发人员眼花缭乱。有时,我也会厌倦重复实现同一个组件,处理屏幕上移动的一个个小像素,或者是实现应用程序中一些相似但略有不同的用户体验。然而,前端开发的乐趣也正在与此。每个新项目都有不同的体验。如果换成其他编程语言,相信今天也会遇到相同的限制。

每当想到前端开发人员面临的挑战,我就会感到很荣幸成为这个社区的一员。

  • 参考链接:https://erock.io/2021/03/27/my-love-letter-to-front-end-web-development.html

更多推荐

为什么专业工程师对前端开发不屑一顾?