我是现代 web 开发的忠实粉丝, 我认为它称得上是一种 "魔法"-- 但所有的魔法都有其优点和不足:
如果你能熟练使用 Web 开发的一系列神奇工具 (Babel,bundler,watcher 等!), 就能打造出快速, 强大而令人愉悦的开发流程;
如果你不熟悉 Web 开发的这些神奇工具就会寸步难行;
想要搞清楚这些魔法的工作机制往往是条不归路, 除非有人引导你区分 Web 业内的术语, 热点和过时信息.
最近, 我常常需要向新手解释 "现代 Web 开发流程" 的内容, 但是......
这很难解释!
哪怕是泛泛而谈都需要长篇大论才行.
千里之行始于足下, 本文就是针对 Web 开发演变的一系列概括介绍的第一篇内容: 静态网站到 Babel 的演变
最简单的网站: 静态网站
故事要从 "经典" 的前端 Web 开发模式讲起, 相信大家对这部分内容很熟悉了.
在经典的前端 Web 开发模式中, 我们会直接修 html/CSS/JavaScript 文件. 想要预览更改时, 我们在本地浏览器中打开 HTML 文件, 更改代码后刷新页面以更新内容.
开发流程
这种开发流程如下所示:
在 Atom 这样的文本编辑器中编辑 HTML/CSS/JavaScript 文件.
在文本编辑器中保存文件.
在浏览器中打开并重新加载文件.
编辑 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.)
但以下步骤之间是有延迟的:
在 JavaScript 中定义语言功能.
浏览器实现全部功能并发布支持.
用户全部升级到最新版本的浏览器, 通常通过自动更新 / 重新启动浏览器来完成 (有时还做不到!).
矛盾: 我们应该用旧版 JavaScript 还是最新的 JavaScript 编写呢? 两者都有利有弊
这给 JavaScript 开发人员带来了两难的处境: 我们希望使用现代化的 JavaScript 语言功能, 因为这些改进通常会让某些内容编写起来更容易. 但我们也希望网站能够为所有用户服务, 不管他们是什么时候重启浏览器更新版本的都应该看到同样的内容.
这种困境通常要由 Babel https://babeljs.io/ 来解决.
Babel 是一个 JavaScript 编译器, 可以将 JavaScript 代码转换为... 不同的 JavaScript 代码! 具体来说, 它能把用最新版 JavaScript 编写的 JavaScript 代码转换为被更多浏览器支持的旧版 JavaScript 等效代码.
Web 开发人员将 Babel 整合到流程中, 就可以使用最新的 JavaScript 功能编写代码, 无需担心浏览器兼容性.
小故事: Babel 不包括 Web API
例如, 如果你在 JavaScript 中使用 fetch,Babel 将不会提供兼容性支持 (兼容支持也称为 "polyfill"-ing), 因为 fetch 是一个 Web API 而不是 JavaScript 本身的一部分.(他们正在重新考虑这个 决定 https://github.com/babel/babel/issues/10008 .
因此你还需要一个独立的解决方案来 polyfilling Web API! 之后的文章中我们会谈到这一点.
再来看流程: 静态网站 +Babel
好的, 所以现在我们已经知道为什么要用 Babel 了. 那么使用 Babel 的 Web 开发流程是什么样的呢?
以下是最简单的 Babel 流程, 人们通常不会用它.(因为像 Parcel 或 webpack 这样的包更方便, 我们以后会提!)
安装
安装 Babel
你可以按照这里的 CLI 说明 https://babeljs.io/setup#installation 操作, 但它假设你了解 NPM 的机制. 他们建议你在本地安装 Babel 作为每个项目的 NPM dev 依赖项, 而不是在你的计算机上全局安装.
开发流程
像普通的静态网页一样开发你的网站.
示例: src 目录是你的 JavaScript 所在的位置
部署
当你准备将网站发布到互联网时, 不可能直接把写好的 JavaScript 文件上传到 Web 端, 因为你一直都用的是所有浏览器都不支持的 JavaScript 功能.
你要做的事情是:
使用 Babel 编译 JavaScript, 以获得与浏览器兼容的代码:
这将在单独的文件夹中创建新的编译好的 JavaScript 文件:
示例: Babel 将生成第二个 "script.js", 该脚本具有跨浏览器兼容的代码
2. 将 编译好 的 JavaScript 与 HTML 和 CSS 一起上传到互联网:
编译好的 JS
加上你的 CSS 和 HTML 文件
你的网站看起来 * 和动起来都和开发模式中的一样, 但用户拿到的是 Babel 编译过的 JavaScript.
这是没有 Babel 的项目: site / script.JS )
这是用了 Babel 的项目: site /script.JS https://zen-lamarr-b74cd8.netlify.com/script.js
(但愿如此! 有时调试和发布版本会有差异, 但这些都是错误!)
停一下, 谈谈开发与发布代码!
请注意, 我们现在将 "开发" 代码和 "发布" 代码区分开对待:
开发代码: 你在开发 Web 应用程序时编写的代码.
发布代码: 用户访问你的 Web 应用程序时要运行的代码.
我们有意区分这两者, 因为:
开发代码对开发人员有利, 但对用户不利
发布代码对用户有利, 但对开发人员不利
在前端 Web 开发中, 不是每个人都会用或者需要 Babel.
但下面的模式:
编写不向用户显示的 开发代码 .
然后编译成另一个版本的 发布代码 显示给用户.
不仅很常见, 而且在现代前端 Web 开发中经常会用到.
请注意, 区分 "调试" 与 "发布" 构建是软件工程中的常用模式, 并不是 Web 开发引入的新事物. 但它特别适合前端 Web 开发, 因为它太常见了, 而且前端 Web 开发的调试 / 发布版本之间区别巨大.
下面是一个简短的前端技术列表, 可以用来区分调试和发布版本:
NPM 模块
各种 CSS 预处理器
React/vue/Angular/ 各种 Web 框架
之后的文章会反复提到这种模式, 所以现在好好记下来!
来源: http://www.tuicool.com/articles/RzYzimY