41

为何现代Web开发如此复杂?-InfoQ

 4 years ago
source link: https://www.infoq.cn/article/YPEj-1CKSxkVG290iIY0
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

我是现代 Web 开发的忠实粉丝,我认为它称得上是一种“魔法”——但所有的魔法都有其优点和不足:

  • 如果你能熟练使用 Web 开发的一系列神奇工具(Babel、bundler、watcher 等!),就能打造出快速、强大而令人愉悦的开发流程;

  • 如果你不熟悉 Web 开发的这些神奇工具就会寸步难行;

  • 想要搞清楚这些魔法的工作机制往往是条不归路,除非有人引导你区分 Web 业内的术语、热点和过时信息。

最近,我常常需要向新手解释“现代 Web 开发流程”的内容,但是……

这很难解释!

哪怕是泛泛而谈都需要长篇大论才行。

千里之行始于足下,本文就是针对 Web 开发演变的一系列概括介绍的第一篇内容:静态网站到 Babel 的演变

最简单的网站:静态网站

故事要从“经典”的前端 Web 开发模式讲起,相信大家对这部分内容很熟悉了。

在经典的前端 Web 开发模式中,我们会直接修 HTML/CSS/JavaScript 文件。想要预览更改时,我们在本地浏览器中打开 HTML 文件,更改代码后刷新页面以更新内容。

这种开发流程如下所示:

  1. 在 Atom 这样的文本编辑器中编辑 HTML/CSS/JavaScript 文件。

  2. 在文本编辑器中保存文件。

  3. 在浏览器中打开并重新加载文件。

为何现代Web开发如此复杂?

编辑 JavaScript,保存文件,刷新页面以查看更新

然后当你想将网站发布到互联网时,只需将 HTML/CSS/JavaScript 文件上传到网上即可。

只要使用像 Netlify 这样的服务,把包含文件的文件夹拖上去即可将页面发布到 Web 端。

以下是一个简单的示例: https://sleepy-lichterman-6811cc.netlify.com/

简直太简单了!为什么我们还要让事情变得那么复杂呢?

如果你了解“经典”Web 开发流程的机制,你可能会问:这么简单的方法为什么我们要抛弃它?!为什么现代 Web 开发流程如此复杂?

简短的答案:好吧,也许我得给出两个简短的答案:

  • 你并不一定选择那么复杂的道路。“经典”的 Web 开发流程非常棒!并且足以满足你的需求!你根本用不着添加多余的,或者你看不懂的那些工具。

  • 但对于某些项目来说,更复杂的流程自有其好处。你添加到流程中的每项工具都是用来解决某种问题的。

为了理解现代 Web 开发的工具系统,我们必须理解 Web 开发面临的问题

在这段漫漫长路中我们将逐一解决这些问题,首先来看一个已经存在了几十年的 Web 开发老问题吧。

一个老问题:JavaScript 的局限性

直到今天,JavaScript 和一系列 Web API 都有很多局限(原因多种多样,这里就不细说了)。

举几个例子:

  • 没有 Promise/ 异步

  • 没有 Array.includes()

  • 笨拙的语法 / 缺失很多常用原语(没有 for-of、模板字面量、箭头函数语法、模板解包…

  • (Web API)有无数 DOM 操作根本没必要那么复杂(比如添加 / 删除类名、隐藏元素、选择元素、删除元素…)

浏览器只能执行 JavaScript,因此当限制是来自 JavaScript 语言本身时,你没法简单地换成别的语言来解决问题;你只能忍受这些局限。

小故事:JavaScript 和 Web API 之间的区别?

你可能已经注意到我在上面说的是“JavaScript 和 Web API”。这是两件不同的事情!

当你为网页编写 JavaScript 时,与网页本身交互的 API 调用都是 Web API(只是刚好用 JavaScript 编写而已),而不是 JavaScript 语言的一部分。

一些例子:

  • Web API:文档和文档上的方法;窗口和窗口上的方法;事件、XMLHttpRequest、获取,等等

  • JavaScript:函数、const/let/var、数组、Promise,等等。

比如说你正在写一个 Node.js 服务器,你会用 JavaScript 编写,意味着你可以使用 Promise 这种东西,但不能使用 document.querySelector(这样做也没有意义)。

一个古老的解决方案:jQuery 和它的小伙伴们

jQuery 早在 2006 年就诞生了:它是一个用来解决 JavaScript 和 Web API 中许多缺陷的库。

jQuery 中的 API 对常见 Web 任务助力颇大,如 DOM 操作、异步处理、处理跨浏览器差异和资源获取等。

基本上来说,虽然用旧的 JavaScript/ 旧的 Web-API 处理这些事情在技术上都是可行的,但它们非常烦人、无趣,而且往往很难编写——所以为了把 Web 开发者从编写头疼代码的负担中解放出来,你可以下载 jQuery 库并用它的精美 API 来处理 JSON 文件之类的任务。

一个新的解决方案:改进 JavaScript 本身

但是今天距离 2006 年已经很久了!

自 2006 年以来,JavaScript 和 Web API 得到了极大的改进。(jQuery 和很多人都贡献巨大!)

JavaScript 是一种不断发展的语言。与软件的更新类似,JavaScript 语言也会更新很多版本。

你可能听说过“ES6”一词。ES6 代表“ECMAScript 6”,指的是 ECMAScript 的第 6 次迭代。ECMAScript 只是 JavaScript 的另一种叫法,区别只是人们通常使用“ECMAScript”来指代规范,而使用“JavaScript”来指代人们编写的语言。

(顺便说一句,这又是一件让人头晕的事情:JavaScript 不是 ECMAScript 的实现;就像你不能把“HTML”称为“HTML”的实现一样,叫成“HTML 规范”也不行,都是错的!维基百科就写错了!JavaScript 和 ECMAScript 是一个东西。)

不管怎样,ES6(2015 年发布)是一次重大更新,因为它为 JavaScript 添加了很多非常好的语言功能,比如 const、模块和 Promise 等。(另外 ES8 引入了我最喜欢的语言功能,也就是异步。)

与此同时,自 2006 年以来 Web API 也得到了极大的改进,加入了 document.querySelector、fetch 以及 classList 和 hidden 之类的东西。

因此在 2019 年的今天,大多数情况下我们可以直接使用 JavaScript 和 Web API,无需 jQuery 之类的库了。

……但也有例外

一个长久以来的难题:跨浏览器支持

更新 JavaScript 语言时浏览器也要更新才能支持新的语言功能。(Web API 也是如此,但简单起见我们现在只谈 JavaScript。)

但以下步骤之间是有延迟的:

  1. 在 JavaScript 中定义语言功能。

  2. 浏览器实现全部功能并发布支持。

  3. 用户全部升级到最新版本的浏览器,通常通过自动更新 / 重新启动浏览器来完成(有时还做不到!)。

矛盾:我们应该用旧版 JavaScript 还是最新的 JavaScript 编写呢?两者都有利有弊

这给 JavaScript 开发人员带来了两难的处境:我们希望使用现代化的 JavaScript 语言功能,因为这些改进通常会让某些内容编写起来更容易。但我们也希望网站能够为所有用户服务,不管他们是什么时候重启浏览器更新版本的都应该看到同样的内容。

这种困境通常要由 Babel 来解决。

Babel 是一个 JavaScript 编译器,可以将 JavaScript 代码转换为…不同的 JavaScript 代码!具体来说,它能把用最新版 JavaScript 编写的 JavaScript 代码转换为被更多浏览器支持的旧版 JavaScript 等效代码。

为何现代Web开发如此复杂?

Web 开发人员将 Babel 整合到流程中,就可以使用最新的 JavaScript 功能编写代码,无需担心浏览器兼容性。

小故事:Babel 不包括 Web API

例如,如果你在 JavaScript 中使用 fetch,Babel 将不会提供兼容性支持(兼容支持也称为“polyfill”-ing),因为 fetch 是一个 Web API 而不是 JavaScript 本身的一部分。(他们正在重新考虑这个决定

因此你还需要一个独立的解决方案来 polyfilling Web API!之后的文章中我们会谈到这一点。

再来看流程:静态网站 +Babel

好的,所以现在我们已经知道为什么要用 Babel 了。那么使用 Babel 的 Web 开发流程是什么样的呢?

以下是最简单的 Babel 流程,人们通常不会用它。(因为像 Parcel 或 webpack 这样的包更方便,我们以后会提!)

安装 Babel

你可以按照这里的 CLI 说明操作,但它假设你了解 npm 的机制。他们建议你在本地安装 Babel 作为每个项目的 npm dev 依赖项,而不是在你的计算机上全局安装。

  1. 像普通的静态网页一样开发你的网站。
为何现代Web开发如此复杂?

示例:src 目录是你的 JavaScript 所在的位置

当你准备将网站发布到互联网时,不可能直接把写好的 JavaScript 文件上传到 Web 端,因为你一直都用的是所有浏览器都不支持的 JavaScript 功能。

你要做的事情是:

  1. 使用 Babel 编译 JavaScript,以获得与浏览器兼容的代码:
为何现代Web开发如此复杂?

这将在单独的文件夹中创建新的编译好的 JavaScript 文件:

示例:Babel 将生成第二个“script.js”,该脚本具有跨浏览器兼容的代码

2. 将编译好的 JavaScript 与 HTML 和 CSS 一起上传到互联网:

为何现代Web开发如此复杂?

编译好的 JS

为何现代Web开发如此复杂?

加上你的 CSS 和 HTML 文件

你的网站看起来 * 和动起来都和开发模式中的一样,但用户拿到的是 Babel 编译过的 JavaScript。

(但愿如此!有时调试和发布版本会有差异,但这些都是错误!)

停一下,谈谈开发与发布代码!

为何现代Web开发如此复杂?

请注意,我们现在将“开发”代码和“发布”代码区分开对待:

  • 开发代码:你在开发 Web 应用程序时编写的代码。

  • 发布代码:用户访问你的 Web 应用程序时要运行的代码。

我们有意区分这两者,因为:

  • 开发代码对开发人员有利,但对用户不利

  • 发布代码对用户有利,但对开发人员不利

在前端 Web 开发中,不是每个人都会用或者需要 Babel。

但下面的模式:

  • 编写不向用户显示的开发代码

  • 然后编译成另一个版本的发布代码显示给用户。

不仅很常见,而且在现代前端 Web 开发中经常会用到。

请注意,区分“调试”与“发布”构建是软件工程中的常用模式,并不是 Web 开发引入的新事物。但它特别适合前端 Web 开发,因为它太常见了,而且前端 Web 开发的调试 / 发布版本之间区别巨大。

下面是一个简短的前端技术列表,可以用来区分调试和发布版本:

  • npm 模块

  • 各种 CSS 预处理器

  • React/Vue/Angular/ 各种 Web 框架

之后的文章会反复提到这种模式,所以现在好好记下来!

英文原文: https://www.vrk.dev/2019/07/11/why-is-modern-web-development-so-complicated-a-long-yet-hasty-explanation-part-1/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK