Web開發基礎
核心概念
-
HTML、CSS和JavaScript:Web開發的三大基石,分別負責結構、樣式和行為。
-
代碼管理:隨著項目規模擴大,需要將代碼拆分成小塊,便于維護。
-
作用域污染:早期所有代碼共享全局作用域,容易導致變量和函數名沖突。
細化解釋
在Web開發的初期,開發者通常將HTML、CSS和JavaScript寫在一個文件(如index.html)中。這種方式簡單,但當代碼量增加時,文件變得臃腫,維護困難。為了解決這個問題,開發者開始將JavaScript拆分成多個文件,通過<script>標簽引入。然而,所有代碼仍共享全局作用域,如果多個文件中定義了同名變量或函數,就會相互覆蓋,導致“作用域污染”。
模塊化與打包工具
核心概念
-
模塊化:將代碼拆分為獨立模塊,每個模塊有自己的作用域,避免全局污染。
-
打包工具:如Webpack,將多個模塊整合成一個或多個文件,便于部署。
-
Webpack:主流打包工具,支持前端和后端代碼的統一處理。
細化解釋
模塊化開發通過將功能封裝到獨立的模塊中,避免了全局作用域的沖突。每個模塊可以導出功能(如函數或變量),其他模塊通過導入使用這些功能。Webpack作為打包工具,能夠分析模塊間的依賴關系,將所有模塊打包成一個bundle.js文件,瀏覽器可以直接加載運行。
后端引入方式與AMD/CMD協議
核心概念
-
require:Node.js中同步加載模塊的方式。
-
AMD(異步模塊定義):瀏覽器端異步加載模塊的標準。
-
CMD(通用模塊定義):在AMD基礎上改進,提供更靈活的加載方式。
細化解釋
在Node.js中,require同步加載模塊,適合服務器端,但在瀏覽器端由于網絡延遲,同步加載效率低下。AMD通過define定義模塊,支持異步加載依賴,適用于前端。CMD在AMD基礎上優化,允許按需加載依賴,并通過緩存減少重復請求。
Webpack的統一打包功能
核心概念
-
統一打包:支持不同模塊標準(如CommonJS、ES Modules)的代碼整合。
-
入口文件:從指定入口開始,構建依賴圖并打包。
細化解釋
Webpack能夠處理使用require(CommonJS)或import(ES Modules)的代碼,將其統一打包為一個文件。開發者無需擔心模塊標準的差異,只需指定入口文件,Webpack會自動解析依賴并生成bundle.js。
單頁面應用和多頁面應用
核心概念
-
網頁加載:瀏覽器通過URL向服務器請求資源。
-
緩存機制:存儲靜態資源,減少重復請求。
-
單頁面應用(SPA):一個HTML文件,通過JavaScript動態渲染。
-
多頁面應用(MPA):多個獨立HTML文件,適合SEO。
細化解釋
傳統MPA中,每個頁面對應一個HTML文件,導航時重新請求。SPA只有一個HTML,通過JavaScript動態更新內容,提升用戶體驗。緩存機制通過存儲JS、CSS等靜態文件,加速后續加載。
單頁面應用框架
React、Angular、Vue
-
React、Angular、Vue:主流SPA框架,提供組件化開發。
-
與Webpack結合:優化代碼打包和資源管理。
細化解釋
這些框架通過組件化方式組織代碼,與Webpack結合實現模塊化開發和高效打包。React以聲明式UI著稱,Vue易上手,Angular功能全面。
組件化的概念
-
單頁面應用采用的方式都是構建一個大組件,然后再把這個大組件掛載到一個名叫 div#app 下面去
-
這里幾乎是所有初中級前端邁不過去的概念了,他們不知道可以多創建一個 div,然后通過改寫 main.js 將多個 Vue 組件掛載到多個 div 下,因為一般情況下完全不需要這樣做,但是在谷歌插件開發,需要增強一個網頁功能時,恰巧需要這個概念,若沒有這個概念,就很難搞了,如下圖紅框里面這些小圖標
-
-
將單頁面的打包理解為一個大 Vue 組件的 js 代碼用 Webpack 打包的過程,才能更好的理解谷歌插件開發,否則很難對谷歌插件知識進行分層,最終將插件知識和 Webpack + Vue 打包知識混合在一起,那就讓你腦袋大了。
谷歌插件開發基礎
popup.html,option.html,background.js,content script,inject script
-
谷歌插件:實現多頁面間數據通信。
-
結構:
-
background:后臺腳本,處理持久數據。
-
popup:彈出界面。
-
content script:注入網頁,監聽消息。
-
inject script:處理業務邏輯。
-
細化解釋
谷歌插件通過多個組件協作實現功能。background腳本常駐后臺,popup提供用戶交互,content script訪問網頁DOM,inject script執行具體邏輯。多端通信涉及1:n關系(如插件到多個tab)。
background.js 特殊存在,為何谷歌稱它 serviceworker.js
-
background.js 最早期 MV2 版本時,它就是一個獨立 page 和其他頁面沒啥區別,也即意味著原來谷歌瀏覽器需要給 background.html 提供 V8 運行環境,提供一些毫無用處的 DOM 全局變量的概念,但是 background.js 是個不可見的純提供服務的概念,追加 window 和 DOM 以及其他 html5 API 都沒有任何實質意義,還增加了性能開銷,這東西需要常駐以便為其他頁面提供服務;
-
那為何不把 background.html 做成一個簡單的 worker.js 呢?用的時候加載進來,不用的時候卸載掉?不就不存在性能損耗了嗎?不就可以讓谷歌瀏覽器同時支持上百個插件在運行了嗎?既然如此那必須干!于是 background.html 變成了 background.js,成為其他頁面通信中轉和數據增刪改查的服務;
谷歌插件的知識分層
-
知道谷歌插件由 popup.html,option.html,background.js,content script,inject script 5 個部分構成,其中 popup.html,option.html 是單頁面,content script 和 inject script 是組件化打包之后掛載到網頁的某個 div 上實現具體功能的存在,而 background.js 是負責通信中轉和數據增刪改查的概念,但以上概念,均可以通過 webpack 進行打包,且 target:"web",因為這 5 個概念都沒有偏離 web 下運行的范疇;
-
你要掌握的谷歌插件知識只有
-
5 個部分如何通信?
-
content script 和 inject script 不共用一個作用域
-
inject script 是與網頁共享一個 window 作用域
-
content script 在復雜開發中,只充當通信中轉器,因為網頁環境無法直接跟某個插件直接通信,因為網頁和插件是 1:n 的概念,window.postmessage 到底發給哪個插件,瀏覽器不得而知,你必須有個 content script 接收這個消息才能保證網頁和插件的對應。
-
所有的數據持久化,必須通過 background.js,因為其他那 4 個都不能保證穩定性和對應性,例如 inject script 只能存到 localstorage 里面,是針對某個網頁的,與插件的存儲范圍不一樣。
-
了解 chrome.storage 所有增刪改查的使用方法;
-
-
至于 vuex,vue-router,vue 腳手架的使用壓根跟谷歌插件開發沒有關系,但若你一開始就從一個谷歌插件腳手架開始,迷惑也很正常;
Electron桌面應用開發
主進程 Main 和渲染進程 renderer
-
主進程:管理操作系統功能,類似于 background.js
-
渲染進程:類似于 popup.html option.html
-
webview 渲染進程:類似于網頁+inject script
-
渲染進程的 preload.js:類似于網頁+content script
-
-
歸根結底,你只需要了解兩個概念,主進程和渲染進程,其他都是進一步的細化
細化解釋
Electron結合Node.js(主進程)和Chromium(渲染進程),支持跨平臺開發。主進程處理文件操作等,渲染進程負責界面展示,二者通過IPC通信。
主進程 Main
-
node.js 環境下的運行腳本,electron.exe main.js 進行啟動
-
相當于 electron.js 程序運行到一定步驟后,使用 eval 函數,將 main.js 加載后執行
渲染進程 Renderer
-
main.js 啟動 V8 環境構建出來的網頁環境,這個環境可以直接執行里面的 html 和 js,那說明 web 打包那一套又可以直接拿來用了,比如 vue 腳手架打包一個單頁面,直接丟進來就能用了
-
特殊的渲染進程 webview,會對具體的網頁進行渲染,通過將 Vue 打包成組件掛載到網頁的具體 div 上面,實現網頁功能的增強
進程間通信
核心概念
-
進程間通信(IPC):主進程與渲染進程間的消息傳遞。
-
服務間通信:主進程與外部服務的交互。
-
通信方式:監聽、發送消息、第三方中轉。
細化解釋
在Electron中,IPC通過ipcMain和ipcRenderer實現進程間通信。服務間通信可能涉及HTTP或WebSocket,復雜場景可借助消息隊列。
服務間通信
-
如果將所有的邏輯都放在 main.js 中,比如數據庫的增刪改查操作,就會讓主進程變得特別冗雜,冗雜就會導致出錯率增大,針對渲染進程和 webview 進程閃退,都會自動重啟,而主進程因為異常而閃退,則沒有任何機會重啟,因此降低主進程的代碼復雜量,非常必要。
-
但是將邏輯抽離出來,單獨形成 http 本地服務實現數據庫增刪改查,但隨之而來的問題,是主進程和 http 本地服務就無法通信了,此時可以將主進程和 http 本地服務都理解為獨立的服務,兩個服務之間可通過訂閱一個獨立的服務消息,實現消息的實時通信,例如 Redis 或者 zeroMQ
總結
看似非常復雜的大前端開發,最終無非就是在解決兩個問題:
-
解決不同層級下的通信問題
-
同頁面下的通信,例如 vue 的父子通信,或者 vuex
-
不同頁面下的通信,例如谷歌插件不同頁面的 chrome.runtime.sendMessage
-
不同進程下的通信,例如 electron 的 ipcRenderer.invoke
-
不同服務下的通信,例如 electron 的 main.js 和本地 http.exe
-
-
解決數據的存儲問題
-
同頁面下的數據存儲,例如 vuex 和 localStorage
-
不同頁面下的數據存儲,例如 chrome.storage
-
不同進程下的數據存儲,例如 config.json 和 sqlite
-
其他東西都是這兩大問題的具體細化過程,以及 web 方面的開發知識,如果你覺得很難,那基本是 web 本身的基礎就不牢靠,學得似是而非。