如果你是個毫無基礎又想要轉職成前端工程師的迷惘初學者,你腦中浮現的第一個問題有八成會是這個。接下來你會做什麼?你大概會用:「如何成為前端工程師」、「前端 入門」、「前端 轉職」、「前端 非本科」等等的關鍵字來搜尋,然後呢?
然後我希望你能搜尋到我這一篇,讓我來好好告訴你。
有鑒於上一篇(如果你還沒看過的話:跟著小明一起搞懂技術名詞:MVC、SPA 與 SSR)的反應出乎意料的好,因此這次還是由小明出馬,由一段虛構的故事慢慢帶你看前端工程師到底需要會哪些東西,故事看完了,你也差不多知道你到底該學什麼了。
這篇文章的目標是你沒什麼程式基礎也能夠看得懂,比上篇的門檻再低一點。故事情節的發展順序不一定代表真實世界中這些技術出現的順序,順序的安排只是因為我覺得這樣子能幫助初學者更好理解這些技術到底在幹嘛。
好,讓我們開始吧!
在很久很久以前…(真的很久)
那時候小明 12 歲,正在唸小學六年級。在上電腦課玩著世紀帝國的時候(how do you turn this on?),老師突然宣布學校有舉辦班級網頁設計比賽,優勝者可以獲得十個好寶寶章。
身為一個從小學二年級就開始用電腦的人,小明自認為對電腦操作都很熟悉,心想網頁應該也不難,就決定接受這個挑戰。並且在回到家之後 ,上了奇摩知識+發問:
[急]請問要怎麼寫網頁? 求解 20 點
底下熱心的網友們給了他兩個關鍵字:FrontPage 跟 Dreamweaver,並且跟他說寫網頁其實很簡單,這兩個軟體提供了很多現成的元件,你就想成是在打一份 word 文件就好,只是你可以加上按鈕、表單等等只有網頁會出現的東西。你只要用拖拉的方式,就能夠很輕易地寫出一個網頁來。
就如下圖所示,你可以立刻看到你的網頁長什麼樣子:
雖然搞不太懂是怎樣一回事,但小明試用了一下這兩套軟體,發現寫個網站還真的很容易!就跟編輯文件一樣,你想要編輯什麼文字你就直接改就對了,要圖片的話也可以很輕鬆的直接插入。
一直到小明長大後才知道,原來這種編輯模式就叫做「所見即所得」,你看到編輯器裡面長什麼樣子,實際上的網頁就會長成那個樣子(英文叫做 WYSIWYG,What You See Is What You Get)。
經過一番摸索之後,小明完成了班網的雛形:
「才一個下午我就可以做成這樣,再給我三天,我應該可以拿優勝吧」樂觀的小明自覺前途一片光明,想說今天也累了便先去洗洗睡了。
他不知道的是,坎坷的未來正在等著他。
與網頁本人的初次見面
隔天放學回家,小明打開電腦想要繼續做班網,可是卻發現 FrontPage 怎麼樣都打不開,重開機、重新安裝都沒有用,就只差重灌了。可是重灌會把即時通的歷史記錄全部都洗掉,母湯母湯,到時候小美傳給他的訊息就都不見了,這可不行。
束手無策的小明,看著昨天用 FrontPage 產生出來的 index.html,不知道哪來的靈感,對它點右鍵,選了「以記事本開啟」,看到了驚人的畫面:
「這是什麼碗糕!」整個畫面上,小明只看得懂中文,其他的根本不知道在寫些什麼。
原本小明想把視窗關掉,可是卻轉念想說再看一眼好了,而這一看卻讓他發現了一些規律:
<xxx>
似乎都是成雙成對出現的,有<xxx>
就會有</xxx>
- style 看起來好像跟背景顏色之類的樣式有關
觀察到規律之後,小明心想那不然我來改改看,看會發生什麼事情好了。於是他就把 <li>通訊錄</li>
複製了幾次並且改成其他文字,也把 body 那邊的 background 換成 #666666。
接著存檔,不用記事本而是用網頁來打開,小明看到了下面的景象:
「哇!居然還真的改了!」
一直到日後小明去書店翻書才知道,原來網頁本人其實就是那個用記事本打開的文字檔,而 FrontPage 在做的事不過就是自動幫你產生這些文字而已。而那些成雙成對的<>我們叫它標籤,不同標籤有不同的用途。
舉例來說,<li>
就是 list item 的意思,而標籤裡面放的就是你的內容。至於 style 則是人如其名,負責管理所有跟樣式有關的操作,background 就是背景,color 就是文字顏色。
這些標籤跟內容我們叫它 HTML(HyperText Markup Language),那些樣式叫做 CSS(Cascading Style Sheets),這就是構成網頁最基本的兩大元素。
知道網頁原來是由文字組成,不一定要用現成軟體才可以寫出來之後,小明便拋棄了 FrontPage,跑到書店買了幾本網頁入門的書,下定決心從基礎學起。
不到半個月,他就已經可以只靠文字編輯器來寫出整個網頁。
我也想要華麗酷炫的功能
得意洋洋的小明覺得同年齡一定沒有人像他這麼認真參加這個比賽,看來要拿到第一名是輕而易舉了。如此天真的小明,有天碰巧看見隔壁班的小華在請教電腦老師一些網頁的問題,便湊上前去看。
不看還好,一看驚為天人,兩千四百萬人都驚呆了。
首先呢,網頁上面有一個計數器,可以顯示一共有多少訪客曾經造訪過這個問題。再來,你的滑鼠附近會有一圈文字,滑鼠移到哪裡文字就跑到哪裡,超級酷炫!還有網頁跑馬燈會不斷輪播班級的公告,就跟實體的跑馬燈效果一樣。
意氣風發的小明在那一刻啞口無言,深深覺得自己只是隻井底之蛙,不知道外面的世界有多大。花了一些時間整了好自己的心態以後,小明鼓起勇氣問了隔壁班的小華:「欸欸,你那些效果怎麼用的,可以教我嗎?」
『很簡單啦,你去搜尋:網頁建置百寶箱,那裡真的是百寶箱,要什麼有什麼!根本就是網頁設計師的哆拉 A 夢』
回到家以後小明照著做了,果真發現一片新天地,那裡充滿著各式各樣的酷炫功能跟效果,你只要把一段文字複製貼上到你的網頁就能夠起作用。小明選了幾個自己覺得很帥的效果,改造了一下班網:
可是,如果只是複製貼上的話,是贏不過小華的!必須要以這些特效為基礎自己再客製化,才能夠殺出重圍,驚豔到學校的評審老師們。
秉持著這樣子的決心,小明仔細看了一下貼到網頁的那些文字,希望能發現一些端倪:
雖然看不太懂是在做什麼,但小明心想:「這應該就是寫程式吧」,透過一些程式碼來操控 HTML 上面的元素,產生出會震動的圖片的效果。
上網查了一些資料之後,小明才發現原來這個程式語言叫做 JavaScript,能夠操縱網頁上面的東西,只要是看得到的地方都可以用它來操作。所以理想上能做出任何你想得到的功能。
以上面的圖片震動功能來說,就只是用 JavaScript 寫了以下程式碼:
- 當滑鼠移上圖片的時候
- 開始震動(震動原理:不斷改變它的位置)
- 當滑鼠移開的時候,停止震動並恢復位置
知道原來可以用 JavaScript 做出這麼酷炫的事情之後,沒有理由不把這個學好。於是小明就到書店找了幾本相關的書籍,從最基本的那些變數、迴圈、判斷式開始學,希望有朝一日能夠寫出屬於自己的程式碼。
過了兩個禮拜,小明順利的實作出以下功能:
- 封鎖右鍵(原理:偵測到按下滑鼠右鍵時就刻意不做任何事)
- 顯示日曆(原理:靠程式碼抓出現在時間並顯示出來)
- 顯示歡迎文字(原理:網站載入完成時就跳出一個視窗)
而憑藉著這些小明手寫出來的功能,順利獲得了班網評審老師的一致讚賞,使得他拿到了班網比賽的第一名,把十個好寶寶章輕鬆納入口袋。
原本就不謙虛的小明在奪冠之後變得更加狂妄,在即時通的狀態寫說:
哈!網頁不過就這樣嘛,就是 HTML 做內容,CSS 做樣式,JavaScript 加程式碼,只要會這三個就好,太簡單了吧!
是的,其實網頁一直到今天還是如此,依舊是以這三者為核心在發展。可是當原生的東西跟不上前端的演進的時候,我們就必須先依賴一些第三方的工具,才能幫助我們更有效率。
於是長大了以後
在拿到班網比賽冠軍之後,小明就發現自己對網頁設計真的很有興趣,於是回家之後手裡拿的再也不是 GBA,而是 Introduction to Algorithms,噢不對,是「第一次寫網頁就上手」、「100 個酷炫的 JavaScript 網頁特效」等等的相關書籍。
升上國中之後,他依舊努力不懈,靠著課餘時間進修網頁設計,對網頁三劍客(HTML、CSS 與 JavaScript)的掌握度也愈來愈高,自大的小明想說他應該已經是世界第一等的水準了,是該出去外面的世界闖闖,就跟父母說他想要嘗試看看接案,拜託他們問問看朋友們有沒有適合的案子。
把案子交給一個國中生跟交給一個專業的工作室,雖然前者的確也有可能很厲害沒錯,但從公司的角度來看,還是會傾向把案子交給後者,畢竟接案不單單只有「寫程式」這件事情,還有開會討論、報價等等的流程。
可是皇天不負苦心人,得來全不費工夫,終於在國二的時候,小明接到了人生中第一個案子。
這案子是一個公司官方網站的建置,圖片素材跟設計稿都由他們提供,小明只要負責把網頁寫出來就好,並且用 JavaScript 來實作一點特效。
小明雖然只是個 junior student,但自認為是 super junior,花了兩個禮拜的時間就把版面切好,帶到公司去跟對方 demo。案主起初相當滿意,但卻問了一個小明從未想過的問題:
你有在其他瀏覽器上面看過這個網站嗎?舊版 IE、FireFox 或是 Safari?
沒有,小明從來沒有考慮到,他甚至連這世界上有這麼多瀏覽器都不太清楚。而案主當場把他自信滿滿的作品用其他瀏覽器打開,第一個跑版、第二個跳出警告、第三個連畫面都跑不出來,直接白畫面顯示 JavaScript Error。
這件事情對小明的影響很深,很深。
從那一刻開始,他才知道世界比他想像中的大很多。在自己的電腦上可以跑,不代表在別人的電腦上也可以跑。寫網頁不只是自己可以看就夠了,也要保證其他人看到的能夠跟你一樣。
站在巨人的肩膀上
回到家針對不同瀏覽器測試之後,小明發現很多 CSS 跟程式碼都必須對不同的瀏覽器做出調整才行,例如說在 safari 上面,可能要加上特別的 prefix 才能夠正常運行。
而 JavaScript 也是一樣,不同瀏覽器可能會有不同的 function name,要針對每個瀏覽器寫出不同的程式碼。
針對 CSS 的問題,小明發現只有幾個屬性要調整而已,很快就調好了,可是對 JavaScript,卻發現這是一件極為麻煩的事情,有太多東西要加了,而且會把程式碼變得非常混亂。
正在焦頭爛額之際,有些已經在業界工作的網友跟他說:
你可以用 jQuery 啊!
得到了這個關鍵字之後,小明立馬去研究這到底是個什麼樣的玩意兒。噢對了,如果你好奇他怎麼跟這些網友認識的話,他們是在程式設計俱樂部還有藍色小舖認識的。
研究了兩天之後,小明發現 jQuery 就是俗稱的 Library,可是在這領域不會翻作圖書館,而是翻作「函式庫」,意思就是它提供了很多現成的 function,你只要用就好了,不用知道他到底是怎麼實作的。
這跟瀏覽器相容性有什麼關係呢?關係可大了,以前你要寫 30 行程式碼去相容不同的瀏覽器,現在你只要用一行程式碼,用 jQuery 提供的 function 就好,底層它都幫你做好相容了。
除此之外,語法也變得比較簡潔,一些常用的功能它都幫你先寫好了。jQuery 的知名特徵就是 $ 這個符號,把一堆好用的 function 都放在這個裡面。
下圖是 jQuery 與原生 JavaScript(又稱為 vanilla js)的比較,站在巨人的肩膀上以後,可以少寫很多行程式碼。
順利解決了瀏覽器相容性的問題之後,案主也很開心的把這個案子結掉了。擁有了人生中第一筆收入的小明,從此以後開始了他的接案之路。
Don’t repeat yourself
隨著案子越接越多,小明有一個非常困擾的問題,那就是 CSS。你知我知獨眼龍也知,很多案主喜歡把需求改來改去,早上說網站主色是藍色的好,下午說還是綠色吧,到了晚上又問說能不能改成紅色試試看。
而且不只顏色,可能網頁邊距啦,寬度啦,總之要一直改來改去的實在是很麻煩,而且很多時候還會改錯。
為什麼會改錯呢?因為可能網頁背景、按鈕、文章背景都是用紅色做為主色,所以最快的方法顯然是把所有的 red 都取代掉。可是有些顏色雖然也是紅色,但不是因為網頁主色是紅色,而是本來就應該是紅色,例如說錯誤提示的文字。這種就必須再改回來,不然會變得很奇怪。
因此,小明都是這樣改的:尋找、取代,再把改錯的改回來:
在改來改去的過程中,小明想起一句在這領域裡面很有名的一句話:Don’t repeat yourself。不要一直做重複的事情,像現在這樣就很不好,永遠要屈就於這種非常不方便的流程。
有沒有可能把程式的概念引入到 CSS 裡面去呢?例如說變數?這樣我們就能夠用變數來取代寫死的顏色,要改的話也很方便,只要改一個地方就好:
在業界工作的前輩們聽到小明的想法之後,就跟他說了:
這不就是 CSS preprocessor 嗎?
CSS preprocessor,翻成中文就叫做 CSS 「預處理器」,簡單來說就是你可以先寫一些不是 CSS 的語法,經過這個預處理器之後,就會變成符合標準的 CSS。
或是說得更白話一點,就是翻譯啦,你先寫中文,經過 Google 翻譯之後翻成日文,然後日本人就看得懂了。差別在於 Google 翻譯可能會翻的不精準,可是 CSS 預處理器能夠翻的超級精準,保證是標準的 CSS。
有了預處理器之後,你就可以把變數也應用到 CSS 上面,或甚至你要用迴圈或是函式也可以!總之呢,有了預處理器之後,寫 CSS 跟寫程式的感覺變得更相似了,下面是個簡單的範例:
最常用的預處理器有幾個:SCSS/SASS、Less 跟 Stylus,語法都很類似,基本上挑一個學就夠了,要轉去其他的也不難。有了預處理器之後,就能夠更有效率地去寫 CSS。
但如果你不用預處理器,可以寫網頁嗎?當然可以!只是業主要你一直改顏色的時候你可能會很崩潰而已。
還記得之前提過需要針對不同瀏覽器去調整 CSS 嗎?有些必須要加 prefix 才能運作。這點用預處理器也能夠很輕鬆地去解決,用一種叫做 mixin 的東西,你就想成是 function 就好:
原本在每個地方都要重複寫這些不同的屬性,現在把它包裝成 mixin,你只要 include 進來就好。
不過,小明有了一個疑問:
既然我們都知道這個屬性要加 prefix,為什麼不讓程式幫我們自動加上就好?
對啊,為什麼不?有個東西叫做 PostCSS,就是在做這件事情。(其實 PostCSS 包含了很多的 plugin,這邊提到的是其中一個叫做 Autoprefixer 的 plugin)
在這邊你要知道 PostCSS 跟 CSS preprocessor 的差別在哪,前者的 input 是 CSS,output 是加上了 prefix 之後的 CSS;後者的 input 是 SCSS(或其他),output 是 CSS。你甚至可以把兩者合在一起用:
合在一起用的好處就是你在寫 SCSS 的時候,完全不用管 prefix 這件事情,因為 PostCSS 都會幫你做好。
有了這兩項神兵利器以後,小明在寫 CSS 的時候就沒什麼太大的問題了,就算案主們的需求朝令夕改,也能夠憑藉著這些工具快速做出更動。而且長時間接案下來,已經累積了一套自己的程式碼,能夠迅速就搭出一個基本的頁面。
在不斷接案的過程中,小明也就這樣漸漸長大,轉眼間已經是個大一新生了。小明成長了,前端的世界也慢慢在成長,長成一個小明從未預料到的模樣。
像詩人依賴著月亮,像海豚依賴海洋
上了大學之後,小明開始挑戰接更大的案子,而更大的案子就意味著不再只是那些美美的公司形象網站,而是開始往更複雜、更多功能的方向走,例如說購物網站或者是 CMS 系統等等。
身為一個程式設計師,當你看到一個沒實作過的新功能時,第一件事情就是:上網去找有沒有人實作過。如果已經有人把輪子造出來了,大多數時候沒有必要自己重新做一個。
於是除了 jQuery 以外,小明開始用了其他的 Library 來解決問題,直接把別人寫好的功能拿來用。可是用著用著,小明發現了一個問題,那就是引入 library 的機制。
現在的機制是怎樣呢?就是直接引入每一個你要用的 library,然後直接用就行了:
看起來其實挺合理的,但會有幾個問題。
第一個,假如說 A.js 裡面定義了一個變數叫做:VERSION,而 B.js 裡面也定義了一個變數叫做 VERSION,那就會產生變數名稱衝突,兩個 library 互相干擾。
第二個,其實每個 library 本身也有可能使用到其他的 library,假設 A 用到了一個 library 叫做 popular,B 也用到了 popular,那我們這邊其實就把 popular 引用了兩次(因為 A 跟 B 都用到了,所以在引入 A 跟 B 的時候各引入一次)。
總之呢,污染全域變數跟 library 之間的相依問題讓小明豆頁很痛,怎麼看都很不順眼。在理想上,小明覺得這些 library 的使用應該要像其他程式語言那樣,例如說 Python:
簡單乾淨俐落,要用什麼 library,就用 import 把你要用的東西引入進來,也可以在程式碼裡面把 library 用不同的別名引入,或者是只引入特定的幾個 function。
雖然能這樣用一定很棒,可是 JavaScript 又不支援,怎麼辦呢?
咦?有沒有一種似曾相識的感覺?
如果 CSS 能用變數就好了,一定會很棒,可是 CSS 又不支援…
如果原生不支援,解法很簡單嘛,我們就假裝有支援,之後透過工具把它轉成原生的程式碼就好了。像 SCSS 就是這樣啊,反正轉換完之後是原生的 CSS,一定有支援。
於是呢,一個可以讓 JavaScript 支援這種引入機制的 Library 誕生了:
現在你可以直接在程式碼裡面寫:var A = require(‘libraryA’)
去引入一個 library,而不是用 <script />
標籤去引入。而背後的原理就是靠著 browserify 去幫你實作 require 這個函式,自動幫你處理好背後的相依性問題。
有了 require 的機制以後,在寫 JavaScript 的時候你就可以分成好幾個檔案來寫,最後再透過 browserify 把程式碼組裝起來:
最後透過 browserify,會產生一個 bundle.js,顧名思義,所有需要用到的東西都打包在裡面了,這就是你真正需要在 HTML 裡面引入的檔案。
這個要變、那個也要變,當我超級變變變?
雖然 browserify 成功解決了小明的問題,可是又有一個新的問題產生。截止目前為止,我們寫 SCSS,接著用指令把 SCSS 轉成 CSS。然後我們在 JavaScript 裡面開心用著模組,用 browserify 打包出 bundle.js。
儘管只是改一個小東西,就要打兩個不同的指令去做轉換,才能看到最後的結果。更別說要把這專案上線之前還要先對 CSS 以及 JavaScript 做混淆以及壓縮,把程式碼變得更像亂碼一些。
這些流程之後只會隨著需求越來越煩瑣,該怎麼辦呢?可能過一年之後一個專案有十幾個指令要執行,有沒有什麼好用的工具能夠處理這個呢?小明再次求助於認識的業界朋友們,最後得出了:Gulp 這個關鍵字。
Gulp 能夠用程式碼來管理你的 workflow,你就定義很多 task,說清楚每一個 task 要做什麼事情,然後再去執行那個 task 就好了,如下圖所示:
開頭定義一個 task 叫做 html,是來把 pug 檔案轉換成 html,第二個 task 叫做 css,用 less 轉換之後再 minify;第三個則是把 js 產生 sourcemap。只要你一打 gulp 這個指令,就會自動幫你執行上面三個 task。
有了 gulp 以後,當你拿到了一個陌生的專案,你直接去看 gulpfile.js 就可以知道這個專案應該要怎麼開始跑或是怎麼打包了,每一個 task 都清清楚楚寫在裡面。
以前我們需要自己手動打好幾個指令,現在我們用 gulp 轉換成一個個 task,只要一行指令就可以又用 SCSS 轉換成 CSS 又用 browserify 打包成 bundle.js,十分方便。
現在的小明已經不再是當年那個只會用 HTML、CSS 跟 JavaScript 寫著班網的小明了,而是手上握有 SCSS、PostCSS、browserify、Gulp、jQuery 等等工具的小明。有了這麼多工具輔助,在開發網頁的速度上面快了許多,因為每一個工具的目標本來就是讓你變得更有效率,而不是拖累你。
就在此時,小明看到一個令人振奮的消息:新一代的 JavaScript 語法出來了(嚴格來講是 ECMAScript),叫做 ES6,在這新語法裡面多了小明很期待的一些新功能。
不支援怎麼辦?你知道的 😏
既然是新語法,想必舊的瀏覽器不會支援。小明一路跟著前端發展過來,也大概摸清了前端的套路。什麼是前端的套路?
當你想用瀏覽器不支援的東西時,你就開發個工具來轉換就對了
SCSS 如此,browserify 亦是如此。小明知道 ES6 推出時已經是第三手的消息了,因此他深知一定已經有人做出這個工具了,上網搜尋了一下,Bingo!
這個工具就叫做 babel,它的官方網站簡單明瞭的說出了它的作用:
簡單來說就是你可以寫新一代的 JavaScript(儘管瀏覽器還不支援),再透過 babel 把它 compile 成瀏覽器支援的語法。概念跟 CSS preprocesseor 有點像,但最大的差異在於 SCSS 的那些語法不是「下一代的 CSS」,所以瀏覽器以後也不會支援那些語法;而新一代的 JavaScript 只是「現在」還沒被瀏覽器支援,有朝一日一定會的。
等到那天到來,你就可以把 babel 整個丟掉了,可是專案還是一樣可以正常運行(但那一天可能要很久就是了)。
用了 babel 之後,就可以用一些又炫又潮的語法,只是你必須要多一層手續,用 babel 來 compile 才能在瀏覽器上面執行。不過沒關係,因為我們有 gulp 了,所以只要在 gulp 裡面多增加一個 babel 的 task 就好了。
CSS 沒問題了,JavaScript 也有了模組化以及新一代的語法,都已經這麼前衛了,難道還有什麼東西可以再進化嗎?
靠北,還真的有。
你的資源,我全包了
前面提過了 browserify,讓你可以用 require 把 JavaScript 引入進來使用。有人覺得單純這樣還不夠,提出了一個瘋狂的想法:
為什麼只有 JavaScript 呢?為什麼我不乾脆把所有東西都視為資源?不只要引入 JavaScript,我也可以引入 CSS,甚至引入圖片!
這樣子一視同仁,把所有東西都視為是資源的想法,就是 webpack 的核心理念。我不只要 require(‘A.js’),我還要 require(‘style.css’), require(‘bg.png’)
只要是外來的資源,我全部都要引入!
webpack 用起來其實跟 browserify 很像,差別在於前者把更多東西都視為是資源,所以寫出來的程式碼會像這樣:
除此之外呢,webpack 也可以透過一個個的 plugin,在打包的時候對這些資源做一些事情。什麼事呢?例如說用 babel-plugin 把 ES6 轉成 JavaScript!或者是用 scss-plugin 把 SCSS 程式碼轉成 CSS。
意思就是你在寫 code 的時候,你甚至可以直接引入 style.scss,webpack 會自動幫你在引入時轉換成 CSS!聽起來很棒吧!
自從 webpack 嶄露頭角之後,browserify 就漸漸愈來愈少人用了,因為 webpack 可以做的事情又更多一些,而 gulp 的很多 task 其實也能被 webpack 取代(例如說 compile)。
但要注意的是 webpack 只是一個 module bundler,不是像 gulp 那種 task manager,其實你可以把兩者配在一起使用,就像我們之前把 browserify 當作 gulp 的一個 task 一樣,你也可以把 webpack 當作一個 task。
「呼,前端有了這麼多工具,應該很足夠了吧!」小明邊看著越來越多工具的專案邊感嘆著。
是的,工具差不多了,可是我們前面一直專注的都是在:新一代的語法跟模組化機制,完全忽略了前端變複雜以後最困難的問題之一。
如何讓 UI 跟程式內部的狀態同步?
如果你現在有個 Todo List 的 App,假設你的程式裡面有一個 array 叫做 todo_list,你這個 array 長什麼樣子,你的介面就應該要長什麼樣子,這樣就叫做 UI 跟程式內部的狀態同步。
難嗎?乍看之下沒那麼難,我們可以寫出以下的程式碼,在操作 todo 的時候同時操作 UI 以及程式內部的狀態:
雖然在專案規模小的時候還行,可是如果你的專案超級無敵大,這就變成是一件很困難的事了,因為你要能永遠保證這兩者是同步的。照我們現在的方法,假如你有個 function 忘記更改狀態,那你就 GG 了,之後的狀態都不會再同步了。
Google 針對這個問題的解法是:那我自動讓這兩者綁定好了,改變 state 就會改變 UI,而改變 UI 的話也會改變 state,這樣不就好了嘛!於是就有了 Angular 這套框架(我對 Angular 極度不熟,就只點到這了)。
而 Facebook 針對這個問題的解法非常非常非常直覺,真的非常直覺,是我認為從概念上最好理解、最簡單的一個解法:
阿就每次 state 改變的時候都重新渲染 UI 不就好了
你要刪除 todo,你直接刪除 state 的 todo,不用管網頁上的元件。你要新增也是一樣,完全不用管畫面上的東西,因為只要 state 一改變,整個 UI 就會改變。以這個概念來實作的話,大概會變成這樣:
有沒有很簡單?有吧!
要如何讓 state 跟 UI 一致?寫程式的人只要關注 state,每次都只改變 state,然後每改變一次就把整個 UI 按照現在的 state 重新畫出來,不就能確保兩者完全一樣了嗎?
聽起來很有道理,那為什麼以前的人沒想到呢?因為如果真的「每次都重畫」,其實會有效能問題,因為事實上你只要重畫一部分就好。但總之 React 解決了這個問題,讓你用起來像是全部重畫,實際上卻是只重畫必要的部份。
在學 React 以前,只希望你記得 React 的這個核心概念就好:只改變 state 就好,UI 就會自動跟著改變。
把這複雜的前端問題解決以後,小明對前端的掌握度又更高了一層。
初出茅廬
故事說到這,小明大學也畢了業,兵也當完了,退伍的隔一天便很興奮地投了履歷,過幾天後拿到了人生中首次的面試機會。想當然爾,他投的職缺是前端工程師。
整個面試的過程都很不錯,面試官很驚訝小明在這個年紀就能夠對前端有這麼多的理解,而且該會的他都會了。在面試的尾聲,面試官問了這個一句:「這麼多的工具,你不會覺得很煩嗎?你都怎麼學會的?」
只見小明回道:
不會啊,出現問題不是就要解決嗎?我也沒特別學,就只是覺得用了這些工具能夠解決我的問題罷了。
話說完,面試便結束了,而隔天下午小明就拿到了 offer。
「主管說你對程式的觀念很好,催促我一定要快點發 offer 給你。」,HR 是這麼跟他說的。
結語
為什麼前端對新手來說這麼複雜,這麼多工具要學?因為他們根本不知道前面發生這麼多事情阿,他們沒有經歷過這一段演變,怎麼知道為什麼要用這些工具?
工具的出現是為了把問題變得簡單,而不是變得更複雜。當你發現引入了工具卻讓你變得更沒效率,就應該好好思考你是不是根本不需要這個工具,而不是去怪工具不好用。
文章看完了,如果我寫得還不錯的話,你應該會理解 HTML、CSS、JavaScript、SCSS(CSS preprocessor)、PostCSS、jQuery、Gulp、Babel、Webpack、React 這些東西在幹嘛,而這些就是現代一個前端工程師會需要的技能組(React 可換成 Angular 或 Vue)。
小明身為一個從以前就做前端做到現在的人,知道每一個工具出來時要解決的問題。但身為現今 2018 才想要踏進前端的你,自然而然就會覺得前端怎麼這麼多工具這麼複雜。但其實不是的,如果有人能跟你講小明發生過什麼事,你應該就能對這些工具更了解。
為什麼、為什麼、為什麼!我一直再三強調你一定要常常問為什麼,你一定要知道為什麼這些工具會產生。當你知道背後的脈絡時,就知道工具其實是在幫助你,而不是在阻礙你。就會知道這些工具的出現有其必要性,就能夠更有個好理由去把這些工具給學好。
只希望這篇能幫助到一些初學者們更理解自己現在為什麼要學這些工具。如果有任何錯誤的話也麻煩不吝指證,感謝。
話說日後我有可能會推出線上教學課程,可能是前端相關或者是帶一點後端,如果你有興趣的話,可以追蹤 Lidemy 鋰學院粉絲專頁,或者是留一下 Email,若有什麼新消息的話可以即時收到通知。
(雖然不太可能)但如果有出版社覺得我可以寫而且寫得不錯,想要找我談一些合作的話,可以直接寫信給我:aszx87410@gmail.com。
若是你對前端相關文章有興趣,下面這一個系列文其實是我最早把這樣子的寫作及教學方式實現出來的實驗品,而最下面的文章則是實際示範前端工程師在找工作時應該要有的技能是什麼,別擔心,那些專有名詞你應該都知道是什麼了。