如今的 Node 對於前端而言能夠涵蓋各個方面,包括命令行接口、插件、依賴庫、腳手架以及 Web 服務等。本文是一篇對於 Node 使用的淺談文章,會簡單講解一些我的使用 Node 的經驗,分享的內容主要可分爲三個方面:javascript
工具篇會講解使用 NPM 發佈命令行接口的簡單教程。插件篇主要講述如何開發一個有趣的 Webpack 插件(Vue CLI / Babel 插件同理)。服務篇會講解一些基於 Express 應用框架的技術選型方案,這類技術每每對於作一些前端工具平臺很是有用(例如 Mock 平臺、多語言平臺等,每每可配合命令行接口進行設計)。因爲篇幅較長,本文只講解服務篇內容。css
舒適提示:這裏的服務篇主要講解了一些本身搭建 Express 應用的經驗,是本身學習 Node 的一個過程。你們若是喜歡折騰或者想作一些前端的工具平臺能夠按照這種思路去嘗試,可是若是要作業務項目,你們仍是要選擇一些成熟穩定的技術方案,考慮的方面須要更多。html
基於 Node.js 的 Web 應用框架不少,包括但不限於前端
這裏盜一張 2019 Node.js Frameworks star 狀況(供你們參考):java
本文主要講解 Express 應用框架,雖然它提供的能力很是簡單,但對於一些工具平臺的開發徹底能夠勝任,而且能夠寫出各類千奇百怪的 MVC 模式(若是對服務端 MVC 不是很清晰能夠閱讀 服務端 MVC 之 Model2 的衍生)。這裏簡單介紹之前設計的幾種基於 Express 擴展的技術選型方案,剛好涵蓋了 React、Angular 以及 Vue 這三個 Web 前端框架。node
舒適提示:接下來使用的示例項目都相對簡單,但願對剛入門 Express 的小白們有所啓示。react
2016年7月到10月,從零開始學習 React 並使用 React 設計了服務端渲染的 Express 應用(同年10月25日誕生了 Next.js ),大體的技術選型以下:webpack
因爲對 React 不是很熟悉,首先實現了單頁應用,而後實現了服務端渲染應用。ios
在使用 React 以前只會簡單的使用 Bootstrap,當時對 React 的學習歷程大體以下:git
學習總結文檔以下:
以上學習過程記錄在 react-demo 和 react-start-kit (小而全的概念性參考價值)中,此時只是簡單的 React 單頁應用設計過程。大體結構以下:
舒適提示:在先後端分離的開發模式中,若是 Web 前端實現的是 SPA(單頁應用),服務端能夠選用不一樣的設計語言,例如 Node.js、Java 或者 Golang 等。Web 前端能夠經過 Express渲染服務器 進行後端的請求代理轉發。若是想要前端先行,可使用 Easy Mock 或者本身設定的 JSON 數據模擬後端提供的接口規範。
服務端的設計選用 Node.js 的 Express 框架,大體實現步驟以下:
以上實現過程記錄在一個簡單的示例 rewatch 裏,入口文件是 app.js
。此時先後端分離,能夠同時啓動服務端 Express 服務和啓動開發態 React 調試頁面服務(webpack-dev-server),並使用開發態頁面向 Express 服務發送請求獲取接口數據(當時使用 JQuery 的$.ajax
發送請求)。設計完成後將開發態頁面使用 Webpack 打包構建,構建目錄爲服務端 Express 的靜態資源目錄。首屏渲染的工做交給 Ejs 模板引擎(事實上也能夠直接使用 HTML 字符串渲染)進行處理。大體結構以下:
單頁應用在路由跳轉時不須要額外的請求靜態資源,能夠提高用戶的體驗。可是若是應用較大,首次請求靜態資源和進行頁面動態渲染的過程當中會產生如下問題:
爲了解決上述客戶端的渲染問題,須要實現 React 服務端渲染。因爲當時還沒出現成熟的服務端渲染應用框架,所以只能本身摸索構建 React 服務端渲染方案:
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)
複製代碼
2016年10月到2017年3月,使用 Angular 設計了一個 Express 應用,大體的技術選型以下:
這是一個簡單的服務端多頁應用示例,使用 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 模型,通常都須要配合模板引擎進行設計。
2018年6月,使用 Vue 設計了服務端渲染的 Express 應用,大體技術選型以下:
該技術選型最主要的特色以下:
在 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 應用時至少須要考慮如下幾個方面:
$.ajax
對於 Express 新手而言,能夠先嚐試多頁應用 + MongoDB + 模板引擎 + JQuery 的選型方案:
若是前端框架選型是 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 進行服務端構建。
舒適提示:主流框架的應用設計和簡單的起手式不一樣,先後端開發能夠徹底分離,這樣的應用設計大大解放了前端的生產力(前端再也不受限於服務端的模板引擎)。例如目前的主流框架設計的一些腳手架,能夠優雅的將 Webpack 配置,開發態渲染服務器以及請求代理結合在一塊兒,作到開箱即用,提高用戶的開發體驗。
Hi,你們好,咱們是阿里巴巴新成立的 BU 政務釘釘事業部(杭州同窗在用的健康碼是我 BU 聯合其餘 BU 共同設計的一個項目),目前還有大量的 Web 前端職位空缺。但願想找我內推或者想了解更多招聘信息的同窗能夠加我微信:18768107826