最近開了一個讀者回饋表單,無論是對文章的感想或是對部落格的感想,有什麼想回饋的都可以填表單跟我說:表單連結

紮實的網頁前端學習路線與資源推薦

(原文寫在 Medium,順便在這邊備份一下)

雖然說我一直很清楚自己目前偏好的學習方法以及路線,並且把我認為適合的路徑都變成上課的大綱拿去教學,但一來好像沒多少人會去看那個大綱,二來大綱並沒有詳細解釋背後的原因。因此我才覺得自己有必要寫這一篇,來寫一下自己認為比較「紮實」的網頁前端學習路線。

在開始之前有幾點必須先說明一下。

首先,此文章我預設的對象是毫無程式基礎的人。若你已經有了程式基礎,可以自行略過相關的單元。另外,對於毫無基礎又想轉職的人來說,這篇絕對不是「最快」轉職指南。

求快的話我相信文章裡提到的東西很多都不用學,畢竟現在有些工作的門檻低到我自己都嚇到了。但一心求快只會讓不穩的基礎更不穩。就算找到工作了,可是然後呢?就不再加強自己了嗎?就讓自己的實力停留在那邊嗎?

若你想把這份工作做得長久,總有一天要面臨這些問題,那些以前沒學好的基礎,會在將來你困惑為什麼上不去時反噬你。每個人認為的「必備」以及對「紮實」的定義都不一樣,例如說有人會覺得只要把資工系教的那些科目修完就叫做紮實,其他都沒那麼重要。而這篇寫的是我自己認為紮實的路線。

這篇文章會告訴你「我認為」應該要學什麼,以及應該要照怎樣的順序學。最重要的是,我會附上理由。你可以自行判斷背後的理由是否合理,來決定是否要按照這個順序學。理由才是最重要的。

如果有時間,可以先參考這兩篇我以前寫過的文章:

  1. 當我們在學程式時,要學的到底是什麼?

  2. There is no magic in my classroom

底下的學習路線基本上是從我之前的課綱改編而來,而且是秉持著上面這些原則在設計的。另外,下面比較多其實都是告訴你該學哪些工具,但請記住在學工具的時候,還必須去思考為什麼需要用到這些工具,它們解決了哪些問題。此篇文章只專注於網頁前端的領域,其餘工程師的基本功(例如說拆解問題或是定義問題範圍等等)不包含在裡面。

推薦資源的部分,原則上我只推薦自己嘗試過並且真的覺得很不錯的資源,所以並不是每個部分都會有。沒有的話可以自己透過 Google 尋找,學會找資料也是很重要的一環。

底下文章會很長,因為又要寫理由又要寫目標,我先附上學習路線:

  1. Command Line 的使用
  2. Git 的使用
  3. npm、Node.js 與 JavaScript 程式基礎
  4. 單元測試 Unit Testing 與 Jest
  5. 網路基礎概念
  6. HTML 與 CSS
  7. JavaScript 與 DOM 以及事件機制
  8. 非同步與 AJAX
  9. 基礎後端 PHP 與 MySQL
  10. 資訊安全概念
  11. 學習後端框架 Express
  12. 後端部署
  13. jQuery 與 Bootstrap
  14. CSS 預處理器
  15. 非同步歷程:callback、promise 與 async/await
  16. 深入理解 JavaScript 與瀏覽器相關機制
  17. gulp 與 webpack
  18. 物件導向
  19. React/Vue/Angular 三選一

接著底下就是每一點的詳細介紹。

1. Command Line 的使用

這是拉近你與電腦距離第一步,也是要開始學程式前最重要的基礎。

先大概講一下 Command line 是什麼,基本上就是你看電影時會看到電腦高手在一個黑底白字的視窗上打一堆指令(command),而第一步就是要學習怎麼使用這些基本指令。

我的 Terminal,有改過所以比較漂亮我的 Terminal,有改過所以比較漂亮

學習理由

這一步之所以放最前面的原因有兩個,第一個是它讓你從以往的圖形使用者介面(Graphical User Interface,GUI)切換到命令列介面(Command Line Interface,CLI)。講白話一點,你以前要看桌面有什麼檔案,就用滑鼠點開檔案總管或是 Finder 就行了,你是靠著這些圖形介面去操作的。

但 Command line 之所以不同,是因為它是用文字去操作。就像我上面的截圖那樣,打一個神奇的指令 ls -al,就可以列出資料夾底下的所有檔案。

寫程式的本質跟使用 Command line 是一樣的:

利用指令與電腦溝通

第二個原因是它在程式開發裡非常重要。如果你是做設計相關的,電腦裡可能會有 PS、AI 或是 Sketch 等等的軟體,想用的時候只要滑鼠點兩下就可以了。但我們寫程式的不一樣,很多工具都沒有提供圖形介面,你只能使用指令(Command line)去操作它。

學習目標

只要學會常見指令(例如說 cd、ls、rm、mv 等等)即可。

2. Git 的使用

假設你有一個很喜歡改東西的主管,他請你幫忙畫一張圖。於是你畫好以後把圖片存成 v1.ai 並交給主管看,而主管說不行,要再改,就有了 v2.ai。後來主管說:「顏色改一下就差不多了」,你就把圖片改完以後存成 final.ai。

可誰知道主管看完以後又說要改,而且還要從 v2 開始改(這時你就會慶幸你有存起來),你只好打開 v2 的檔案,改完以後存成 v2–2.ai。

接下來的故事不用多說了,final.ai、real-final.ai、fucking-final.ai、real-real-final.ai,最後電腦出現了一大堆你也不知道哪個才是最終版的檔案,把自己搞得頭昏腦脹。

這是我自己放履歷的資料夾,我都不知道哪個才是最新的了…這是我自己放履歷的資料夾,我都不知道哪個才是最新的了…

版本控制是一件難事,尤其是透過這種傳統式的複製貼上,只會讓自己搞混。如果一個人搞混其實還行,頂多再花一點時間來找,但如果是一整個團隊協作一份文件,那問題就大了。

而軟體工程師就是一個逃不開團隊協作,也逃不開版本控制的一個行業。例如說目前版本是 v2 穩定版,於是小明繼續開發 v3 的新功能。可是某天 v2 卻被發現了一個 bug!負責救火的小華效率很高,不到一天就把 bug 修掉了。

可是問題來了,已經寫好的新功能不能發布,因為 v3 還沒開發完成,可是修好 bug 以後又要趕快讓使用者更新成新的版本,那怎麼辦呢?這就是需要版本控制的時候了。

講了這麼多,我只是想說明在寫程式上(尤其是多人協作時)版本控制的重要性,而最有名的一套協助你做版本控制的程式就叫做 Git。

學習理由

會放在第二個要學的東西,是因為先學了 Git 以後你就可以體驗幫自己以後寫的程式碼做版本控制。雖然說只有一個人的話,有些團隊協作才會碰到的困難會體驗不到,但沒關係,還是可以先從基礎的開始學。

學習目標

  1. 學習 Git 基本概念:什麼是 repository、什麼是 commit、什麼是 staged…

  2. 學會使用 add、commit、status、log 等基本指令

  3. 搞清楚 Git 與 GitHub 的差別並學會 push、pull、clone、fetch

  4. 學會使用 branch 與 checkout

如果要學 branch 的使用,誠心推薦 Learn Git Branching

3. npm、Node.js 與 JavaScript 程式基礎

JavaScript 只是一個程式語言,目前主要可以跑在兩個環境上面,第一個環境眾所皆知,叫做瀏覽器,可以利用 JavaScript 去操作畫面;第二個環境叫做 Node.js,可以脫離瀏覽器獨立運作。你安裝好 Node.js 以後,輸入 node index.js 這個指令就可以在你電腦上執行 index.js 這個檔案。

這邊我希望大家先不要碰瀏覽器,而是在 Node.js 這個環境上執行自己的 JavaScript 程式碼。

因此這個階段就是要在自己的電腦上安裝 Node.js 環境,並且藉由 JavaScript 來學習程式語言的基礎(變數、判斷式、迴圈、函式等等)。推薦的學習資源是現代 JavaScript 教程

那 npm 又是什麼呢?講到 npm 以前我們要先來講什麼是 library,在程式領域裡面不會翻叫圖書館,而是翻作「函式庫」,就是很多函式的集合啦。

簡單來說呢,有些功能不是很常用嗎?可能我會用到、你會用到、獨眼龍也會用到,那獨樂樂不如眾樂樂,與你分享的快樂勝過獨自擁有,我今天寫好一大堆常用的 function,可以給其他人用,皆大歡喜。這就叫做「我寫了一個 library 給別人用」。

npm 全名為 Node Package Manager,這邊的 package 就跟上面講的 library 差不多,中文翻作「套件」。是一個管理 Node.js 相關套件的服務,因此你可以發布自己寫好的套件到上面去,也可以透過 npm 安裝別人寫好的套件。

學習理由

有些人看到這邊可能會問說:「怎麼不是先學 HTML 與 CSS?」

我的理由是這樣的,既然是要走網頁前端,那就一定要學 JavaScript 這個程式語言,只是早學晚學的問題而已。而 HTML 與 CSS 能夠快速帶給學習者成就感,因為能夠立刻看見自己到底學了什麼,是能夠補充學習動力的科目。

在學新東西的時候,一定是剛開始最有毅力,之後就會慢慢消退,拖延症開始發作。選在這時候學 JavaScript 就是因為這樣。我覺得趁著動力還沒消退的時候先學比較好,後面才學 HTML 與 CSS,順便把動力一起補上。

而 npm 之所以重要,是因為你以後會很常用到 npm。在這個階段可以自己找一些簡單的套件來試用看看,順便練習看文件。

學習目標

想要測驗自己有沒有學好程式語言基礎的話,可以透過一些簡單的小題目來驗證,也可以寫一些 Codewar 的題目。只要裡面提到的那些基本的題目能寫得出來就 ok 了。

npm 的話只需要知道以下概念:

  1. 什麼是 package.json

  2. npm install 做了什麼事情

4. 單元測試 Unit Testing 與 Jest

上個階段有說可以寫一些小題目來測驗自己的程式基礎是否合格。在像是 Codewar 那種網站上面,它會幫你改,會告訴你錯在哪裡,可是在自己的電腦上要怎麼測呢?

簡單嘛,就是自己想幾個測試案例,然後用 console.log 印出答案是不是對的。

感謝 [https://carbon.now.sh](https://carbon.now.sh/) 提供的服務感謝 https://carbon.now.sh 提供的服務

沒錯,這樣子是可以的,但其實這不是一個好方法。因為你必須要用肉眼去判斷到底是哪一個 test case 出了錯,若你的 test case 變多,也很難一時之間看出來到底答案是不是對的。

閃開!讓專業的來!(突然發現這句話也很有年代感了)

Jest 是一套專門讓你測試 JavaScript 程式碼的框架,只要用它指定的架構及函式,就可以輕易寫出用來測試的檔案,而且還會有精美的測試報告。

而這種針對 function 的輸入以及輸出做測試的方式,我們稱之為單元測試( Unit Testing)。測試寫得好,程式就不怕改壞掉。因為只要跑一下測試,就能看出程式碼寫得是否正確。

學習理由

會把單元測試放在這的理由是因為我覺得放這裡最貼切。上個階段會寫一堆小的 function,學了 Jest 之後剛好可以幫這些 function 加上單元測試,體驗看看測試的威力。

學習目標

  1. 知道如何使用 Jest 測試一個 function 的輸出入

  2. 盡力想出各種 test case

5. 網路基礎概念

在正式進入到網頁前端最有名的 HTML 與 CSS 之前,還有最後一件事情要做,那就是稍微知道一下網路的基礎概念。

在這階段你必須知道的東西包括但不限於:

  1. 什麼是前端?什麼是後端?

  2. 什麼是 Request?什麼是 Response?

  3. HTTP 是什麼?HTTP 的 method 又有哪些?

  4. HTTP 的常見狀態碼(200、301、302、400、404、500…)

  5. 什麼是 API?

理解這些概念以後,可以試著找一些現成的 API,然後使用 Node.js 的一些套件例如說 request 或是 axios 來嘗試串接看看。

沒有到很清楚沒關係,但基本的概念一定要有。因為一堆新手都對這方面幾乎毫無概念,導致發生問題時根本就找錯癥結點,花了很多時間才發現錯誤根本不是出在自己想像的地方。

這邊會推薦一些比較理論性的課,除了網路的概念以外也可以順便補齊其他基本概念:

  1. Crash Course

  2. [CS101] 初心者的計概與 coding 火球術

學習理由

會把這些網路概念放在這麼前面,是因為我在各個技術相關社團裡面看過太多太多搞錯領域的問題了。明明要問的是前端,卻在後端的社團發問,以為跟後端用的框架有關;明明是網路出了錯,卻以為是前端的問題。這些我都認為是沒有建立起整體網路的概念所導致的。

學習目標

  1. 知道什麼是 Request 跟 Response

  2. 知道什麼是 DNS

  3. 知道 localhost 跟 127.0.0.1 是什麼

  4. 知道什麼是 API

  5. 會使用 Node.js 寫出串接 API 的程式

  6. 知道 HTTP method 有哪些

  7. 知道基本的 HTTP status code,像是 200、301、400、404、500

6. HTML 與 CSS

前面鋪墊了這麼多,終於可以開始學 HTML 與 CSS 了。前者是網頁的骨架,後者是網頁的衣服。HTML 就只是用特定格式以及標籤組合而成的檔案,你必須選擇適合的標籤來表示內容,只要理解一些常見標籤就差不多了,而學習的重點有兩個。

第一個是要讓自己的 HTML 符合語意(semantic)。例如說你今天有一個列表,比起用一大堆 <div>,用 <ul><li> 會更適合的多。該怎麼檢測呢?你不要看畫面,只看 HTML 原始碼的標籤,試看看能不能看出每個區塊代表的意思或是重要程度,如果可以的話,就代表你寫得不錯。

第二個是可以稍微關注一下 SEO(Search Engine Optimization),這其實跟上一點滿相關的。搜尋引擎會需要去爬很多網頁,並根據網頁的原始碼來解析。SEO 就是要讓它們能夠看懂你的網頁,知道你網頁上的重點是什麼。

舉例來說,假設現在有兩個網頁,第一個全部都只有 <div> 標籤,第二個有用 <h1> 把大標題寫出來。機器人看得懂哪一個?當然是第二個,因為 h1 就代表著大標題,它就會把裡面的內容視為是這個網頁的主題之一。

或是這樣說吧,標籤就像是寫文章的排版一樣,用得不好的沒有粗體、沒有標題甚至還沒有句號,一眼望去全部文字都長得一樣,分不出哪些是大標哪些是小標。用得好的標籤就是優質的排版,一目瞭然,有什麼都十分明瞭。

HTML 只能對網頁做基本的排版,需要進一步美化的話你需要 CSS。利用 CSS 你可以「針對網頁上不同地方」給予不同樣式,例如說 A 區塊背景是紅色,B 區塊背景是綠色等等。

這就帶出了 CSS 的第一個重點:我要怎麼選到我想選的地方?

這叫做 CSS 選擇器(Selector),有一些規則要學,可以透過標籤、class、id 或更複雜的方式來選到想要的元素。學完一些基本的之後可以透過 CSS dinner 這個超可愛又好玩的遊戲來複習並加強對 selector 的理解。

再來就是跟排版相關的了,要知道什麼是 box model,知道 position 跟 display 所有屬性的差異,這都是排版很重要的東西。

為什麼它們重要?因為如果不理解以上機制的話,是沒辦法排版的。盒模型代表著瀏覽器怎麼去看每一個元素,而 display 決定了這些元素能不能排在同一行,position 可以讓你隨心所欲的放置元素。

另外,也必須知道如何使用 Flexbox 排版。可以透過好玩的 Flexbox Froggy 或是 Flex Pirate 來學習。如果有時間的話也可以看看比較新的屬性 grid,並且玩一下這個小遊戲:Grid Garden

最後,也要知道該怎麼在不同螢幕尺寸上做不同的排版。

核心概念就是:「在不同尺寸上套用不同的 CSS」,例如說你原本是兩欄式排版,在使用手機觀看的時候就把這兩欄的寬度都設為 100%,就變成上下兩行的排版而不是並排了,這樣比較符合手機的使用習慣。

要做到這件事情需要透過 media queries 這個寫法,依照不同的條件(例如說螢幕寬度、高度等等)來載入不同的 CSS。

前面已經有講 CSS 學習時的重點了,但理論畢竟只是理論,你千萬不要想著看一看教學文就能夠理解那些理論到底想表達什麼。

我以前看了 position 的解釋千萬遍,卻從來都不理解 position: absolute 到底是根據誰定位,然後要拿來幹什麼。直到有一天我必須實作一個在圖片右上角放叉叉的功能,那時我才真的知道為什麼需要 absolute。

除了 CSS,其他東西也是這樣,光看是沒有用的。你看了 position 的解釋一百遍,還不如打開瀏覽器自己亂玩那些屬性一遍。

推薦的資源有:

  1. html & css is hard

  2. Learn to Code HTML & CSS

  3. MarkSheet

  4. HTML & CSS : 網站設計建置優化之道(我學生推薦的)

學習理由

要開始學習前端的話,一定要會 HTML 與 CSS,因為這兩者是網頁的基礎。

學習目標

  1. 知道如何使用有語意的(semantic)標籤

  2. 知道基本的 CSS Selector

  3. 知道盒模型(box model )是什麼,以及 padding、margin、border、width/height 與它的關係?

  4. 知道 display 的幾種屬性:block、inline 與 inline-block 差別在哪裡

  5. 知道 position 的幾種屬性:static、relative、absolute、fixed 與 sticky 差別在哪裡

  6. 知道如何使用 Flexbox 來排版

  7. 知道如何使用 media queries

7. JavaScript 與 DOM 以及事件機制

還記得我前面說過 JavaScript 基本上可以跑在兩個地方嗎?瀏覽器與 Node.js。在學完 HTML 與 CSS 以後,就可以來試著把 JavaScript 寫在瀏覽器上面了。

寫在 Node.js 與瀏覽器上面最大的差別就是

你可以使用 JavaScript 操作畫面

只要是頁面上看得到的東西,你都可以改。你可以新增元素、刪除元素、更改樣式,也可以針對不同的元素加上不同的事件監聽器(Event listener)。舉例來說,你可以監聽某個按鈕的 click 事件,使用者點下按鈕的時候你就會知道,就可以針對這個事件做出反應,例如說點下按鈕之後跳出一個 alert 之類的。

這個部分的學習重點有兩個,第一個是 JavaScript 是如何操作畫面的?是透過一個叫做 DOM(Document Object Model)的東西。簡單來說就是瀏覽器把畫面上那些 HTML 元素都轉成物件,並且提供給你一個 API 來操作它們。

像是 document.querySelector(‘#aaa’),會回傳 #aaa 這個 DOM 物件,你只要改變它,畫面上的元素也會跟著改變。所以學習的第一個重點就是如何操作 DOM 物件。你要學會怎麼新增、修改以及刪除這些物件。

第二個重點則會放在事件機制。

我要怎麼幫元素加上 event listener?又要怎麼拿掉?如果加上兩個會怎樣?

除此之外,DOM 的事件機制比你想像的更複雜一點,例如說你有兩個重疊的元素,外面是藍色叫做 Blue,裡面是紅色叫做 Red:

事件傳遞機制附圖事件傳遞機制附圖

今天當你點擊 Red 這個方框的時候,Red 的 click 事件就被觸發了。但不僅如此,接著 Blue 的 click 事件也被觸發了!想一想其實也滿合理的,因為 Red 是在 Blue 裡面,藍色的方框不是中空的,只是被紅色蓋過去而已。

這就是這個部分要學習的重點:事件機制的運作方式,細項可參考底下的學習目標。

這邊學完以後,你就能做出任何「不牽涉到網路」的應用程式了。例如說單機就可以玩的數獨小遊戲或者是五子棋,都可以做得出來,因為這些都只是畫面跟事件的集合而已。

舉例來說,五子棋怎麼做?

  1. 先用 HTML 與 CSS 畫出棋盤

  2. 偵測棋盤的點擊事件,點下去時畫一個棋子在點擊的地方

  3. 判斷棋盤上的棋子是否連成一線

  4. 是,遊戲結束

  5. 否,換另一個玩家的回合,回到第二步

不要以為你只學了這些而已,這些就是精髓了。只要你可以監聽事件,可以更改畫面,有什麼功能是做不出來的?把想做的東西拆解到最後,會發現其實都只是這些操作的組合而已,沒有什麼魔法在裡面,你需要的只是一點想像力而已。

學習理由

如果要在瀏覽器上面學 JavaScript,那勢必要談到 DOM,才能操作畫面。

但前面我說過了,我不希望先講 HTML 與 CSS,我希望先講「程式語言 JavaScript」。這時候以 Node.js 環境來學習是比較好的方法,因為它不會牽涉到 DOM 或是其他前端的東西,它就只是個簡單的程式語言而已。

我認為這樣子能有兩個好處:

  1. 知道 JavaScript 不只能在瀏覽器上面跑

  2. 知道 JavaScript 只是個程式語言,DOM 是執行環境(瀏覽器)提供的東西,像是 Node.js 裡面就是沒有 DOM 的。

這樣才不會把執行環境跟 JavaScript 混為一談。

學習目標

  1. 知道 DOM 的基本操作,例如說插入、刪除、更改屬性等等

  2. 知道事件是如何傳遞的。知道什麼是捕獲,什麼又是冒泡。

  3. 知道 e.preventDefault 與 e.stopPropagation 的作用以及差別

  4. 知道 e.target 與 e.currentTarget 的差別

  5. 知道什麼是事件代理(Event delegation)以及適合用的場合

8. 非同步與 AJAX

在上一個部分學完事件機制的相關概念以後,就只差最後一塊拼圖了,那就是 JavaScript 與後端的溝通。我們會使用一種叫做 AJAX 的技術,聽起來很困難,但說穿了其實就是用瀏覽器提供的 Web API 向後端發送 Request 並且拿到 Response。

這個部份對於前端來說超級無敵重要,因為會有很多概念需要理解,我們一個一個來。

第一個是瀏覽器的同源政策(Same-Origin Policy)。

當你利用 JavaScript 發送 Request 的時候,出於安全性的考量瀏覽器會有一些限制。不同的 Request 限制也不太一樣,但大原則就是「如果後端沒有允許你做這件事,就拿不到 Response」。所以通常需要後端的協助,來開啟 CORS(Cross-Origin Resource Sharing,跨來源資源共享)。

你必須搞清楚什麼是同源政策、為什麼要有同源政策,而它又限制了哪些東西。也必須理解該怎麼利用 XMLHttpRequest 或是 Fetch 來串接 API。

第二個是既然提到了AJAX,你也必須知道非同步(Asynchronous)是什麼意思。這邊有些人會被字面上的意思誤導,因為同步(Synchronize)看起來很像「同時做一件事」。

可是在電腦科學的領域裡面,同步指的其實是「一次只能完成一件事,要等前面的事情做完,才會做下一件事」。如果與後端 API 串接是同步的,會發生什麼事?可怕了,如果後端速度很慢,10 秒後才會回傳 Response,那 JavaScript 必須等 10 秒才能執行下一個指令。

這不可能嘛,不可能讓整個畫面卡住 10 秒,所以 AJAX 的第一個 A 就代表著 Asynchronous,意思就是非同步地去跟 Server 溝通並交換資料。

那非同步要怎麼拿到資料?這邊就會講到回呼函式(Callback function)的概念。你準備好一個函式,並且跟瀏覽器說:「欸,你過來一下,等你好的時候記得叫我」。

除了 AJAX 以外,計時器(例如說 setTimeout)也是非同步的,你不可能原地等三秒之後執行嘛,一定在中途還有做其他事情,三秒後才會觸發計時器。可是眾所皆知,JavaScript 的執行是 single thread,一次只能做一件事,那到底是怎麼樣做到非同步的?

這就會牽涉到 Event Loop 的機制,我強力推薦這個影片,講的超級好:What the heck is the event loop anyway? | Philip Roberts | JSConf EU

學習理由

先來講一下為什麼建議這樣學,因為前面我們已經有了網路概念,也有了事件機制的概念,基礎的 JavaScript 都沒有問題了。而非同步的相關操作就是理解 JavaScript 的最後一塊拼圖,也是網頁前端很重要的一部分。

所以才會把 AJAX 放在這裡,等前面基礎打好以後再來接觸 AJAX,並且把非同步的相關概念一併理解。

學習目標

  1. 知道非同步與同步的差別

  2. 知道什麼是同源政策(Same-origin policy)

  3. 知道如何存取跨網域的資源(CORS)

  4. 知道如何使用 XMLHttpRequest 或 Fetch 串接 API

  5. 理解 Event loop

9. 基礎後端 PHP 與 MySQL

接著我們要來學習基礎的後端開發,會學純 PHP,也就是在不使用任何 PHP 的框架下來學習。

另一個重點是資料庫,這邊選用最常見的 MySQL,而且 PHP + MySQL 這個組合有一堆現成的工具可以用,例如說 XAMPP,直接幫你把整個環境建好。

MySQL 的部分不要跑去學什麼 ORM(Object Relational Mapping),請乖乖地寫 SQL Query,好好學一下怎麼樣做 CRUD(Create、Read、Update、Delete),並且自己試著開 Table 然後決定欄位的資料格式。

學習理由

看到這邊有些人可能會問:為什麼要學後端?

來來來,有沒有注意到標題上的四個字?「網頁前端」,這同時代表著「網頁裡的前端」以及「網頁與前端」兩個意思。網頁分為前端跟後端,如果你只理解前端,你是永遠不可能理解整個網頁的。

就如同我在第五點網路基礎概念裡面提到的一樣,許多人都是缺乏了整體概念,才會導致出錯時定位錯問題,或是根本不知道問題發生在哪裡。學習後端最主要的理由就是補齊自己缺少的概念,當發生問題時你才知道問題到底出在哪裡。

這邊我不推薦學 Ruby on Rails,也不推薦 Laravel 跟 Express,而是推薦從 PHP 開始學——沒有使用任何框架的 PHP。

因為它夠簡單。一個 PHP 檔案就是負責一個頁面,你在檔案裡面 echo 什麼,畫面上就輸出什麼,十分簡單明瞭,而且很容易學。

若是你有學過一點程式或找過相關資料,可能會問說:「不對啊,可是這樣寫到後面 code 不會很髒嗎?全都混在一起,毫無架構可言!」

對啊,就是這樣,你說的很對——但我是故意的的。

如果全世界的生理男都長得像金城武,金城武還是帥的嗎?不是。金城武之所以帥,是因為你看過很多比他醜的人,你才知道金城武是帥的,這是比較而來的。

寫 code 也是同樣道理。你如果沒有寫過看過爛 code,你看到好 code 的時候怎麼知道它好在哪裡?你不會知道,而且你搞不好也認不出來那是好 code。你必須先寫過夠多爛 code,才會知道好 code 到底厲害在哪裡。

這就是為什麼我推薦從純 PHP 開始學,因為寫到後面你一定會寫得很髒很亂很難修改很難維護,但唯有這樣,接觸框架時才會知道框架到底好在哪裡。

學習目標

  1. 理解什麼是前端,什麼是後端

  2. 知道什麼是資料庫

  3. 了解基本的 SQL 語法,包括 Select、Insert Into、Delete 與 Update

  4. 能夠使用 PHP 做出簡單的留言板或是部落格

10. 資訊安全概念

學後端還有一個好處,那就是你會更清楚常見資訊安全漏洞到底是怎麼出現的,以及如何防禦。

如果你聽我的去學純 PHP 的話,你很有可能會寫出有 SQL Injection 或是 XSS(Cross-site Scripting 跨站式腳本攻擊)以及 CSRF(Cross-site request forgery 跨站請求偽造)漏洞的網站。

平常看再多文章,都不如自己的網站出漏洞來的有感。像我之前的興趣之一就是攻擊學生們自以為防禦的很好的網站,讓他們知道資訊安全的重要性。

常見的資安漏洞通常都是沒有預料到使用者的輸入會長得那麼千奇百怪。

例如說你有一個留言板開放人家留言,後端直接把留言內容印出來,你可能會想說沒什麼。直到某天有人留了 <script>alert(1)</script>,讓所有開啟留言板的人都彈出一個視窗,你才意識到:「靠腰勒,原來有人會輸入這麼奇怪的東西」。

學習理由

再重新講一下為什麼我建議不要從框架開始學的理由。若是你學了框架,你很有可能碰不到 SQL Injection 與 XSS,因為框架都幫你防掉了,你想入侵自己的網站都沒有辦法,就少了很多實測的樂趣。而且重點是哪天你一但脫離框架或者是錯誤地使用框架,很有可能產生出漏洞卻不自知,因為你沒有資訊安全的意識。

所以在這個部分,就是盡量讓自己寫出有漏洞的網站,然後自己試著入侵網站,看看是否能成功。成功以後就開始查詢修補方法,看看要怎麼補起來,這時候就會知道攻擊原理跟防禦手法,印象也會更深刻。

還有一個很重要的,密碼要記得 hash 過後才存到資料庫,拜託不要存明碼。

學習目標

  1. 知道雜湊與加密的差別

  2. 知道什麼是 SQL Injection 以及如何防範

  3. 知道什麼是 XSS 以及如何防範

  4. 知道什麼是 CSRF 以及如何防範

11. 學習後端框架 Express

前面已經受過純 PHP 的折磨了,寫過夠多爛 code,也寫出夠多漏洞了,接下來我才會推薦你開始學框架。要學哪一個都行,但我推薦 Express,因為它比較輕量,而且使用的程式語言是 JavaScript。

這個部分的目標很簡單,就是體驗看看有框架與之前沒框架的差別,熟悉後端框架中的幾個元素(MVC 之類的)與整體架構。

對於網頁前端工程師,學 Express 還有一個好處,那就是以後想要做什麼 side project 都可以自己來,後端可以自己寫。這是很多前端工程師的煩惱,想要做 side project 可是卻不會後端,資料不知道從哪裡去抓,因此只能放棄。

如果有時間也可以去學一套 ORM,例如說 Sequelize,你會覺得跟之前 SQL query 比起來快很多也簡單很多。

但是請千萬要記住,像 Express 這種框架或者是 Sequelize 這些 ORM,背後都沒有什麼魔法。拆到最底層一樣是你之前在 PHP 裡面學到的那些基礎,解析 Request、拿取參數、返回 Response 與執行 SQL query 等等。

學到框架以後就可以拋棄純 PHP 了,以後都可以用框架來開發。因為你是個知道框架在幹嘛,也知道為什麼要用框架的開發者,而不是只會用框架,卻連 SQL query 都不會寫的人。

學習理由

體驗有無框架的差別以及熟悉後端 MVC 架構,會更清楚有架構與沒有架構的差別。

學習目標

  1. 知道什麼是 MVC

  2. 知道什麼是 ORM

12. 後端部署

既然都已經開始學後端了,那就把後端的流程全部跑完吧!接下來要學的東西是部署,你必須自己去租一台機器(AWS、Google Cloud 第一年都有一些優惠,沒有優惠的 DigitalOcean 最便宜的機器一個月也才五塊美金),然後把程式碼放上去。

還需要自己去買一個網域(Domain),並且學習 DNS 的設定,把網域對應到你買的機器。完成之後,就能夠擁有一個個人網站了,以後的作品集都可以放在自己的網站上。

學習理由

這是學習路線裡面最後一個有關後端的部分了,之後的內容都不會再有後端。你可能會想說身為網頁前端工程師,有必要學這麼多後端嗎?

你錯了,這些一點都不多,我覺得只是皮毛而已。後端的水一樣很深,我們學到的真的只是一些基礎,而這些後端概念是我認為許多前端工程師所欠缺的。

如同我前面說的一樣,網頁是由前端與後端組成,少了任何一邊都不夠完整。要你學這些後端不是為了讓你成為後端工程師,而是讓你在網頁出問題時能夠明確知道問題發生在哪裡。

學習目標

  1. 知道如何設定網域(A、CNAME)

  2. 知道如何用 SSH 遠端連線到自己的主機

  3. 知道怎麼部署自己寫好的程式

中場總結

以上的東西全部學完以後,我覺得基礎就算 ok 了。以學到的東西來說,已經可以把任何看得到的網站實作出來。真心不騙,只是功能可能陽春一點,速度慢一點,但真的做得出來。

任何網站都是由底下這些基礎組合而成,括弧裡面是學到的對應的技術:

  1. 後端伺服器與商業邏輯(PHP + Apache)

  2. 資料庫(MySQL)

  3. 前端頁面與互動(HTML + CSS + JavaScript)

圖片來源:[https://tw.beanfun.com/kartrider/img_newhand/s01.jpg](https://tw.beanfun.com/kartrider/img_newhand/s01.jpg)圖片來源:https://tw.beanfun.com/kartrider/img_newhand/s01.jpg

不知道大家有沒有玩過跑跑卡丁車?反正就是一個賽車遊戲。現在的情況就是,你已經學會開車、學會甩尾以及單噴,也學了常見地圖的跑法,一定可以跑到終點,只是時間快慢而已。

所以接下來要學的東西都只有一個目的:

讓你跑得更快

13. jQuery 與 Bootstrap

在前面的段落裡與前端相關的部分幾乎沒有提到任何一個 library,而接下來的推薦學習路線會出現許多的 library 以及工具。

第一個是鼎鼎大名的 jQuery。不用學到多厲害,基本的東西會用就好。我覺得 jQuery 還是挺好用的,而且是前端發展史上面非常重要的一環。

再來是 Bootstrap,只想入門的話我也覺得不難學,就按照官方文件把元件的 CSS 加上 class 就差不多了。總之它是個 UI library,可以幫助你把畫面變得更漂亮也更有一致性。

前面有說過基礎已經學的差不多了,接下來的內容都會專注在「如何跑得更快」,而這兩個 library 我認為就有符合這個條件,藉由 jQuery 以及 Bootstrap 來提升自己的開發速度。

學習理由

學 jQuery 的理由是儘管它現在沒有那麼熱門了,但在小專案上面依然很好用,而且透過 jQuery 可以幫你減少一些原生很煩瑣的操作,節省時間。然後只是想要入門 jQuery 的話我覺得不用花多久時間,所以學一下比較好。

Bootstrap 的話則是能夠美化你的介面並且加速排版。

除了學新的工具以外,同時也是在訓練自己看文件的能力。今天你想要用 jQuery 來做 AJAX,應該要用哪個函式?想要套用 Bootstrap 的按鈕,class 應該怎麼用?這些都要透過 Google 或者是去官方文件查詢才會知道。看文件也是工程師的必備能力之一。

學習目標

我覺得可以用這兩個東西寫出一個 TodoList 就沒問題了。

14. CSS 預處理器

「跑得更快」的方法之一就是站在巨人的肩膀上,用著前輩們開發出來的好用工具,就能讓開發的速度更快,程式碼也更好維護。

而 CSS 預處理器就是這樣子的一個東西,可以讓你用像寫程式那樣子的方法來寫 CSS,可以定義變數、跑迴圈,甚至是呼叫函式。

知名的預處理器有 SaSS/SCSS、Less 以及 Stylus 等等,這裡面隨便挑一套來學就好。會需要學這個是因為現在很少人直接寫 CSS 了,都是用 CSS 預處理器來編譯。

學習理由

幫助你寫出更好維護的 CSS,同時也提高開發效率。

學習目標

  1. 了解 CSS 預處理器的目的以及原理

  2. 能夠把自己之前寫的 CSS 用任一預處理器改寫

15. 非同步歷程:callback、promise 與 async/await

在第八點「非同步與 AJAX」裡面就有學到了 Callback 的概念。由這個延伸出去可以學到 Promise,以及比較新的 async/await 語法,這些都與非同步的概念息息相關。

學習理由

在 JavaScript 裡面,理解這些東西的使用以及發展歷程我覺得是滿重要的事情,因此特地給這個主題一個段落,畢竟這些東西應該要是放在一起學習的。

要學的理由是 JavaScript 裡許多東西是非同步的,而現在幾乎都會用 Promise 來處理非同步的問題,要理解這些語法才能知道如何使用。

學習目標

  1. 知道如何使用 Promise

  2. 知道如何使用 .then 及 .catch

  3. 知道如何「同時」執行多個 Promise

  4. 知道如何「按照順序」執行多個 Promise

  5. 知道如何使用 async/await

16. 深入理解 JavaScript 與瀏覽器相關機制

在前面我們學了比較多的工具,使我們可以利用它們打造出自己的產品。但除了工具以外,背後的原理也是很重要的。學習原理以及一些比較底層的概念,會讓你對這些技術更有信心,在發生問題時你能想到的地方也更多。

舉例來說,有時候碰到的問題可能跟 JavaScript 本身沒有關係,而是瀏覽器的運行機制導致這樣的結果。如果完全都不知道瀏覽器做了什麼,那可能會一直糾結在「問題一定出在這邊!」,但事實上根本不是。

這邊推薦的學習資源是 How Browsers Work: Behind the scenes of modern web browsers,裡面可以看到現代瀏覽器的執行方式。

還有 Chrome 滿 20 歲時所推出的 Inside look at modern web browser 系列,都能夠大大增進你對於瀏覽器的理解。如果英文不好,上面這些文章都可以找到非官方的中文翻譯版本。

最後也推薦一堂 Google 在 Udacity 上開的課:Website Performance Optimization,裡面會提到瀏覽器解析 HTML 的過程以及載入資源的順序等等。

至於 JavaScript 的部分可以從一些常見的問題下手,例如說 closure、scope、this、hoisting 等等,都是常見的關鍵字。

這邊推薦俗擱大碗的 JavaScript: Understanding the Weird Parts,也推薦 You Don’t Know JS 以及我自己之前寫的五篇相關文章:

  1. 該來理解 JavaScript 的原型鍊了

  2. 深入探討 JavaScript 中的參數傳遞:call by value 還是 reference?

  3. 我知道你懂 hoisting,可是你了解到多深?

  4. 所有的函式都是閉包:談 JS 中的作用域與 Closure

  5. 淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂

學習理由

除了使用工具,你還要知道工具背後的原理是什麼。在發生問題時才能更精確地定位。

JavaScript 的部分我覺得對新手來說雖然有時候感受不出來,但它的確是重要的。很多時候新手會寫出相關的 bug 並踩到類似的問題,可是因為缺少了這些能力,所以不知道該如何找出問題在哪,也不知道怎麼 debug。

學習目標

  1. 知道什麼是作用域(Scope)

  2. 你知道 Hoisting(提升)是什麼

  3. 你知道 Hoisting 的原理為何

  4. 你知道 Closure(閉包)是什麼

  5. 你能夠舉出一個運用 Closure 的例子

  6. 你知道 Prototype 在 JavaScript 裡是什麼

  7. 你知道大部分情況下 this 的值是什麼

17. gulp 與 webpack

當專案變得越來越大以後,可能就會需要一些工具來輔助開發。

gulp 能夠管理工作流程,可以用 gulp 來執行一系列的任務,例如說:

  1. 把 SCSS 轉成 CSS

  2. 壓縮 CSS 檔案

  3. 把 ES6 用 babel 轉成 ES5

  4. 壓縮 JS 檔案

  5. 把 HTML 裡面的圖片都換成 webp 格式

gulp 就只是個工作流程管理器而已,以上的功能都要額外安裝對應的 plugin 才能成功使用。

而 webpack 則是截然不同的東西,它是打包工具。以前瀏覽器原生並不支援在 Node.js 裡寫過的 import 與 export 這些語法(現在已經支援了),因此必須找一個打包工具來做這件事,webpack 的目的之一就是這個。

但除了這點以外,它把「打包」這件事情看得更廣,所有東西都是資源,不只有 JS 檔案。只要是資源都可以被 webpack 打包,在打包的過程中也可以透過 webpack 的 plugin 做一些事,例如說把 SCSS 轉成 CSS 或是壓縮 JS 檔案之類的。

會把兩個放在一起是因為這兩個常常被搞混,但我覺得可以很明顯看出他們本質上就是不同的。gulp 本身毫無作用,只是個任務管理員,真正的重點是底下執行了什麼任務;webpack 就是個打包工具,可以把你的前端專案打包起來,在打包過程可以順便利用 plugin 對資源做一些轉化。

如果你真的有理解這兩個東西,就會知道 webpack 也可以當作 gulp 的其中一個 task 來執行。

學習理由

為什麼要學這兩個東西呢?gulp 我覺得其實不學也行,但概念不難而且門檻不高,學一下也是很不錯的。而且會常常跟 webpack 搞混,學一下之後比較能解釋跟 webpack 的異同。

真正的重點其實是 webpack,我認為理解 webpack 在幹嘛是進入現代前端開發的重點之一。因為那些前端框架幾乎都使用了 webpack 來打包,如果不學 webpack 的話,你就永遠搞不懂它們在幹嘛。

學習目標

  1. 知道 gulp 的目的以及原理

  2. 知道 webpack 的目的以及原理

  3. 熟悉如何使用 webpack 進行模組化開發

  4. 熟悉如何使用 gulp 建構自動化工作流程

18. 物件導向

物件導向這個東西我真的不太知道要放在哪裡,只好放在框架前面了。

其實在前面的過程中就可以慢慢培養物件導向的概念,例如說使用 XMLHttpRequest 或是使用 Promise 的時候,就有物件導向的概念在裡面。

這邊需要去學習物件導向的基本概念,以及如何使用 ES6 的 Class 語法還有繼承。有時間的話也可以學 ES5 的 prototype,畢竟 JavaScript 是 prototype-based,Class 只是語法糖而已。

物件導向如果真的要學,可以學的東西很多,開始學的時候會先被一大堆新名詞給淹沒,但建議先學一些比較常見或是在 JavaScript 比較常用的就行了,像是繼承(Inheritance)跟封裝(Encapsulation)。

至於多型(Polymorphism)或是多載(Overloading)這些都可以先放著,稍微看一下有個概念就好,未來有機會的話再去深入學習。

學習理由

下個部分要進入到前端框架了,在學習前端框架以前必須要有物件導向的觀念,不然有一大堆用法你會看不懂在幹嘛。

學習目標

  1. 知道什麼是 Class

  2. 知道 Class 與 Instance 的區別

  3. 知道什麼是 super()

  4. 知道如何使用 ES6 的 Class,能夠寫出簡單的物件導向程式

  5. 知道什麼是繼承(Inheritance)

19. React/Vue/Angular 三選一

前面學了這麼多東西,這個學習路線也漸漸接近尾聲,終於到了學習前端框架的時候(React 嚴格來說不算是框架,但它跟整個生態系合起來我覺得算是一個框架,所以就稱它為框架了)。

在學習的部分,三大框架 React/Vue/Angular 可以選一套來學就好,Vue 好像比較容易上手,但我只會 React 而且我推薦 React。我完全沒用過其他兩套,推薦學 React 只是因為我比較喜歡它(對,是個很薄弱的理由)。

React 的學習資源我推薦從 React 小書開始,是我認為不可多得的資源,前四個 lesson 是精華,不直接教 React 卻讓你學會 React。看完之後可以看官方教學,內容也很豐富。

前端框架的部分要掌握核心概念以及基礎用法,以 React 來說,核心概念就是:state 對應到 UI,你要改變 UI,改變 state 就好。UI 只是 state 的呈現,所以基本上你不會直接動到 UI,而是改變 state,再讓 React 幫你重新繪製 UI。除此之外,Component 跟 JSX 也是滿重要的觀念,React 的幾個生命週期也必須好好搞懂。

總之呢,進入到現代的前端開發以後我覺得就差不多了。如果上面講的都有好好學的話,你在我心目中已經是個基礎不錯的網頁前端工程師了。

學習理由

為什麼要把前端框架放那麼後面?

因為我覺得學習這些前端框架是必須要有基礎的,沒有基礎的話只會死得很難看,根本不知道在學什麼。至少要能熟練的使用 JavaScript 以及理解物件導向,還要會一點基本的 webpack,最後才來學前端框架。

我認為框架本來就不是給新手用的東西,請先把基礎打好再來學框架,這樣才叫事半功倍。直接學框架是事倍功半,請一步一步來。有很多新手太早學框架,導致於碰到問題時不知道是框架的問題還是 JavaScript 本身的問題,這就會被我稱作是基礎不穩。

學習目標(以 React 為例)

  1. 知道 React 的目的以及原理

  2. 知道我們為什麼需要 React

  3. 知道使用 React 跟之前使用 jQuery 的區別

  4. 理解 state 跟 props 的不同

  5. 熟悉 React 基本操作

結語

學的東西很多嗎?不少,但這只是個開始而已,還有很多主題我沒提到呢。

上面這些只是我認為的基礎而已,從每一項基礎都可以再延伸出許多更深入的議題,例如說 React 專案越來越大之後就會遇到一些狀態管理的問題,延伸出 Redux 以及一些 Redux middleware。

或者是 CSS 越寫也會越複雜,會接觸到一些 CSS 方法論如 OOCSS、SMACSS、BEM 以及 Functional CSS。

我還沒有提網頁效能優化呢,像是從伺服器端的 gzip、Cache、CDN、HTTP/2 再到前端的 lazy loading、圖片壓縮、PRPL Pattern 或是 code splitting,有太多太多東西可以學習以及研究。

成為一個網頁前端工程師容易嗎?

看你自己對這個職業的標準是什麼。如果你只是想要找到一份職稱為「網頁前端工程師」的工作的話,以現在的情況來說我覺得沒有很難。就如同我開頭所說的,若是以快速求職為導向,很多我提到的東西都不需要學。

但若是你想把基礎打得好一點,讓未來的自己能走得更順遂一點,那當然不是件容易的事。想要成為工程師很容易,但想要成為基礎紮實的工程師就是另外一回事了。

希望這份落落長的清單能對想要學習網頁前端或是想加強自己網頁前端基礎的人有幫助。

最後,感謝幫我先看過文章並給予建議的朋友們。

淺談新手在學習 SPA 時的常見問題:以 Router 為例 深入 Session 與 Cookie:Express、PHP 與 Rails 的實作

評論