AppWorks School Batch #16 Front-End Class 學習筆記&心得(駐點階段一:指定練習專案:STYLiSH)


Posted by ralphhong5465 on 2022-09-12

AppWorks School 的駐點集訓真的很充實,之前自學要花上一個月才逐漸有概念的內容,這裡要在三天內就會實作,每天都在徬徨、崩潰、平復、滿足、掙扎的循環中度過,所幸,身邊有許多一起共患難的夥伴,前行的路上一點也不孤單。

短暫的甜蜜期~開學典禮

遠距教學結束後有兩天的短暫假期,但這兩天我實在沒什麼心情放假,因為第四週的遠距作業都已經過繳交期限,依然還是還寫不出來啊!

經過一番摸索、嘗試,總算在開學前一天,交出結果正確、卻不知其所以然的作業,但至少可以沒有掛念去參加讓人期待又有些緊張的開學典禮了!

AppWorks School 在不久前才搬家,從信義區的 7-Eleven 必成門市樓上搬到仁愛新生路口的福記大樓。因為開學典禮與當初面試的場地不同,讓我對未來幾個月生活的地方充滿更多想像。雖然活動十點才開始,九點未到我就已經抵達,在大略認識週遭環境後,在校務人員的許可下,成為最早進入活動場地的學員。

第 16 屆的報名與面試在去年十二月進行、今年 1 月 12 日放榜,遠距則是在 3 月 21 日開始,但唯有坐在開學典禮現場的此刻,才深刻感受到在 AppWorks School 的生活已經正式開始。校長 Shirney 跟我們簡短說明了未來幾個月的課程安排,相關內容跟招生說明會講的差不多,而更重要的是,校長也給我們做了「心理建設」。

學習程式一般會分為四個階段:蜜月期(hand-handling honeymoon)、下滑期(cliff of confusion)、絕望期(desert of despair)、上升期(upswing of awesome)。對於多數 School 的學員來說,參加駐點集訓會是「下滑期」的開始,因為強度很高、也不再有人手把手教學,信心受挫是常有的事,這時身邊同學就是很珍貴的資源,校長鼓勵我們多跟同儕互動,少當「自幹王」。

因此,在校長與校務、導師們簡短致詞後,我們有超過一個小時的時間破冰。因為報到時並沒有依照班別入座,此時一大任務就是找到自己班的同學,畢竟在遠距時當了一個月的 Discord 網友,現在總算能見到同學的廬山真面目。School 訂了披薩、炸物、烤雞翅等當午餐,讓我們能跟同學邊吃邊聊。

開學典禮的午餐

School 接著為我們進行簡單的環境導覽、並設定打卡機的指紋資料,最終才抵達未來數個月要待上最長時間的大教室,然後就要面對第一天的作業啦!

這天要做的事情很簡單,就是完成 GitHub 環境設定,了解如何發送 pull request (簡稱「發 PR」)繳交作業、並在導師完成合併後同步(sync)到自己的本機。記得遠距時完全搞不清楚如何用命令提示字元操作 GitHub 與本機間的關係,甚至作業還都用上傳的方式放上 GitHub、有錯再直接於 GitHub 修改程式碼,完全不是一般開發人員使用版本控制、協作專案的方式,在駐點教學這天,我終於搞懂了整個流程。


第16屆駐點集訓貼文(取自 AppWorks School Instagram

震撼教育~STYLiSH 電商網站專案練習

相較於許多培訓單位都是在課程尾聲才開始做專案,School 在駐點教學的頭三週半就要讓每位學員都做出一個名為 STYLiSH 的電商網站,而專案的開始也就代表著蜜月期的結束,這不過是開學典禮的隔一天。


STYLiSH 網站成品外觀

學習內容

每個班別的進度安排都不太一樣,對於前端班來說,共有下列五大重點:

  1. 切版:能夠使用 HTML 搭配 CSS 刻出設計圖給的網頁外觀,並依照響應式網頁設計(RWD)概念,做出符合不同螢幕寬度的畫面。
  2. 用純 JavaScript 實現功能:熟悉文件物件模型(DOM)的操作,搭配回呼、迴圈、條件判斷、AJAX 等,讓使用者得以跟網頁進行互動。
  3. React:在純 JavaScript 之外,以更被普遍使用的前端函式庫 React 實現網頁功能。
  4. 串接第三方服務:使用第三方軟體開發工具組(SDK),直接引入會員登入、登出與付款功能。
  5. 優化與部署:使用 ESLint、Prettier 等套件,讓程式碼更簡潔、易讀、易維護,並進行 SEO 優化等,最終部署到 Firebase

記得剛開始切版時,大家就不斷哇哇叫,因為網頁版與手機版的細節有諸多不同之處,光要構思基本的 HTML 架構就足以讓人傷透腦筋,導師還會將我們刻出來的網頁與設計圖相疊比較,只要有明顯的殘影就會被退回,每個人都盯螢幕盯到眼睛快要脫窗。


奮戰中的我們

但當我們進入用 JavaScript 實現功能的環節,卻又變得非常想念切版,跟直接刻畫面相比,要構思如何用程式碼寫出目標功能更為燒腦,這部分要做的功能可不是只有「點選某個按鍵後改變顯示內容」這麼簡單,要做出輪播圖、根據使用者選擇跟 API 資料比較並顯示對應結果,每個項目都需要許多步驟搭配才能完成,常常想了老半天還是沒有任何進展,上網查到相似功能的程式碼、卻發現怎麼看也看不出個所以然,最終還是要自己想或跟同學討論出解法。


就算不在 School,也在咖啡店一起努力的我們

到了 React 後,又是另外一個世界,因為 React 的重點觀念環繞在 props 與 state,跟純 JavaScript 非常不同,要如何用另外一種思維實現網頁功能又是一番考驗,而到了最後面的串接第三方服務,還要理解 JSON Web Token (JWT) 認證機制、並根據認證結果處理不同對應方式。新觀念這麼多,做到後來真的不知道自己在寫什麼,只能東貼西貼,這邊改一點、那邊改一點,寫出可以跑、但卻不見得清楚每段內容實際意義的程式碼。

至於最後的優化呢?除了極少數大神有做完這部分外,多數人不是做一點點就是連碰都還沒碰,於是乎,我們先前寫出那些可以實現功能的程式碼,其實就是一坨垃圾,不僅沒有符合 DRY (Don’t Repeat Yourself) 原則,變數命名、架構安排等都是一團亂,如果真的要套用 ESLint 中的 airbnb 規則檢查,出現數百個不合規範之處是很正常的事。

/* 完全不符合DRY原則的程式碼 */
const webMinusButton = document.querySelector(".web-minus");

const mobileMinusButton = document.querySelector(".mobile-minus");

const webPlusButton = document.querySelector(".web-add");

const mobilePlusButton = document.querySelector(".mobile-add");

if (webMinusButton) {
  webMinusButton.addEventListener("click", (e) => {
    let currentValue = e.target.parentElement.children[1];
    if (currentValue.textContent >= 1) {
      currentValue.textContent--;
    } else if (stock === undefined || colorInHex === undefined) {
      currentValue.textContent = 0;
    } else {
      currentValue.textContent = 0;
    }
  });
}

if (webPlusButton) {
  webPlusButton.addEventListener("click", (e) => {
    let currentValue = e.target.parentElement.children[1];
    if (currentValue.textContent < stock) {
      currentValue.textContent++;
    } else if (stock === undefined || colorInHex === undefined) {
      currentValue.textContent = 0;
    } else {
      currentValue.textContent = stock;
    }
  });
}

if (mobileMinusButton) {
  mobileMinusButton.addEventListener("click", (e) => {
    let currentValue = e.target.parentElement.children[1];
    if (currentValue.textContent >= 1) {
      currentValue.textContent--;
    } else if (stock === undefined || colorInHex === undefined) {
      currentValue.textContent = 0;
    } else {
      currentValue.textContent = 0;
    }
  });
}

if (mobilePlusButton) {
  mobilePlusButton.addEventListener("click", (e) => {
    let currentValue = e.target.parentElement.children[1];
    if (currentValue.textContent < stock) {
      currentValue.textContent++;
    } else if (stock === undefined || colorInHex === undefined) {
      currentValue.textContent = 0;
    } else {
      currentValue.textContent = stock;
    }
  });
}

會的永遠不夠用

這三個半禮拜下來,真的深深感受到要學的很多、自己會的卻非常少。遠距教學期間觀看的 TreeHouse 授課內容,在 STYLiSH 專案中完全不夠用,需要在實作的過程中另外找資料學習,例如下列內容:

  1. Intersection Observer API:可實現惰性載入(infinite scroll / lazy loading)。
  2. Location:相關屬性可取得 URL 相關資訊、並實現頁面跳轉等功能。
  3. localStorage:讓使用者將暫存資料放在本地瀏覽器中,必要時可再將其取出使用。
  4. React:useEffect、useRef 等 Hook。
  5. 版本控制:使用 git rebase 功能,在舊的進度未合併前就可以開新分支進行下個階段的作業。

也有部分內容在遠距時期是學到舊的方法,但實作專案時多半會改用現今更普遍的新方法,例如下列內容:

  1. 打 API:遠距時學 XMLHttpRequest (XHR)、駐點後多使用 Fetch API,有時搭配非同步函式 async、await;另有同學使用 axios。
  2. 用 React 操作 state:遠距時只學到用 class 元件處理、駐點後改用 function 元件的 Hook 功能。

每天要學習的新觀念很多,在有作業進度壓力的情況下,我們無法每個細節都花時間摸熟,常常都是當下能夠實現功能就好,但做久了也會發現哪些工具會重複使用,自然就會去多花些時間鑽研。

找到自己的學習步調

實作專案期間,每個人的程度落差非常明顯,就像在學校一樣,大致可以分為五種類別:

  1. 學神:唯一有辦法在每天晚上六點以前繳交當天進度,甚至提早合併、可以超前進度的大神,還能有餘裕協助其他同學、並有空閒時間安排其他娛樂活動。
  2. 學霸:進度通常不會落後超過一天,不用太多協助就能自己把作業寫完,一樣常化身小助教,學神在忙時要問問題必定首先想到這些人。
  3. 學民:進度落後約兩天,需要大量協助才能完成作業,通常覺得自己是學渣,殊不知其能力還勝過班上近半的同學。
  4. 學弱:進度落後三天以上,全班其他同學都可以是這些人的助教,常常是以上三種人交的作業都合併了、他們的 PR 還沒有發。
  5. 學渣:作業不會寫也不想努力,完全擺爛狀態,但進 School 要經過篩選,這種人幾乎不存在,不過上述四種人通通會把自己歸為此類。

至於我是哪種人呢?嘴巴上當然會說自己是第五種,實際上是...第四種,我認真沒在謙虛,是真的全班進度最慢那種!常常看著同學交的作業都已經合併了,我卻還是沒什麼頭緒,試著看同學寫的作業當作參考,卻因為看不出個所以然而越來越慌,最後躺在床上翻來覆去睡不著,曾在某個夜晚 12 點就躺平、到快天亮才睡著,兩個小時後再次起床前往 School 進行當天的課程。


這張圖有略為誇大,但感覺差不多就是這樣

進度落後的代價就是每天晨會只要講到作業進度、或者同學在群組討論作業內容,我就完全聽不懂、看不懂,都得過兩天、寫到同樣進度時再回去看,才恍然大悟:「哦!原來當初講的是這個!」。很想再聽一次講解,可惜已經晚了,其他同學已經在討論後面的進度。


每天早上的晨會(recap)

說不沮喪是騙人的,這三個多星期來不知道經歷多少心煩意亂的時刻,但我後來想想,其實「用相同的時間間隔落後」,代表我跟大家的行進速率是一樣的呀!只是最開始的進度不知道為何有拖到,才會導致後來每天的進度都穩定落後同學兩天,最後其實也都有陸續完成每天的作業,沒有跟同學進度越差越遠的情況,這樣想或許能讓自己好過一些、不會再失眠。導師也不斷跟我們進度偏慢的人說:跟自己比,不要跟別人比,只要自己也有在前進,就是有進步。

心得

打從學測考完開始,我從來沒有這麼高強度接收新知過,或許是太久沒有認真唸書的緣故,面對新挑戰時快速找到資源、消化資料、擬定並施行解決方法的能力大幅下降,現在要找回當初高中曾經有的能力,是會吃力一些,但相信只要持續不間斷地學習,狀況會越來越好的。

校長 Shirney 每週都提供一對一對談時間,我身先士卒成為全屆第一位使用此服務的學員。在約半小時的對談中,校長提到的一個重點令我印象非常深刻:要學會看「文件」。回顧過往學習軟體技術相關知識,文件永遠是最後看的項目,看文件前必先找教學影片、部落格的技術文章等,倒也不是不信任文件,而是文件就算寫繁體中文也完全看不懂!追根究柢應該是底子不夠紮實、無法觸類旁通所致,需要持續靠高頻率接觸相關領域知識、慢慢體會工程師寫文件的邏輯。

軟體技術更新很快,現在精通的工具或許過不到兩年就被認為已經過時,因此,現階段的最大重點是「找到學習方法」,每當有新的技術或觀念推出,工程師們得要在最短的時間掌握,而文件必定在教學影片與技術文章之前推出,我想,這就是校長會強調要「學會看文件」的原因吧!

新的進度開始了,想必又將是不輕鬆的過程,但我們有一群戰友一起前進,有夥伴們一起奮戰的感覺,真好!

五月的第二個週日前,School 也準備了精美的母親節卡片給每一位學員,不管是自己或是媽咪,都覺得好暖、好溫馨。


母親節卡片(取自 AppWorks School 臉書貼文


#AppWorks School









Related Posts

JavaScript 執行環境與作用域

JavaScript 執行環境與作用域

CS50 HTTP (Hypertext Transfer Protocol)

CS50 HTTP (Hypertext Transfer Protocol)

Linux小技巧暨問題集

Linux小技巧暨問題集


Comments