摘要:原文發(fā)表于抹橋的博客基于的前端項(xiàng)目開發(fā)總結(jié)技術(shù)選型我們的項(xiàng)目主要選用以下技術(shù)開發(fā),再配合一些其它輔助工具。線上環(huán)境前后端是分開部署的,所有的靜態(tài)資源都放在上面。
原文發(fā)表于【抹橋的博客-基于 React 的前端項(xiàng)目開發(fā)總結(jié)】
技術(shù)選型我們的項(xiàng)目主要選用以下技術(shù)開發(fā),再配合一些其它輔助工具。
react
react-router
redux
react-redux
開發(fā)及線上環(huán)境 開發(fā)環(huán)境由于項(xiàng)目是前后端分離的,所以我們需要一套完整的開發(fā)環(huán)境,需要包括以下功能:
數(shù)據(jù) Mock
Webpack 實(shí)施編譯刷新
方便前后端聯(lián)調(diào)
基于這些需求,我們基于 Express, Webpack, Webpack-dev-middleware 搭建了這套完整的開發(fā)環(huán)境。
可以看到,瀏覽器所有的請(qǐng)求都被本地的 Node.js 服務(wù)攔截。對(duì)于靜態(tài)資源請(qǐng)求,都委托給 webpack-dev-middleware 來處理,對(duì)于接口請(qǐng)求根據(jù)不同的環(huán)境來決定要做的操作。
本地開發(fā)當(dāng) ENV = "development" 時(shí),也就是開發(fā)環(huán)境,那么就直接讀取本地的 mock 數(shù)據(jù)來渲染頁面。
前后端聯(lián)調(diào)當(dāng) ENV = "api" 時(shí),也就是我們認(rèn)為的聯(lián)調(diào)環(huán)境,這個(gè)時(shí)候?qū)τ诮涌谡?qǐng)求由 node.js 轉(zhuǎn)發(fā)到需要聯(lián)調(diào)的真實(shí)后端服務(wù)地址上,從而避免直接調(diào)用所產(chǎn)生的跨域問題。
這樣就可以直接用本地開發(fā)代碼和后端聯(lián)調(diào),能大大提高效率,省去了每次需要往服務(wù)器上構(gòu)建部署的步驟。
線上環(huán)境前后端是分開部署的,所有的靜態(tài)資源都放在 CDN (example.cdn.com)上面。
也就是說我們的頁面在 example.cdn/index.html 這里,但是請(qǐng)求的接口在 example.163.com/api/xxx,我們肯定不能讓用戶去直接去訪問 example.cdn.com/index.html,這樣不合理,而且由跨域問題存在。
那么訪問 example.dai.163.com 的時(shí)候,怎么拿到我們的 HTML 頁面呢?
看下圖:
在客戶端和后臺(tái)服務(wù)之間架設(shè)一臺(tái) Nginx, 我們?cè)L問的 example.dai.163.com 有兩種請(qǐng)求:
HTML 頁面資源
接口請(qǐng)求
這兩種請(qǐng)求都先經(jīng)過 nginx,在這里做判斷,如果是頁面請(qǐng)求那么由 nginx 轉(zhuǎn)發(fā)到 CDN, 否則交給后端服務(wù)來響應(yīng)接口請(qǐng)求。
拿到頁面以后,其它所有的 css, js 等靜態(tài)資源都是直接請(qǐng)求到 CDN ,這里沒什么說的。
數(shù)據(jù)流轉(zhuǎn)我們是借助 redux 來管理數(shù)據(jù)流的。
我們來看這張圖。
首先,通過 middleware 和 reducer 生成 store, 然后獲得項(xiàng)目的初始 state,通過初始 state 去渲染頁面的初始狀態(tài)。
以 Home 頁面為例,首先 Home 通過 react-redux 提供的 connect 方法拿到初始 state 作為 Home 的 prop 傳遞給 Home. 而 Home 由多個(gè)不同的子組件組成,這些組件的需要數(shù)據(jù)再由 Home 通過 props 傳遞給自己的子組件。
當(dāng) Home 的初始狀態(tài)加載完畢后,我們需要向后端請(qǐng)求去拿去一些用戶數(shù)據(jù)。這時(shí),我們分發(fā)一個(gè)下面這種格式的 action:
{ types: ["home/start","home/success","home/failure"], payload: { api: ... }, meta: { isApi: true } }
所有的 action 都會(huì)按照我們制定的循序通過一個(gè)個(gè) middleware.
在這里,我們的 action 會(huì)被 callApiMiddleware 通過 meta 里面的 isApi 標(biāo)識(shí)命中,并去做相應(yīng)的事情。
比如在這個(gè)中間件里面,我們?nèi)プ隽苏鎸?shí)的接口請(qǐng)求,在請(qǐng)求成功或失敗的時(shí)候分發(fā)對(duì)應(yīng)的 action,以及做一些統(tǒng)一的業(yè)務(wù)邏輯。比如我們對(duì)后端返回的接口中 code 值有統(tǒng)一的約定,假設(shè) 1 為成功, 2 為失敗, 3 為未登錄。那么我們就可以在中間件中去處理這些業(yè)務(wù)邏輯。
當(dāng)請(qǐng)求成功,并渲染頁面后,假設(shè)用戶點(diǎn)擊了一個(gè)按鈕,這個(gè)按鈕需要喚起 native 的一些功能,比如說拍照。那么我們分發(fā)一個(gè)喚起拍照功能的 camera/start 的action:
{ types: ["sdk/start","sdk/success","sdk/failure"], payload: { command: ... }, meta: { isSDK: true } }
同樣的道理,這個(gè) action 會(huì)被 EpaySDKMiddleware 所識(shí)別并處理,在調(diào)起 native 的時(shí)候, 為了保證安全性,我們需要向后發(fā)起一個(gè)請(qǐng)求去拿簽名,這個(gè)時(shí)候就可以在 EpaySDKMiddleware 里面分發(fā)一個(gè)接口請(qǐng)求的 action,那么這個(gè) action 同樣需要走一遍所有的 middleware. 那么這個(gè)接口請(qǐng)求的 action 就會(huì)像上面的流程一樣,通過 callApiMiddleware 去處理。
中間件的存在,使整個(gè)流程變得非常清晰,接口的請(qǐng)求的中間件就只做接口請(qǐng)求,調(diào)用 native 接口的中間件就只做對(duì) native 的調(diào)用,當(dāng)對(duì) native 接口的調(diào)用需要做后端接口請(qǐng)求的時(shí)候,去分發(fā)一個(gè) action 走接口請(qǐng)求的中間件。
每個(gè)中間件只專注于自己的事情,既方便后續(xù)的維護(hù),同時(shí)也提供了一個(gè)很好的拓展方式。
一個(gè)例子假設(shè)我們由如下的一個(gè)路由配置。
{ component: App, path: "/", onEnter: initLogin(store), indexRoute: { getComponent(nextState, cb) { require.ensure([], require => { cb(null, require("../views/Home").default) }, "Home") }, onEnter: initHome(store) }, childRoutes: [ createActivateRoute(store), { path: "test", indexRoute: { getComponent(nextState, cb) { require.ensure([], require => { cb(null, require("../views/Test").default) }, "Test") } } }, ... ] }
那結(jié)合 react-route 我們來看一個(gè)完整的流程。當(dāng)我們?yōu)g覽器里面輸入 example.dai.163.com/index.html/#/ 的時(shí)候。
首先,通過最上面 線上環(huán)境 一節(jié)提到的內(nèi)容,拿到頁面需要 html,css,js.
然后渲染 Provide 和 Router 組件,分別提供 store 的注入和路由的控制。
此時(shí)觸發(fā)根路徑的路由匹配,然后加載根組件 APP, 然后根據(jù)路由匹配規(guī)則匹配到 IndexRouter, 加載 Home 組件。
后面的事情就和前面數(shù)據(jù)流轉(zhuǎn)一節(jié)講的是一樣的了。
總結(jié)在前后端完全分離的基礎(chǔ)上,借助一套完善的開發(fā)環(huán)境,可以大大提高的我們的開發(fā)效率,降低前后端聯(lián)調(diào)的成本。
同時(shí)借助于 Redux 思想,實(shí)現(xiàn)單向數(shù)據(jù)流,讓我們可以實(shí)現(xiàn)一個(gè)非常清晰的數(shù)據(jù)流向。并且,借助于中間件,我們可以更加有效的控制數(shù)據(jù)流轉(zhuǎn)的過程。為后面項(xiàng)目的擴(kuò)展提供無限的想象空間。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/88273.html
摘要:前端每周清單半年盤點(diǎn)之與篇前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。與求同存異近日,宣布將的構(gòu)建工具由遷移到,引發(fā)了很多開發(fā)者的討論。 前端每周清單半年盤點(diǎn)之 React 與 ReactNative 篇 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為...
平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...
平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...
平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...
平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...
閱讀 3070·2023-04-25 16:50
閱讀 904·2021-11-25 09:43
閱讀 3512·2021-09-26 10:11
閱讀 2518·2019-08-26 13:28
閱讀 2531·2019-08-26 13:23
閱讀 2419·2019-08-26 11:53
閱讀 3566·2019-08-23 18:19
閱讀 2987·2019-08-23 16:27