爲什麼現代Web開發如此複雜?

爲什麼現代Web開發如此複雜?


image.png



源自 | vrk.dev best log譯者 | 王強編輯 | Yonie前端

現代前端 Web 開發的體驗是兩極分化的:一些人對它的評價很高,另外一部分人則認爲它很是惱人。webpack

我是現代 Web 開發的忠實粉絲,我認爲它稱得上是一種「魔法」——但全部的魔法都有其優勢和不足:
  • 若是你能熟練使用 Web 開發的一系列神奇工具(Babel、bundler、watcher 等),就能打造出快速、強大而使人愉悅的開發流程;
  • 若是你不熟悉 Web 開發的這些神奇工具就會步履維艱;
  • 想要搞清楚這些魔法的工做機制每每是條不歸路,除非有人引導你區分 Web 業內的術語、熱點和過期信息。git

最近,我經常須要向新手解釋「現代 Web 開發流程」的內容,可是……github

這很難解釋!web

哪怕是泛泛而談都須要長篇大論才行。npm

千里之行始於足下,本文就是針對 Web 開發演變的一系列歸納介紹的第一篇內容:靜態網站到 Babel 的演變。小程序

最簡單的網站:靜態網站

故事要從「經典」的前端 Web 開發模式講起,相信你們對這部份內容很熟悉了。數組

在經典的前端 Web 開發模式中,咱們會直接修改 HTML/CSS/JavaScript 文件。想要預覽更改時,咱們在本地瀏覽器中打開 HTML 文件,更改代碼後刷新頁面以更新內容。瀏覽器

開發流程這種開發流程以下所示:
  1. 在 Atom 這樣的文本編輯器中編輯 HTML/CSS/JavaScript 文件。
  2. 在文本編輯器中保存文件。
  3. 在瀏覽器中打開並從新加載文件。服務器

  4. image.png

編輯 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. 用戶所有升級到最新版本的瀏覽器,一般經過自動更新 / 從新啓動瀏覽器來完成(有時還作不到!)。

  4. image.png

矛盾:咱們應該用舊版 JavaScript 仍是最新的 JavaScript 編寫呢?二者都有利有弊

這給 JavaScript 開發人員帶來了兩難的處境:咱們但願使用現代化的 JavaScript 語言功能,由於這些改進一般會讓某些內容編寫起來更容易。但咱們也但願網站可以爲全部用戶服務,無論他們是何時重啓瀏覽器更新版本的都應該看到一樣的內容。

這種困境一般要由 Babel 來解決。

Babel 是一個 JavaScript 編譯器,能夠將 JavaScript 代碼轉換爲... 不一樣的 JavaScript 代碼!具體來講,它能把用最新版 JavaScript 編寫的 JavaScript 代碼轉換爲被更多瀏覽器支持的舊版 JavaScript 等效代碼。image.png

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 說明(詳見下方連接)操做,但它假設你瞭解 npm 的機制。他們建議你在本地安裝 Babel 做爲每一個項目的 npm dev 依賴項,而不是在你的計算機上全局安裝。

CLI 說明: https://babeljs.io/setup#installation

 開發流程

  1. 像普通的靜態網頁同樣開發你的網站。

  2. image.png

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

 部署

當你準備將網站發佈到互聯網時,不可能直接把寫好的 JavaScript 文件上傳到 Web 端,由於你一直都用的是全部瀏覽器都不支持的 JavaScript 功能。

你要作的事情是:
  1. 使用 Babel 編譯 JavaScript,以得到與瀏覽器兼容的代碼:

  2. image.png

這將在單獨的文件夾中建立新的編譯好的 JavaScript 文件:image.png

示例: Babel 將生成第二個「script.js」,該腳本具備跨瀏覽器兼容的代碼
  1. 將編譯好的 JavaScript 與 HTML 和 CSS 一塊兒上傳到互聯網:

  2. image.png

編譯好的 JSimage.png

加上你的 CSS 和 HTML 文件

你的網站看起來和動起來都和開發模式中的同樣,但用戶拿到的是 Babel 編譯過的 JavaScript。
  • 這是沒有 Babel 的項目:https://sleepy-lichterman-6811cc.netlify.com/script.js

  • 這是用了 Babel 的項目:https://zen-lamarr-b74cd8.netlify.com/script.js

    (希望如此!有時調試和發佈版本會有差別,但這些都是錯誤!)

 停一下,談談開發代碼與發佈代碼 image.png

請注意,咱們如今將「開發」代碼和「發佈」代碼區分開對待:
  • 開發代碼:你在開發 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/

  活動推薦

遊戲大佬,很久不見!8 月 17 日下週六 13:30-18:00,在廣州南國酒店的 「小程序·雲開發」系列沙龍(小遊戲專場),咱們邀請來自微信團隊與騰訊雲團隊的資深工程師們將就遊戲話題與你一同探討,並經過 Workshop 上手開發一款屬於本身的小遊戲呦~ 掃描下圖二維碼和閱讀原文連接免費報名參加。

報名到場還有機會贏取小霸王遊戲機、華爲無線充電器等超值禮品。

相關文章
相關標籤/搜索