給非前端夥伴的前端知識學習引導

語言: CN / TW / HK

導讀

有些非前端夥伴希望介入一些前端的工作,可以參考本文,擬定一個初步的學習計劃。

  • 現代前端的本質

  • 前端工具鏈的脈絡

  • 參與基礎開發需要掌握的最小知識量

  • 介入實際開發工作的步驟

現代前端的本質

前端的原始 形態

所需知識:html(頁面元素) + css(頁面元素的樣式效果) + javascript(動態對元素增刪改查,動態調整樣式)

我們通過瀏覽器檢視頁面原始碼或者審查元素,可以直觀的體驗前端的原始形態。

示範

新建檔案hello.html,在編輯器中輸入下面的內容:

<!-程式碼片段1-->
<html>
<head></head>
<body>
<div id="root"> hello world</div>
</body>
<script>
setTimeout(()=>{
document.getElementById("root").innerHTML = "修改過後的 hello world"
},3000)
</script>
</html>

輸入完成後儲存檔案,在瀏覽器中開啟這個頁面,會發現頁面上會展示hello world,在3秒鐘後,頁面展示的內容變化為修改過後的 hello world。

通過上面的體驗,我們可以發現這樣的前端程式有兩個明顯的特點:

特點一:編寫的程式碼不需要任何額外的處理,瀏覽器馬上可以解析執行,程式只包含瀏覽器能識別的html標籤和js程式碼(為了程式簡潔,這裡沒寫css相關程式碼)。

特點二:如果要修改頁面上的內容,需要先直接操作DOM節點。舉個例子,如果我們從伺服器請求了一個很長的列表資料,我們需要手動根據這些資料建立不同的DOM節點,然後掛載到頁面中去。這個過程如果處理的好,可以效能優良的執行,如果處理不好極有可能產生效能問題,同時編碼複雜度會增加。

現代前端

所需知識:html + css/less/scss + javascript + (vue、vuex、pinia、 vue-router…)/react/angular + node + webpack/vite/rollup + babel + …

從所需知識來看,現代前端需要掌握大量的知識,下面我們以vue2.6為例(實際工作中很多舊專案用的還都是vue2.6,所以沒用vue3或react來舉例),實現一個和程式碼 片段1 類似的功能。新建檔案hello.vue,

輸入下面內容:

// 程式碼片段2
<template>
<div>{{textStr}}</div>
</template>
<script>
export default {
data(){
return {
textStr:'Hello World'
}
},
mounted(){
setTimeout(()=>{
this.textStr = '修改過後的 Hello World'
},3000)
}
}
</script>
<style lang="less" scoped>
</style>

注:實際上,用vue2.6實現程式碼片段1類似的功能,可以有很多種不同的寫法,但在實際工程專案實踐中通常是程式碼 片段2 所示的形態。

如果大家瞭解了html、css、javascript的基礎語法,會發現程式碼 片段2 雖然看起來和前端程式的原始狀態有幾分相似,但是實際上是不符合相關語法規範的(比如程式碼 片段2 中出現的template、less、{{textStr}}等內容,對於瀏覽器來說都比較陌生),換句話說,瀏覽器是不能識別程式碼 片段2 的相關程式碼,瀏覽器只能識別符合html、css、javascript語法規範的程式。

既然我們寫的hello.vue不能被瀏覽器正確識別,毫無疑問我們需要做一件事情:

將瀏覽器不能識別的內容,轉化為瀏覽器可以識別的內容

那我們需要轉化成什麼樣的內容,瀏覽器才可以識別呢?

答案其實很簡單,轉化成符合html、css、javascript相關語法規範的程式碼即可。以程式碼 片段2 為例,我們應該將程式轉化成下面兩種形式之一:

形式一:使用帶編譯功能的vue版本,程式內部會解析處理下面template所指向的內容

// 程式碼片段3
new Vue({
el:'#root',
template:'<div>{{helloTest}}
',
data(){
return {
helloTest: 'hello world'
}
}
})

注:這裡程式碼 片段3 的template對應了程式碼 片段2 中的template相關的內容,我們稱之為 模版 。vue在底層最終會將這些模版表示的元素轉化成真正的html元素。

形式二:提前進行編譯處理,將template轉化為render函式,只需要執行時的vue版本

// 程式碼片段4
new Vue({
el:'#root',
data(){
return {
helloTest: 'hello world'
}
},
render:h=>{
return h('div',{},[this.helloTest])
}
})

相較於程式碼 片段3 ,程式碼 片段4 中傳給Vue建構函式的引數中沒了template屬性,多了一個render函式,這個render函式就是由template轉化而來,在該render函式的底層,實際上會把模版所對應的內容轉化為對應的Javascript物件,我們稱這些物件為 虛擬DOM ,然後再將這些 虛擬DOM 轉化為 真實DOM 呈現在頁面上。

注:Vue的編譯時相關程式碼主要就是將模版轉化為render函式,如果這個轉化的過程如果體現完成,我們的程式釋出到線上環境的時候,我們所引入的Vue.js就可以不用帶編譯相關功能,這也就是上文 形式一形式二 根本的不同。

這時我們可能會產生一個疑問:

程式碼片段3和程式碼片段4為什麼能被瀏覽器識別呢?

因為這裡的new Vue({...})操作,就是通過new操作符初始化一個Vue例項,而Vue是一個普通的JavaScript建構函式,只不過在初始化的過程中,Vue在內部執行了許多邏輯。

注:所謂學習Vue,就是編寫Vue能識別的程式碼。比如程式碼片段3中的{{helloTest}},雖然瀏覽器不識別,但是Vue知道如何將其轉化為瀏覽器能識別的內容。

有了上面的認識,我們可能會產生一個新的疑問:

為什麼我們不直接編寫成程式碼片段3或程式碼片段4的程式碼,而要寫成程式碼片段2的程式碼?

答案其實很簡單,至少有下面幾個原因:

1、程式碼片段3中的template寫著體驗不好

2、程式碼不好組織管理

到這裡,我們已經回答了上面的問題那我們需要轉化成什麼樣的內容,瀏覽器才可以識別呢?

但新問題是:我們怎麼去轉化了呢?怎麼把瀏覽器不識別的程式碼片段2的內容轉化成瀏覽器能識別的程式碼片段3或程式碼片段4的內容?

答案是什麼我們先不去深究,但我們這裡要知道,肯定是通過一個程式去完成這個轉化的過程。那既然是程式,我們可以是C++、Java、Python、Go、Rust等各種各樣的程式來實現這個轉化的過程,但是在前端生態圈,這些轉化程式一般都是通過Javascript編寫的。

注:其實到了這裡,我們已經可以認為現代前端的本質就是:利用一系列的前端庫開發前端程式,再利用另一些工具將我們所編寫的程式碼轉化為瀏覽器識別的程式碼,最終還是要回歸到前端的原始形態,就像程式碼片段1那樣。

我們前面不是提到過瀏覽器可以正確的識別JavaScript程式嗎?那我們的這些轉化程式不可能是到瀏覽器上面執行吧?其實從理論上講,如果非要這麼做也是可以實現的,但是這不具備工程實踐意義,我們通常是在本地開發的時候就完成了這個轉化的過程。既然是在本地開發過程中實現這個轉化過程,那我們用JavaScript編寫的轉化程式怎麼才能執行呢?請看下文。

前端工具鏈的脈絡

前端工具鏈的基石—Node.js

Node是什麼

Node是一個基於Chrome V8引擎的JavaScript執行環境。

能夠解析javascript,呼叫作業系統的能力,比如檔案讀取,埠監聽等等。這其實也就回答了上文關於如何在非瀏覽器環境下執行JavaScript程式的問題。

注:推薦nvm管理Node環境

有了執行JavaScript程式的平臺,那我們到底用哪個程式來轉化呢,將瀏覽器不認識的hello.vue轉化成瀏覽器可以識別的內容。答案是多樣的,webpack、vite、esbuild、rollup...都是行業知名的前端程式構建工具。其實準確的講,轉化的過程來講並不是由這些工具來實現的,而是在這些工具所屬的體系下,整合某些能力來進行轉化。甚至於我們可以自己編寫一些特定的程式來進行特定的轉化,但這在實際工作中不太普遍。鑑於工作中有很多專案還在用webpack,本文以webpack來簡要介紹。

Webpack

webpack的本質:

可以這樣來簡單的理解其核心工作。webpack以一個入口檔案開始,把相互依賴的js、css整合在一起(當然也可以按規則拆分),產生出諸如xxx.js、xx.css的檔案嵌入一個所配置的html檔案中。

webpack官網是這樣解釋的:

At its core, webpack is a static module bundler for modern JavaScript applications.

webpack作為一個通用的前端程式構建工具,會在多種場景下工作,比如在js檔案中遇見程式碼import HelloWorld from './helloworld.vue', 正常也是無法識別的。但webpack提供了可擴充套件的機制,其中loader和plugin是webpack兩個重要的概念,對於檔案的識別一般通過loader來配合。比如對於vue而言,就有vue-loader來進行處理,至於vue-loader具體如何工作,大家可以讀完本文後去查閱相關資料瞭解。

上面描述了那麼多的內容來進行程式的轉化,一個新問題可能從腦海中浮現:

既然經歷了複雜的過程,最終還是要轉化成前端程式的原始狀態,那為什麼要用Vue來寫程式?

1、很少去手動操作DOM,專注於資料層面的變化,提高開發效率;

2、可以配合前端工具一定程度上提高相容性處理的效率(如高版本js程式碼轉低版本–bable);

3、給了特定的開發正規化,程式碼可讀性可維護性增強(元件化,css預處理等等);

4、完善的生態系統,可直接使用的成熟的庫。

其實有了上面的知識,我們已經可以進行程式的開發了,但是還有許多工程實踐問題需要我們處理: 怎麼對專案進行管理,具體的,比如怎麼引入依賴,怎麼啟動專案??

如果沒有工具,我們需要手動下載一些依賴包放到某個地方去,然後通過特定的路徑去匯入引用,這樣做的效率會很低,同時繁瑣且容易出錯。這時我們需要藉助一些程式的包管理工具。行業中有npm、yarn、pnpm...等很多優秀的工具,本文以npm為例進行介紹。

包管理工具—npm

安裝、解除安裝、更新…

npm intall xxx # 安裝什麼依賴包,依賴包從哪裡來,安裝到哪裡去,安裝了怎麼用
npm uninstall xxx
npm run xxx # 執行什麼指令

package.json

一個npm用的包管理配置檔案,記錄了諸多資訊,參看npm官方文件。

node_modules

package.json對應的目錄下會自動建立改目錄,存放下載的安裝包。

模組

程式碼本質上就是引入了一個js檔案中的某些暴露的方法或物件,對於模組的基本概念需要掌握。

注:推薦nrm工具來切換npm映象源

當前需要掌握的知識

1、js的基本語法《JavaScript權威指南》或者其他類似的書籍;

2、vue基本語法、vuex/pinia、vue-router等等;

3、node、npm 基本環境的配置,webpack的簡單應用;

4、元件庫 element-ui的瞭解。

有了上面的知識,可以支撐我們從事一些普通的管理後臺系統的開發。如果只是簡單的體驗,相關的書籍或者文件可以瞭解下即可。如果想比較深入的理解前端,建議系統化的閱讀相關資料,否則在後續的過程中容易走很多彎路。

介入開發的工作安排

1、掌握上面的基礎知識;

2、有興趣的夥伴閱讀專案程式碼,基本瞭解並將專案跑起來嘗試寫些程式碼;

3、自己評估,如果有信心就可以進入開發了;

4、建議

  • 開發新功能,儘量不改舊功能,因為歷史原因,有些程式碼相互關聯很容易出錯;

  • 前期評估時間儘量充裕些,前期提交的程式碼最好CodeReview下,適應一段時間自己提交自己改bug;

  • 可以網上找點教程聽一聽,不過需要注意公司實際專案中用的是Vue2還是Vue3又或者是React,別學錯了。

掃描下方二維碼新增 「好未來技術」 微信官方賬號

進入好未來技術官方交流群與作者實時互動~

(若掃碼無效,可通過微訊號 TAL-111111 直接新增)

- 也許你還想看 -

關於冪等設計

Python併發程式設計入門

Orchestrator 在好未來資料庫高可用系統中的應用

基於雙模檢測的通話錄音質檢解決方案

我知道你“在看”喲!~