- 工具篇
- 插件篇
- 服務篇
工具篇會講解使用 NPM 發佈命令行接口的簡單教程。插件篇主要講述如何開發一個有趣的 Webpack 插件(Vue CLI / Babel 插件同理)。服務篇會講解一些基於 Express 應用框架的技術選型方案,這類技術每每對於作一些前端工具平臺很是有用(例如 Mock 平臺、多語言平臺等,每每可配合命令行接口進行設計)。因爲篇幅較長,本文只講解服務篇內容。javascript
舒適提示:css
1.這裏的服務篇主要講解了一些本身搭建 Express 應用的經驗,是本身學習 Node 的一個過程。你們若是喜歡折騰或者想作一些前端的工具平臺能夠按照這種思路去嘗試,可是若是要作業務項目,你們仍是要選擇一些成熟穩定的技術方案,考慮的方面須要更多。
2.不要在博客私信我、你們有問題或者交流經驗能夠來個人扣扣裙 519293536 找 我 都會盡力幫你們哦html
Web 應用框架
基於 Node.js 的 Web 應用框架不少,包括但不限於前端
- Express : 已經成爲開發 Node.js WEB 應用的標準框架,大多數工程師都很熟悉他的設計思想(極簡的內核,但能讓你用各類中間件來擴展他的功能)
- Koa :設計思想很是相似 Express,區別在於它是使用 ES6 中的 generator 編寫,這種寫法解決了你們所熟知的回調地獄問題
- Feathers:用來實現面向服務架構的一種靈活的解決方案,很是適合建立 Node.js 微服務
- Sails :是一個全能的 MVC 框架,主要是受到 Ruby on Rails 啓發,已經存在很長時間,支持各類數據庫,不論是 SQL 仍是 No-SQL
- Egg :爲企業級框架和應用而生
- Modal:建立基於 PostgreSQL 的無狀態的、分佈式的服務
- Keystone:快速搭建基於 MongoDB 的管理後臺的最佳解決方案,基於數據模型的定義便可自動生成後臺界面,支持常見的增刪改查操做和靈活的數據過濾
- Loopback:內置了不少特性的成熟框架,支持基於 token 的認證,支持各類數據庫。 loopback 的「殺手鐗」功能是 API 瀏覽器,該功能能讓開發者用很是直觀的方式查看全部的 API 接口,若是你須要建立 API 服務的話,它無疑是個很好的選擇
這裏盜一張 2019 Node.js Frameworks star 狀況(供你們參考):java
本文主要講解 Express 應用框架,雖然它提供的能力很是簡單,但對於一些工具平臺的開發徹底能夠勝任,而且能夠寫出各類千奇百怪的 MVC 模式(若是對服務端 MVC 不是很清晰能夠閱讀 服務端 MVC 之 Model2 的衍生)。這裏簡單介紹之前設計的幾種基於 Express 擴展的技術選型方案,剛好涵蓋了 React、Angular 以及 Vue 這三個 Web 前端框架。
舒適提示:接下來使用的示例項目都相對簡單,但願對剛入門 Express 的小白們有所啓示。node
React 技術方案選型
2016年7月到10月,從零開始學習 React 並使用 React 設計了服務端渲染的 Express 應用(同年10月25日誕生了 Next.js ),大體的技術選型以下:react
- Bootstrap
- React
- Mongoose
- Webpack
- Karma/Chai
因爲對 React 不是很熟悉,首先實現了單頁應用,而後實現了服務端渲染應用。webpack
實現 React 單頁應用(SPA)
React 學習和設計過程
在使用 React 以前只會簡單的使用 Bootstrap,當時對 React 的學習歷程大體以下:ios
- 學習 React 語法
- 學習 ES6 / ES7 語法
- 學習 Babel / Webpack,打包代碼支持 ES6 / ES7 / JSX 語法
- 學習 webpack-dev-server / Hot Module Replacement,啓動開發環境的 Express 服務,實現熱加載功能
- 學習 flux / react-redux
- 學習 react-router
- 學習 mocha / karma
學習總結文檔以下:git
以上學習過程記錄在 react-demo 和 react-start-kit (小而全的概念性參考價值)中,此時只是簡單的 React 單頁應用設計過程。大體結構以下:
舒適提示:在先後端分離的開發模式中,若是 Web 前端實現的是 SPA(單頁應用),服務端能夠選用不一樣的設計語言,例如 Node.js、Java 或者 Golang 等。Web 前端能夠經過 Express渲染服務器 進行後端的請求代理轉發。若是想要前端先行,可使用 Easy Mock 或者本身設定的 JSON 數據模擬後端提供的接口規範。
Express 服務端設計過程
服務端的設計選用 Node.js 的 Express 框架,大體實現步驟以下:
- 搭建服務端 Express,設計服務端 MVC 目錄結構
- 設置 Express 的靜態資源目錄,將 Web 前端的 Webpack 構建目錄設置成 Express 的靜態資源目錄
- 設置單頁應用的路由和路由服務
- 啓動服務查看頁面是否能夠渲染成功
以上實現過程記錄在一個簡單的示例 rewatch 裏,入口文件是 app.js
。此時先後端分離,能夠同時啓動服務端 Express 服務和啓動開發態 React 調試頁面服務(webpack-dev-server),並使用開發態頁面向 Express 服務發送請求獲取接口數據(當時使用 JQuery 的$.ajax
發送請求)。設計完成後將開發態頁面使用 Webpack 打包構建,構建目錄爲服務端 Express 的靜態資源目錄。首屏渲染的工做交給 Ejs 模板引擎(事實上也能夠直接使用 HTML 字符串渲染)進行處理。大體結構以下:
實現 React 服務端渲染(SSR)
單頁應用在路由跳轉時不須要額外的請求靜態資源,能夠提高用戶的體驗。可是若是應用較大,首次請求靜態資源和進行頁面動態渲染的過程當中會產生如下問題:
- 首屏加載慢,產生白屏效果
- 不利於 SEO
爲了解決上述客戶端的渲染問題,須要實現 React 服務端渲染。因爲當時還沒出現成熟的服務端渲染應用框架,所以只能本身摸索構建 React 服務端渲染方案:
- 爲了實現先後端代碼同構,須要對服務端代碼進行 Webpack 打包配置
- 使用 script 標籤以及全局變量的形式實現先後端
react-redux
數據store
的統一(這個印象深入,當時思索了好久)
使用了服務端渲染方案後,能夠去除以前的 Ejs 模板引擎,當時設計的大體結構以下:
當頁面發送路由請求時,Express 服務端使用
react-router
匹配相應路由對應的 React 組件實例並調用 renderToString
方法進行服務端頁面渲染(實現頁面的局部刷新)。當頁面渲染完成後,由 React 打包後的靜態資源對頁面進行 hydrate 處理。此時的 React 代碼是同構的,所以須要注意哪些會運行在服務端,哪些會運行在客戶端。同時服務端須要對同構代碼進行Webpack 打包處理。
以上實現記錄在示例 rewatch 中,入口文件是 server.js
,因爲文件比較混亂(把客戶端渲染和服務端渲染的示例放在了同一個文件項目中),這裏給出另一個很是簡單的示例 rewatch-server-render,項目目錄結構以下:
.
├── public # 靜態資源目錄
│ └── js
│ ├── bundle.js # react 目錄打包文件
│ ├── common.js # react 目錄打包公共文件
│ ├── react-dom.min.js # react 庫文件
│ └── react.min.js # react 庫文件
├── react # react 同構代碼目錄(沒有 react-router,能夠查看 rewatch 示例)
│ ├── actions
│ ├── components
│ ├── containers
│ ├── reducers
│ ├── store
│ └── index.js
├── server # 服務端
│ └── routes # 服務端路由(沒有使用 react-router 同構,能夠查看 rewatch 示例)
├── server.js # 開發態服務入口文件
├── server.bundle.js # 生產態服務入口文件
├── webpack.browser.config.js # 靜態資源打包的 webpack 配置(目標文件 bundle.js、common.js)
└── webpack.node.config.js # 服務端打包的 webpack 配置(目標文件 server.bundle.js)
複製代碼
Angular 技術方案選型
2016年10月到2017年3月,使用 Angular 設計了一個 Express 應用,大體的技術選型以下:
- Ejs
- Bootstrap
- Angular-Chart
- Mongoose
- Redis
- Sokect.io
這是一個簡單的服務端多頁應用示例,使用 Ejs 模板引擎進行頁面渲染,渲染完成後交由 Anguar 進行頁面的響應操做(發送請求使用 Angular 內置的 $http
服務)。該示例不須要額外的 Webpack 配置,只須要啓動 Express 服務自己渲染設計便可。目錄結構以下:
.
├── client # 靜態資源目錄
│ ├── css/ # 樣式
│ ├── imgs/ # 圖片
│ ├── js/ # 腳本
│ │ ├── angular/ # angular應用
│ │ │ ├── controllers/ # angular控制器
│ │ │ ├── services/ # angular服務
│ │ │ └── webapp.js/ # angular自動引導應用程序
│ │ └── sockets/ # sockets應用
│ └── lib # 插件(包括angualr、bootstrap/bootstrap-table、chart等)
├── config # 配置(包括Redis、Mongoose配置)
│ ├── config.js # 參數配置
│ └── index.config.js # 導出配置
├── server # 服務端
│ ├── constants/ # 常量
│ ├── controllers/ # 控制器
│ ├── events/ # 事件
│ ├── models/ # 模型
│ ├── routes/ # 路由
│ ├── sockets/ # socket.io
│ ├── pubs/ # Redis發佈
│ └── subs/ # Redis訂閱
├── views # 視圖(使用Ejs模板引擎)
└── app.js # 服務入口文件
複製代碼
舒適提示:這種多頁應用框架是自然的 SSR 模型,通常都須要配合模板引擎進行設計。
Vue 技術方案選型
2018年6月,使用 Vue 設計了服務端渲染的 Express 應用,大體技術選型以下:
- Mongoose
- Nuxt
- Vue
- lokka
- Muse-UI
- 客戶端和服務端同構代碼的 Webpack 配置由 Nuxt 封裝
- 服務端 Backpack 配置
該技術選型最主要的特色以下:
- 支持服務端渲染
- 支持 Graphql 查詢語言
- 先後端統一 TypeScript 語法
選型詳細說明
- 爲了支持 Graphql 查詢語言,服務端選擇使用支持 Express 中間件擴展的 graphql-yoga。
- 客戶端的 HTTP 請求須要符合 Graphql 請求格式,一種方式是使用 axios 等模擬 Graphql 的請求格式,另一種方式是選用支持Graphql 請求格式的請求庫,這裏選用 lokka 做爲 Graphql 客戶端的請求庫。
- 爲了快速設計頁面,選用了基於 Vue 2.0 的 Material Design UI 組件庫 Muse-UI。
- 選用了 Nuxt 做爲服務端渲染的中間件(基於 Vue.js 的通用應用框架,預設了服務端渲染應用所須要的各類配置)。
- 爲了支持客戶端 TypeScript 語法,須要擴展 Nuxt 的默認 Webpack 配置,利用 Nuxt 的模塊/註冊自定義loaders配置 ts-loader,配合 nuxt-property-decorator 實現客戶端 TypeScript 語法。
項目目錄結構
在 Nuxt 的目錄結構中,服務端引入的同構代碼放在.nuxt
目錄中,是 Webpack 打包後的代碼文件,所以若是服務端不使用特殊的語法,徹底不須要 Backpack 配置。此項目爲了支持服務端 TypeScript 語法,使用 Backpack 對服務端代碼進行構建(不影響同構部分代碼的構建,同構代碼在 Nuxt 裏是經過讀取文件的方式獲取)。
.
├── .nuxt # Nuxt構建目錄(Nuxt預設目錄)
├── assets # 資源目錄(Nuxt預設目錄)
│ ├── img # 圖片
│ ├── icon # 圖標
│ └── style # 樣式
├── build # 配置(包括Redis、Mongoose配置)
│ └── main.js # 服務端Backpack構建的目標啓動入口文件
├── common # 先後端通用
│ ├── constants/ # 常量
│ └── types/ # TypeScript接口
├── components # 組件目錄(Nuxt預設目錄)
├── constants # 前端常量目錄
├── docs # 文檔目錄(渲染.md文件)
├── graphql # 前端Graphql請求接口
├── layouts # 佈局目錄(Nuxt預設目錄)
├── middleware # 中間件目錄(Nuxt預設目錄)
├── mixins # 全局mixins
├── modules # Nuxt模塊(TypeScrpt的Webpack配置擴展)
├── pages # 頁面目錄(Nuxt預設目錄)
├── plugins # 插件目錄(Nuxt預設目錄)
├── server # 服務端目錄
│ ├── constants/ # 常量
│ ├── database/ # 數據庫模型
│ ├── express/ # 服務對外的公共API接口
│ │ ├── controllers/ # 控制器
│ │ ├── routes/ # 路由
│ │ └── services/ # 服務
│ ├── graphql/ # 服務內部的Graphql查詢接口
│ │ ├── middlewares/ # Graphql中間件
│ │ ├── resolvers/ # Graphql Resolver
│ │ ├── schemas/ # Graphql Schema
│ │ └── index.ts # graphql接口入口文件
│ ├── types/ # TypeScript接口
│ ├── utils/ # 工具方法
│ └── index.ts # 服務端入口文件(Backpack構建入口地址)
├── static # 靜態文件目錄(Nuxt預設目錄)
├── store # Vuex目錄(Nuxt預設目錄)
├── utils # 客戶端工具方法
├── .cz-config.js # cz提交配置文件
├── .env # 環境變量
├── .gitignore # Git忽視文件
├── .huskyrc # Git鉤子配置文件
├── .vcmrc # cz校驗配置
├── app.html # html文件
├── backpack.config.js # Backpack配置文件
├── CHANGELOG.md # 升級日誌
├── ecosystem.config.js # PM2啓動配置文件
├── index.d.ts # TypeScript聲明文件
├── nuxt.config.js # Nuxt配置文件
├── package.json # 項目描述文件
├── README.md # 說明
├── tag.bat # 項目打Tag腳本
└── tsconfig_node.json # TypeScript配置文件
複製代碼
運行腳本設計
在package.json
中的配置腳本以下:
"build": "cross-env NODE_ENV=production nuxt build && backpack build", "pm2": "pm2 start ecosystem.config.js", "pm2:stop": "pm2 stop ecosystem.config.js", "dev:client": "cross-env NODE_ENV=development DEV_TYPE=nuxt ts-node --compiler ntypescript --project tsconfig_node.json ./server", "dev:server": "cross-env NODE_ENV=development DEV_TYPE=server ts-node-dev --compiler ntypescript --project tsconfig_node.json ./server" 複製代碼
build
:使用 Webpack 構建 Nuxt 資源包以及使用 Backpack 構建服務端入口文件(轉義 TypeScript)pm2
:以生產模式啓動一個進程守護的 Web 服務器pm2:stop
:中止運行 Web 服務器dev:client
:啓動開發態熱部署前端渲染服務dev:server
:啓動開發態熱啓動服務端服務
雖然是服務端渲染框架(理論上能夠一我的開發項目,啓動一個熱加載的服務端命令便可),可是在開發的過程當中考慮到多人協做以及開發的便利性仍然將客戶端和服務端進行分離。
在服務端配置 Nuxt 的 Builder
會致使服務端熱加載過慢,所以將服務端 Nuxt 的 Builder
過濾掉,使用 ts-node-dev 作服務端熱啓動。在客戶端使用 ts-node 啓動服務,經過識別 DEV_TYPE
環境變量加載Nuxt的 Builder
,實現 Web 前端的熱加載功能。須要注意客戶端向服務端發送請求是跨域的,所以在服務端的開發態環境須要配置容許跨域。
舒適提示:一個服務端渲染框架楞是讓我拆成了先後端開發分離的框架模式。
最後
設計了以上三個方案後,發現從零開始構建一個 Express 應用時至少須要考慮如下幾個方面:
- 數據庫( MongoDB / MySql 等)選型
- 是否須要模板引擎以及模板引擎( Ejs / Jade 等)選型
- 前端框架( JQuery / Angular / React/ Vue 等)選型
- HTTP 請求庫(axios / request / superagent 等)選型
- 是否須要 UI 組件庫以及 UI 組件庫選型
- 客戶端是否須要 Webpack 構建
- 服務端是否須要 Webpack / Backpack 構建
- 其餘(session、redis、socket.io 等)
- 性能、監控等
簡單的起手式
- MongoDB
- Ejs 模板引擎
- JQuery
- JQuery 內置的
$.ajax
- Bootstrap(可選)
- 客戶端和服務端都不須要 Webpack 配置
對於 Express 新手而言,能夠先嚐試多頁應用 + MongoDB + 模板引擎 + JQuery 的選型方案:
- 使用 Ejs 模板引擎須要額外瞭解 Ejs 語法,可是語法相對簡單,學習成本低。
- 使用 JQuery 不須要考慮 HTTP 請求庫選型,JQuery 內置了 HTTP 請求的 API。
- 若是對於頁面佈局以及樣式設計不熟悉,能夠考慮選用 Bootstrap 前端框架。
- 不須要深刻了解 ES6 / ES7 / JSX 等語法,所以不須要學習和使用 Webpack 配置。
- 使用 Ejs 模板引擎進行渲染的 Express 應用,是自然的服務端渲染應用。
主流框架的應用設計
- MongoDB
- 無需模板引擎
- React / Vue 等
- axios / request / superagent 等
- Ant Design / Ant Design Vue / Element / Muse-UI 等
- 客戶端 Webpack 配置
- 服務端是否須要 Webpack / Backpack 配置依據狀況而定
若是前端框架選型是 React 或 Vue(一般是單頁應用設計),而且須要使用 ES6 / ES7 / JSX 以及 Vue 的 SFC 格式等語法,那麼Web前端勢必要設計 Webpack 的構建配置,此時可使用相似於 webpack-dev-server
的 Express 開發態渲染服務器設計和調試開發態前端頁面。固然目前的 Web 前端開發針對不一樣的前端框架都有本身設計的腳手架,所以能夠直接使用腳手架進行開發設計和靜態資源構建。同時若是框架中沒有內置 HTTP 請求庫,能夠本身封裝或者使用一些成熟的 HTTP 庫,例如axios、request以及superagent等。若是須要使用 UI 組件庫進行頁面設計,能夠根據使用的框架進行 UI 組件庫選型,例如 React 的 Ant Design、Vue 的 Element 等。Express 服務端的設計因爲使用了主流框架的動態渲染能力,所以能夠去除模板引擎渲染功能。若是想支持 Node.js 不支持的 ES6 / ES7 / TypeScript 語法等,那麼須要 Backpack 進行服務端構建。
舒適提示:不要在博客私信我,你們有問題或者交流經驗能夠來個人扣扣裙 519293536 找 我 都會盡力幫你們哦
本文的文字及圖片來源於網絡加上本身的想法,僅供學習、交流使用,不具備任何商業用途,版權歸原做者全部,若有問題請及時聯繫咱們以做處理