本文系原創,轉載請附帶做者信息:yhlben
在實際的開發過程當中,從零開始初始化一個項目每每很麻煩,因此各類各樣的腳手架工具應運而生。crea-react-app,vue-cli,@angular/cli 等腳手架工具,只須要執行一個命令,項目結構以及開發環境就搭建好了。html
腳手架工具確實方便了咱們使用,開發者能夠專一於業務,而不須要考慮太多的環境搭建。但做者認爲,學習腳手架工具背後的搭建過程也是很重要的,以防腳手架掛了以後,咱們還能正常搭建項目。基於這個目的,做者從零搭建了cdfang-spider項目。前端
如今讓咱們就以這個項目爲例,從零開始搭建項目吧。vue
三大框架裏選哪一個?node
引入強類型語言?react
css 選型?webpack
構建工具選哪一個?nginx
代碼規範檢查?git
測試框架選型?es6
後端框架選型?
數據庫選型?
接口方式選型?
基本框架選型完畢,接下來就開始搭建項目環境。
TypeScript 是 JavaScript 的超集,意味着能夠徹底兼容 JavaScript 文件,但 TypeScript 文件卻並不能直接在瀏覽器中運行,須要通過編譯生成 JavaScript 文件後才能運行。
一、 新建 tsconfig.json 文件。
tslint 會讀取 tsconfig.json 文件中的規則,輔助編碼規範校驗。
二、 配置 eslint。
根據 typescript-eslint 引導,配置 eslint 對 typescript 的支持。
三、 選擇一個 typescript 編譯器,tsc 仍是 babel?
使用 babel。好處以下:
babel 流程分析
babel 是一個 js 語法編譯器,在編譯時分爲 3 個階段:解析、轉換、輸出。
- 解析階段:將 js 代碼解析爲抽象語法樹(ast)。
- 轉換階段:對 ast 進行修改,產生一個轉換後的 ast。
- 輸出階段:將轉換後的 ast 輸出成 js 文件。
plugin 和 preset
- plugin: 解析,轉換,並輸出轉換後的 js 文件。例如:@babel/plugin-proposal-object-rest-spread 會輸出支持
{...}
解構語法的 js 文件。- preset: 是一組組合好的 plugin 集合。例如:@babel/preset-env 讓代碼支持最新的 es 語法,自動引入須要支持新特性的 plugin。
四、蒐集全部的 ts,tsx 頁面(前端環境使用 webpack,node 項目使用 gulp),而後經過 babel 編譯成 js 文件。
React 是一個庫,基於組件式開發,開發時經常須要用到如下語法:
這些語法在目前瀏覽器中並不能直接執行,須要進行打包編譯,這也是搭建 React 環境的主要工做。
一、新建一個 html 文件,並在 body 中建立一個根節點,用於掛載 react 最後生成的 dom。
二、新建一個 index.tsx 文件,用於將項目中的全部組件,引入進來,並調用 render 方法,將組件渲染到根節點中。
三、React 項目分層。
四、配置 webpack,以 index.tsx 爲入口文件,進行打包編譯。
配置 ts 編譯器,使用 babel-loader。
配置 html-webpack-plugin 將最後生成的 js,css,注入第 1 步的 html 中。
開發環境配置,使用開箱即用的 webpack-dev-server。
webpack 打包原理webpack 打包過程就像是一條流水線,從入口文件開始,蒐集項目中全部文件的依賴關係,若是遇到不可以識別的模塊,就使用對應的 loader 轉換成可以識別的模塊。webpack 還能使用 plugin 在流水線生命週期中掛載自定義事件,來控制 webpack 輸出結果。
五、編寫 npm script,一鍵開啓開發模式。
// cross-env 用來跨環境設置環境變量 "scripts": { "dev:client": "cross-env NODE_ENV=development webpack-dev-server --open" }
六、如今運行 npm run dev:client
就能夠愉快地編寫客戶端代碼了。
因爲 node 端使用了 typescript 和最新的 es 語法,因此須要進行打包編譯。
"scripts": { "dev:server": "cross-env NODE_ENV=development gulp & cross-env NODE_ENV=development supervisor -i ./dist/client/ -w ./dist/ ./dist/app.js", }
配置好 gulp 後,就能夠運行 npm run dev:server
一鍵啓動服務器端開發環境。
項目採用傳統的 mvc 模式進行層次劃分。
Model 層的主要工做:鏈接數據庫,封裝數據庫操做,例如:新增數據、刪除數據、查詢數據、更新數據等。
model 文件中包含對一個數據表的增刪改查操做。
Controller 層的主要工做:接收和發送 http 請求。根據前端請求,調用 model 層獲取數據,再返回給前端。
傳統的後端通常還包含 service 層,專門用來處理業務邏輯。
View 層的主要工做:提供前端頁面模板。若是是服務器端渲染,是將 model 層的數據注入到 view 層中,最後經過 controller 層返回給客戶端。因爲本項目前端使用 react 渲染,因此 view 層直接是通過 webpack 打包後的頁面。
GraphQL 是一種用於 api 的查詢語言,須要服務器端配置 graphql 支持,同時也須要客戶端使用 graphql 語法的格式進行請求。
使用 apollo 更快的搭建 graphql 環境。
服務器端配置 apollo-server。
客戶端配置 apollo-client。
MongoDB 是一個面向文檔存儲的數據庫,操做起來十分簡單。
Mongoose 爲 mongodb 提供了一種直接的,基於 scheme 結構去定義你的數據模型。它內置數據驗證,查詢構建,業務邏輯鉤子等,開箱即用。
接下來的步驟就是安裝 mongodb,啓動服務,就能夠了。
本項目使用 jest 做爲測試框架,jest 包含了斷言庫、測試框架、mock 數據等功能,是一個大而全的測試庫。因爲前端使用了 react 項目,這裏引入了專門用來測試 react 的 enzyme 庫。
一、新建 jest.config.js 文件。
配置初始化 setup.ts 文件。
配置測試文件的編譯方式。
二、編寫測試文件。
三、編寫測試腳本和上傳覆蓋率腳本。
"scripts": { "test": "jest --no-cache --colors --coverage --forceExit --detectOpenHandles", "coverage": "codecov" }
安裝好各類環境以後,接下來就要考慮項目上線了。
npm i pm2 -g
安裝免費 https 證書。letsencrypt 官網
本項目發佈很是簡單,只須要一步操做就搞定了,這些都是通過持續集成配置後的結果。
# clone with Git Bash git clone https://github.com/yhlben/cdfang-spider.git # change directory cd cdfang-spider # install dependencies npm i # build for production with minification npm run build
全部的事情都在 build 命令下完成了,咱們分析一下 npm run build 命令作的事情。
單元測試。
打包客戶端代碼。
上述事情經過建立 npm script 就能夠了完成需求了,但這些命令也不該該每次都由手工敲一遍,經過配置 travisCI,每一次 master 分支提交代碼時,自動運行上述命令就好了。
travisCI 是一個持續集成平臺,每當 github 提交代碼時,travisCI 就會獲得通知,而後根據 travisCI 中的配置信息執行相應的操做,並及時把運行結果反饋給用戶。travisCI 配置文件能夠參考項目根目錄下的 .travis.yml
文件。配置文件核心在於 script 的配置。
script: - npm run build - npm run test after_success: npm run coverage
能夠看到,每一次 github 提交後,travisCI 就會執行 名稱爲 build 的任務,任務分爲 2 個步驟,首先執行 build 命令,而後執行 test 命令,當命令都執行完成後,執行 coverage 命令。若是執行命令期間出現任何錯誤,travisCI 會經過郵件及時通知咱們。真正要上線時,先查看 ci 狀態,若是已經過全部的步驟,那就不用擔憂發佈的代碼有問題了。
至此,整個項目選型與搭建流程已經介紹完畢了,固然還有一些很細節的地方沒有寫進去,若是有不太明白的地方,能夠提 issue,或者加我微信 yhl2016226。
接下來對如下 4 個方面寫個小總結。
對於項目後期更新,主要是基於如下幾個方面:graphql,docker,k8s,微服務,serverless 等,東西太多,還得加油學習啊,😂