專案開始前,我們先聊一聊關於專案的一些說明。該專案起始於2017年初,當時公司主要技術棧為gulp+angular,鑑於react的火熱的生態,在公司決定研發bss管理系統時選用react開發,目的也是為react native打下基礎,以解決後期公司大前端技術棧的逐步成熟。(當時沒有選擇vue開發的主要原因是weex生態還不夠特別成熟),既然決定換新,專案的構建也跟著一起換,從gulp轉向火熱的webpack,持續大半年的更新迭代,我們將構建模組逐步從專案中抽離出來,把構建模組作為npm包單獨管理,完成和專案程式碼解耦,於是就有了後面我們要說的wci-build構建模組包和wci-cli專案腳手架。
我們要做什麼
技術棧
專案採用前後端分離的形式,後端選用Maven+SpringClould全家桶開發,前端選用webpack+react全家桶開發,前後端全部採用包管理工具完全解決專案依賴管理的難題,版本管理採用git,前後端通過json互動,swgger管理介面文件,介面全部遵循restful規範。由於本文面向社群開放,故本文中不涉及公司業務層的程式碼,本文全部程式碼均為最新編寫,我們以一個旅遊管理系統的三個模組為大家演示專案(登陸登出、使用者模組、景點模組)。為了快速開展,本文涉及的後端程式碼直接採用Java的SSM框架搭建,原始碼也將為大家奉上。朋友們也可以使用mock模擬介面資料。後期我們在演示nodejs+espress時將介面程式碼全部轉為node形式。
準備
因本文不是講解基礎,故大家在敲程式碼前,還需要具備一定的前端基礎,部分如下
- html、css、javascript基礎知識
- es6基礎知識
- react基礎知識
- 瞭解什麼是webpack、babel、redux、react-router、nodejs、npm
- 熟悉螞蟻金服ant design
- 熟悉less基本使用
解決什麼問題
本專案整合了最新的react16、react-router4、redux,同時可以選擇性整合antd|antd mobile,在解決繁瑣的架構配置工作外,還解決了以下問題
通用問題
- 支援開發效率更高的ES6編寫程式碼。
- 拆分開發、測試、生產環境,完成從開發到上線的所有工作。
- 開發環境包含熱替換,本地IP、埠可配置,介面可配置,微服務模組可配置
- 測試環境包含程式碼壓縮、合併、css抽離、公共元件抽離、程式碼新增hash、測試版本字尾
- 生產環境包含程式碼壓縮、合併、css抽離、公共元件抽離、程式碼新增hash、生產版本字尾(和測試程式碼完全一樣,只缺少測試版本號)
- 支援自定義新增webpack loader
其他問題
- 目前大型專案後端多采用微服務架構,API介面在開發、測試、生產環境下來回切換,需要頻繁修改程式碼。解決方案:通過配置檔案的方式統一配置專案模組介面
- 專案模組在分拆開發的過程中css命名衝突,導致程式碼維護性較差。解決方案:構建工具預載入css時自動化新增hash,使css程式碼模組化
- 不同開發人員,不同的程式碼習慣造成專案程式碼難以維護。解決方案:在程式碼編寫、構建、版本管理三個方向加入程式碼規範校驗(airbnb規範)
- 在同時開發多個系統的時候,構建業務模組在不同的專案都存在,當需要修改配置或者優化構建方案的時候,需要修改多個專案的配置。解決方案:抽離構建模組,採用npm形式依賴。
還有什麼問題要解決
雖然經過大半年迭代,但我們還需要在實際專案開發中支援更多的個性化需求
- cdn自動化
- 更加完善的持續整合
- 單元測試,包括程式碼,互動測試
- mock資料,實現前後端真正0接觸
- …
希望
大家在開發過程中遇到任何問題,希望可以給我們留言,我們會不斷優化專案。未來,我們還會加入mobx、rxjs、immutablejs、GraphQL等,也希望在和大家的探討中,持續進步。
專案準備
本專案基礎環境必須依賴nodejs和npm,未安裝的朋友可以去官網自行安裝,安裝教程這裡不詳細說明,安裝完成後使用如下命令,檢視是否安裝成功。
node -v
npm -v
複製程式碼
####初始化專案
本專案我們使用wci-cli腳手架初始化專案
- 全域性安裝wci-cli
npm install -g wci-cli
複製程式碼
- 建立專案
wci-cli 腳手架可以建立三種專案,分別是1.純淨的react專案 2.包含antd的react專案 3.包含antd-mobile的react專案,命令如下
wci new myapp
複製程式碼
執行命令後,命令列會提示是否需要安裝antd以及選擇antd型別,即可完成專案初始化,如下
專案目錄
myapp
├── app // 專案業務程式碼
│ ├── assets // 靜態檔案目錄(圖片、字型等)
│ ├── script // js程式碼目錄
│ │ ├── actions // redux action目錄
│ │ ├── componets // react 無狀態元件目錄
│ │ ├── containers // react 業務程式碼
│ │ ├── reducers // redux reducer目錄
│ │ ├── util // 工具包目錄
│ │ │ ├── theme.js // antd自定義樣式檔案
│ │ ├── Home.js // 首頁
│ │ ├── home.less // 首頁樣式
│ ├── styles // 全域性樣式目錄
│ ├── index.js // 專案入口檔案
│ ├── index.tpl.html // 專案html模版
├── node_modules // 依賴包目錄
├── .babelrc // babel配置檔案
├── .eslintrc // eslint程式碼校驗配置檔案
├── .gitignore
├── package.json
├── README.md
├── wci.json // wci專案配置檔案(主要配置一些開發、測試、生產環境的資訊)
└── webpack.js // webpack自定義配置檔案
複製程式碼
執行如下命令,執行開發環境
cd myapp
npm run start
複製程式碼
如上圖,我們的專案已經跑起來了…
- 測試、釋出
因我們需要保證測試程式碼和生產程式碼必須保持一致,所有在實際專案中,我們可以執行如下命令構建程式碼
npm run test // 測試環境打包
npm run dist // 生產環境打包
複製程式碼
測試程式碼
生產程式碼
到這裡,我們已經完成專案前期開發的所有準備工作,接下來,我們一起開始擼程式碼吧
專案結束後,我會為大家奉上兩篇彩蛋,分別是 1. 一步步搭建webpack前端構建工具並抽成npm單獨模組 2. 一步步構建自己的npm開發包並且以一個真例項子演示(開發一個命令列生成資料夾結構的小工具)
還要說一點
正式開始擼程式碼前,還要針對專案具體說明,包括專案程式碼目錄介紹,前後端分離專案需要注意哪些問題,前後端如何鑑權等…
都是幹什麼的
myapp
├── app // 專案業務程式碼
│ ├── assets // 靜態檔案目錄(圖片、字型等)
│ ├── script // js程式碼目錄
│ │ ├── actions // redux action目錄
│ │ ├── componets // react 無狀態元件目錄
│ │ ├── containers // react 業務程式碼
│ │ ├── reducers // redux reducer目錄
│ │ ├── util // 工具包目錄
│ │ │ ├── theme.js // antd自定義樣式檔案
│ │ ├── Home.js // 首頁
│ │ ├── home.less // 首頁樣式
│ ├── styles // 全域性樣式目錄
│ ├── index.js // 專案入口檔案
│ ├── index.tpl.html // 專案html模版
├── node_modules // 依賴包目錄
├── .babelrc // babel配置檔案
├── .eslintrc // eslint程式碼校驗配置檔案
├── .gitignore
├── package.json
├── README.md
├── wci.json // wci專案配置檔案(主要配置一些開發、測試、生產環境的資訊)
└── webpack.js // webpack自定義配置檔案
複製程式碼
以上是程式碼的全部目錄,下面我們根據功能依次介紹:
- node_modules、.gitignore、package.json、README.md
node_modules: npm依賴包目錄,開發者可以不用管,只要知道我們專案裡所有的依賴都下載在這個資料夾下
.gitignore:git需要忽略的檔案
package.json:npm最主要的檔案,裡面寫滿了我們依賴包的結構和一些專案資訊
README.md:github的說明檔案
- .babelrc、.eslintrc
.babelrc:babel配置檔案,可以配置部分自定義babel外掛(例如本專案裡antd自定義主題和javascript@語法糖就在這裡配置)
.eslintrc:eslint配置檔案,可以自定義配置eslint規則,詳細規則可以去官網eslint檢視
說明:這兩個模組本該配置在wci-build構建工具裡,但考慮到專案的靈活性,所有抽離出來放在專案根目錄
- webpack.js
webpack.js:webpack loader個性化的配置檔案,可以自定義新增webpack loader
- wci.json
wci.json:專案的配置檔案,可以自定義配置專案
{
"index": "app/index.js", // 專案入口檔案
"hostname": "127.0.0.1", // 開發環境IP地址(可以配置域名通過本地host轉發)
"name": "wci-antd-app", // 專案名稱(顯示在瀏覽器title裡的名字)
"libs": [ // 專案的公共包,後續可以自行新增
"react",
"react-dom",
"axios",
"classnames",
"prop-types",
"react-redux",
"react-router-dom",
"redux",
"redux-thunk"
],
"dev": { // 開發環境配置
"port": 8031, // 開發環境埠
"src": "app", // 開發環境監聽目錄
"api": "", // 開發環境後端介面地址
"module": {}, // 開發環境的模組包
"is_eslint": false // 開發環境是否開啟eslint校驗
},
"test": { // 測試環境配置
"module": {}, // 測試環境的模組包
"api": "" // 測試環境後端介面地址
},
"prod": { // 生產環境配置
"module": {}, // 生產環境的模組包
"api": "" // 生產環境後端介面地址
}
}
複製程式碼
- app
專案目錄
├── app // 專案業務程式碼
│ ├── assets // 靜態檔案目錄(圖片、字型等)
│ ├── script // js程式碼目錄
│ │ ├── actions // redux action目錄
│ │ ├── componets // react 無狀態元件目錄
│ │ ├── containers // react 業務程式碼
│ │ ├── reducers // redux reducer目錄
│ │ ├── util // 工具包目錄
│ │ │ ├── theme.js // antd自定義樣式檔案
│ │ ├── Home.js // 首頁
│ │ ├── home.less // 首頁樣式
│ ├── styles // 全域性樣式目錄
│ ├── index.js // 專案入口檔案
│ ├── index.tpl.html // 專案html模版
複製程式碼
如上,因為react遵循元件化開發,故我們的業務程式碼全部寫在containers
目錄下,並且模組的樣式檔案、高階元件寫在相對的模組下,如圖
styles
目錄用於存放專案全域性的樣式檔案,例如全域性樣式的變數檔案等…
其他
版本管理:
推薦使用gitflow來進行版本的管理,這裡不做詳細描述
前後端分離跨域:
一旦專案採用前後端分離,跨域是所有專案裡不可避免的問題,目前跨域的解決方案主要有三種
- 採用jsonp方式(只支援GET請求)
- 採用cors方式
- 採用node中介軟體方式(需要單獨部署nodejs服務)
我們這裡採用方式2
java程式碼
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Headers","Content-Type,Content-Token,Content-User,X-Requested-With");
複製程式碼
nodejs 程式碼
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers","Content-Type,Content-Token,Content-User,X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",` 3.2.1`)
res.header("Content-Type", "application/json;charset=utf-8");
複製程式碼
這種方式還可以自定義請求頭的認證資訊
不明白的朋友可以去看阮一峰大神的這篇文章
更新於2018-02-27