前言
這是一個關(guān)于KOA的內(nèi)部分享交流講稿踢涌,簡述了KOA的一些特點及逐步搭建一個簡單的SSR架子的過程。
內(nèi)容收集自度娘,希望閱讀下文的兄dei有所收獲偿凭。
前置知識
- node
- ES6
講稿
part0 Koa簡介及分享內(nèi)容介紹
Koa -- 基于 Node.js 平臺的下一代 web 開發(fā)框架,它是由 Express 原班人馬打造的派歌,特點:優(yōu)雅弯囊、簡潔、靈活胶果、體積小匾嘱。
Why Koa
為什么我們選擇用Koa呢?這需要從兩方面談起
-
第一點早抠,是我們需要SSR(服務(wù)器端渲染)所以需要node的web應(yīng)用框架
現(xiàn)在我們的wap端用的是vue技術(shù)棧做的單頁面應(yīng)用霎烙,它的優(yōu)點是:
1、頁面跳轉(zhuǎn)不需要刷新,用戶體驗流暢悬垃。
2游昼、前后端只需要用API交互,實現(xiàn)前后端分離。
3尝蠕、實現(xiàn)前端頁面路由功能烘豌,頁面的拼接、顯示邏輯均在客戶端完成看彼,減輕服務(wù)器壓力廊佩。
但是,單頁面應(yīng)用有個不能回避的問題闲昭,就是SEO(Search Engine Optimization):搜索引擎優(yōu)化不友好罐寨。
PC端需要通過搜索引擎做入口,所以需用到SSR的項目架構(gòu)序矩。
-
第二點鸯绿,是在web應(yīng)用框架中,Koa比較符合我們項目的體量簸淀, 市面上主流框架有三種瓶蝴,hapi express koa ,還有一些是經(jīng)過一些封裝和定制的框架,例如:eggjs等租幕。
eggjs的功能很強(qiáng)大舷手,有很多功能,多到有些根本用不著劲绪,從而導(dǎo)致這個框架太重男窟。
koa是express的原班人馬打造,屬于對express的升級贾富。也是現(xiàn)在社區(qū)比較熱門的web框架歉眷,因此我們選擇了Koa。
What we talk about
這次的分享颤枪,會從以下幾點開展
1.介紹基本用法汗捡。 首先,我們跑起一個最基本的Koa應(yīng)用畏纲,實現(xiàn)在瀏覽器顯示hello world扇住。
2.介紹上下文對象。 Koa Context 將 node 的 request 和 response 對象封裝到單個對象中盗胀,為編寫 Web 應(yīng)用程序和 API 提供了許多有用的方法艘蹋。
3.介紹Koa的中間件(middleware) 這是 Koa 的最大特色,也是最重要的一個設(shè)計票灰,Koa 應(yīng)用程序是一個包含一組中間件函數(shù)的對象簿训,它是按照類似堆棧的方式組織和執(zhí)行的咱娶。
4.介紹Koa獲取請求后的一些處理。 包括路由强品、解析數(shù)據(jù)、鑒權(quán)
5.介紹Koa對靜態(tài)資源的處理
6.介紹Koa如何搭配模板引擎
7.最后屈糊,因為node是跑在服務(wù)器上的榛,所以介紹一下性能優(yōu)化與安全相關(guān)的內(nèi)容
part1 基本用法(手把手教你寫hello World)
- 第一步,我們首先檢查node的版本逻锐。 Koa是node的一個web應(yīng)用框架夫晌,首先要檢查是否已經(jīng)安裝了node,因為Koa需要支持async方法,所以node版本要大于7.6
- 第二步昧诱,安裝Koa晓淀。 先npm init 初始化包管理配置文件,再npm install koa 下載koa的資源包盏档,
- 第三步凶掰,編寫入口文件腳本。 先require引入koa蜈亩,new一個實例懦窘,listen3000端口。
- 最后啟動服務(wù)稚配,打開網(wǎng)頁畅涂。 就可以看頁面請求localhost:3000,Koa接受到請求后,返回Hello World道川!的內(nèi)容午衰。
part2 上下文(context)
介紹
- 我們接收到客戶端的請求,需要根據(jù)請求的內(nèi)容做相應(yīng)的操作冒萄,增刪改查數(shù)據(jù)臊岸、返回頁面等等。
- Koa Context 將 node 的 request 和 response 對象封裝到單個對象中宦言,為編寫 Web 應(yīng)用程序和 API 提供了許多有用的方法扇单。
比如:
- 獲取、設(shè)置cookies
- 獲取request headers奠旺,設(shè)置respond headers
- 獲取請求源蜘澜、請求協(xié)議
- 設(shè)置響應(yīng)狀態(tài)、設(shè)置緩存字段等
這里Koa推薦ctx.state這個命名空間响疚,可用于通過中間件傳遞信息和前端視圖鄙信。
代碼展示
每個向Koa發(fā)起的請求都將創(chuàng)建一個 Context 上下文對象,并在中間件中作為接收器引用忿晕,一般用 ctx 標(biāo)識符装诡,如以下代碼片段所示:
這是在控制臺打印出來的ctx信息,有各種請求的相關(guān)信息
part3 中間件(Middleware)
介紹
- Koa 的最大特色,也是最重要的一個設(shè)計鸦采,就是中間件(middleware)宾巍,Koa 應(yīng)用程序就是一個包含一組中間件函數(shù)的對象;
- 每個中間件默認(rèn)接受兩個參數(shù)渔伯,第一個參數(shù)是 Context 對象顶霞,第二個參數(shù)是next函數(shù);
- 中間件是按照類似堆棧的方式組織和執(zhí)行的锣吼。我們看這個中間件執(zhí)行順序GIF选浑。程序由上到下執(zhí)行,在中間件中遇到next()玄叠,就將執(zhí)行權(quán)移交給下一個中間件古徒。當(dāng)最后一個中間件執(zhí)行完成,這里一般是向頁面返回數(shù)據(jù)后读恃。中間件就往回繼續(xù)執(zhí)行隧膘,直到返回第一個中間件。
- 就像這個洋蔥圖一樣狐粱,請求從左至右舀寓。所有的請求經(jīng)過一個中間件的時候都會執(zhí)行兩次,對比 Express 形式的中間件肌蜻,Koa 的模型可以非常方便的實現(xiàn)后置處理邏輯互墓;
對比 Koa 和 Express 的 Compress 中間件就可以明顯的感受到 Koa 中間件模型的優(yōu)勢。
koa-compress for Koa. https://github.com/koajs/compress/blob/master/index.js
compression for Express. https://github.com/expressjs/compression/blob/master/index.js
在demo中蒋搜,我們利用這個特性可以寫個統(tǒng)計請求處理時間的中間件
這里需要注意的是篡撵,node里面是充滿異步的世界,因此豆挽,在中間件里育谬,我們使用async 函數(shù)(generator函數(shù)的語法糖)并 await next(),實現(xiàn)等待異步
中間件實現(xiàn)簡易路由
- koa是個極簡的web框架帮哈,簡單到連路由模塊都沒有配備膛檀,我們先來可以根據(jù)ctx.request.url或者ctx.request.path獲取用戶請求的路徑,來實現(xiàn)簡單的路由娘侍。
- 但當(dāng)項目龐大起來時咖刃,手寫這種路由時就變得繁瑣,我們一般用對應(yīng)的路由中間件koa-router來對路由進(jìn)行控制憾筏。
part4 請求處理(request)
- 這里主要說一下KOA如何處理路由嚎杨、數(shù)據(jù)解析、鑒權(quán)氧腰。
Koa-router
這里首先說一下路由
- 剛剛說中間件的時候枫浙,我們手動實現(xiàn)了一個簡單的路由功能刨肃,但實際項目中,我們會借助koa-router這個中間件
- 一般在項目中箩帚,我們會這樣組織代碼
- app.js是項目的入口文件真友,在app.js中import路由文件,并注冊路由信息膏潮;
- 路由文件寫在routes文件夾下锻狗,用router實例下的get、post等方法焕参,匹配請求;
- 根據(jù)匹配到的路徑油额,調(diào)用到controller.js的不同方法叠纷,渲染頁面或返回數(shù)據(jù);
- 如果有復(fù)雜的異步業(yè)務(wù)操作潦嘶,我們再抽離到service文件中涩嚣。
koa-bodyparser
- koa.js并沒有內(nèi)置Request Body的解析器,當(dāng)我們需要解析請求體時官方提供的koa-bodyparser是個很不錯的選擇掂僵,它支持form航厚、json、text等格式的請求體锰蓬。
- bodyparser比較簡單幔睬,直接引入進(jìn)來,use一下就可以芹扭÷槎ィ可選的配置有:允許的類型,編碼方式舱卡,請求體大小等辅肾。一般配置一下enableTypes,其他默認(rèn)就可以轮锥。
koa-session
介紹
HTTP是無狀態(tài)協(xié)議矫钓,為了保持用戶狀態(tài),我們一般使用Session會話舍杜,koa-session提供了這樣的功能新娜,既支持將會話信息存儲在本地Cookie,也支持存儲在如Redis, MongoDB這樣的外部存儲設(shè)備蝴簇。
例子
這里是一個基于cookies的session設(shè)置例子杯活,session的內(nèi)容直接存放在cookies中。
- CONFIG的參數(shù)就是設(shè)置一個cookie的參數(shù)熬词,設(shè)置鍵名旁钧、有效時間吸重、HTTP Only、簽名加密等等;
- 然后在中間件里就可以讀寫ctx.session對象歪今,將需要的字段掛上去;
- 下圖cookies里的FLB-SESSION就是在中間件中掛在ctx.session的信息嚎幸;
在實際項目中,會話相關(guān)信息往往需要在服務(wù)端持久化寄猩,因此一般都會使用外部存儲來記錄session信息嫉晶。
外部存儲可以是任何的存儲系統(tǒng),可以是內(nèi)存數(shù)據(jù)結(jié)構(gòu)田篇,也可以是本地的文件替废,也可以是遠(yuǎn)程的數(shù)據(jù)庫。
但是這不意味著我們不需要cookie了泊柬,由于http協(xié)議的無狀態(tài)特性椎镣,我們依然需要通過cookie來獲取session的標(biāo)識(這里叫externalKey)。
part5 靜態(tài)資源(resource)
網(wǎng)站一般都提供靜態(tài)資源(圖片兽赁、字體状答、樣式表、腳本……)刀崖,我們可以自己實現(xiàn)一個靜態(tài)資源服務(wù)器惊科,但這沒必要,因為koa-static模塊封裝了這部分功能亮钦,簡單配置后馆截,就可以正常訪問靜態(tài)資源了。
part6 模板引擎(template)
Koa-views
- 在之前的deme中或悲,頁面都是通過ctx.body=‘string’的方式孙咪,將頁面返回到前端。
- 然而真實項目中巡语,我們需要復(fù)用代碼翎蹈,就需要用到模板引擎,就如現(xiàn)在pc項目的jsp一樣男公。
- Koa給需要進(jìn)行視圖模板渲染的應(yīng)用荤堪,提供koa-views這個中間件,這個中間件支持ejs, jade,nunjucks等眾多模板引擎枢赔。
- Koa-views的使用方法澄阳,use一下,指定模板所在的路徑就可以了踏拜。
渲染頁面時碎赢,調(diào)用ctx的render方法,傳入對應(yīng)模板的路徑及數(shù)據(jù)就可以了
Why EJS
為什么我們選用的模板語言是EJS呢
主要是因為速梗,EJS 是一套簡單的模板語言肮塞,具有以下優(yōu)點:
- 純 JavaScript:利用普通的 JavaScript 代碼生成 HTML 頁面;
- 語法簡單: EJS 支持直接在標(biāo)簽內(nèi)書寫簡單襟齿、直白的 JavaScript 代碼。只需讓 JavaScript 輸出你所需要的 HTML ;
- 執(zhí)行迅速:基于V8引擎枕赵,EJS 能夠緩存 JS 函數(shù)的中間代碼猜欺,從而提升執(zhí)行速度;
- 易于調(diào)試:調(diào)試 EJS 錯誤(error)很容易:所有錯誤都是普通的 JavaScript 異常,并且還能輸出異常發(fā)生的位置;
- 社區(qū)活躍: EJS 背后是一個活躍用戶組成的大規(guī)模社區(qū)拷窜,能夠為 EJS 的演進(jìn)提供大力支持开皿。
當(dāng)然,其他模板語言也有這樣那樣的有點篮昧,但最主要的是赋荆,因為ejs的語法與jsp類似,重構(gòu)搬代碼時比較便捷懊昨,可以在編輯器寫正則替換糠睡,提高開發(fā)效率
part7 優(yōu)化與安全(optimize&safety)
因為node跑在服務(wù)器上,最后介紹幾個優(yōu)化疚颊、安全的中間件
koa-helmet 中間件增加安全HTTP頭字段。
koa-compress 壓縮啟用類似Gzip的壓縮技術(shù)減少傳輸內(nèi)容
koa-logger 提供了輸出請求日志的功能信认,包括請求的url材义、狀態(tài)碼、響應(yīng)時間嫁赏、響應(yīng)體大小等信息其掂,對于調(diào)試和跟蹤應(yīng)用程序特別有幫助
相關(guān)資料
demo地址:https://github.com/yejiayuan163/koaDemo
ppt地址:鏈接:https://pan.baidu.com/s/1Vv_LkaN9kj3IP9rOlZjuMQ 提取碼:zhxu
謝謝閱讀!A视款熬!