前言
現在的 Node 對于前端而言可以涵蓋各個方面,包括命令列介面、插件、依賴庫、腳手架以及 Web 服務等,本文是一篇對于 Node 使用的淺談文章,會簡單講解一些個人使用 Node 的經驗,分享的內容主要可分為三個方面:
- 工具篇
- 插件篇
- 服務篇
工具篇會講解使用 NPM 發布命令列介面的簡單教程,插件篇主要講述如何開發一個有趣的 Webpack 插件(Vue CLI / Babel 插件同理),服務篇會講解一些基于 Express 應用框架的技術選型方案,這類技術往往對于做一些前端工具平臺非常有用(例如 Mock 平臺、多語言平臺等,往往可配合命令列介面進行設計),由于篇幅較長,本文只講解服務篇內容,
溫馨提示:
1.這里的服務篇主要講解了一些自己搭建 Express 應用的經驗,是自己學習 Node 的一個程序,大家如果喜歡折騰或者想做一些前端的工具平臺可以按照這種思路去嘗試,但是如果要做業務專案,大家還是要選擇一些成熟穩定的技術方案,考慮的方面需要更多,
2.不要在博客私信我、大家有問題或者交流經驗可以來我的扣扣裙 519293536 找 我 都會盡力幫大家哦
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 情況(供大家參考):

本文主要講解 Express 應用框架,雖然它提供的能力非常簡單,但對于一些工具平臺的開發完全可以勝任,并且可以寫出各種千奇百怪的 MVC 模式(如果對服務端 MVC 不是很清晰可以閱讀 服務端 MVC 之 Model2 的衍生),這里簡單介紹以前設計的幾種基于 Express 擴展的技術選型方案,恰好涵蓋了 React、Angular 以及 Vue 這三個 Web 前端框架,
溫馨提示:接下來使用的示例專案都相對簡單,希望對剛入門 Express 的小白們有所啟示,
React 技術方案選型
2016年7月到10月,從零開始學習 React 并使用 React 設計了服務端渲染的 Express 應用(同年10月25日誕生了 Next.js ),大致的技術選型如下:
- Bootstrap
- React
- Mongoose
- Webpack
- Karma/Chai
由于對 React 不是很熟悉,首先實作了單頁應用,然后實作了服務端渲染應用,
實作 React 單頁應用(SPA)
React 學習和設計程序
在使用 React 之前只會簡單的使用 Bootstrap,當時對 React 的學習歷程大致如下:
- 學習 React 語法
- 學習 ES6 / ES7 語法
- 學習 Babel / Webpack,打包代碼支持 ES6 / ES7 / JSX 語法
- 學習 webpack-dev-server / Hot Module Replacement,啟動開發環境的 Express 服務,實作熱加載功能
- 學習 flux / react-redux
- 學習 react-router
- 學習 mocha / karma
學習總結檔案如下:
- Webpack
- Server
- React-Redux
- React-Router
- Mocha
- Karma
以上學習程序記錄在 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 找 我 都會盡力幫大家哦
本文的文字及圖片來源于網路加上自己的想法,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/62344.html
標籤:JavaScript
