有了 Vue + Nginx,為什麼還要 Node?
vue也可以前後端分離,伺服器用nginx,為什麼要vue + node呢,既然有這種模式,一定有他的道理,有什麼特別的值得這麼做的麼,感覺vue+nginx用起來很簡單,如果vue+node就複雜了
@圓胖腫 真的說得不對,而且我看過他其他一部分回答,錯得比較離譜。以下引用,就是他的話:
歷史原因,以前沒有用javascript寫server的歷史
文不對題。在這裡vue+Nginx 為什麼還用 node 的原因並不只是什麼歷史原因。Nginx 作為反向伺服器存在的情況是非常多的,而且大部分 Nginx 並不提供邏輯處理,只做譬如負載均衡、流量控制、數據驗證、靜態伺服器等功能,雖然他也可以作為邏輯伺服器使用 Lua 去拓展他的模塊,但是這對於大部分人來說,並不會這麼去做,大部分人的做法是 Nginx 擋在前面作為一個負載均衡伺服器,後面的邏輯伺服器使用自己擅長的語言去實現邏輯,譬如:php,python,go,甚至是 c++(fast cgi)
Vue 配合 node 大部分的原因是因為
- 就目前而言,vue 對 node 的服務端渲染支持最好(反過來說就不準確了)。並不是說除了 node 以外就不能做服務端渲染了,只要你夠強,你可以使用 go 把 vue 的 js 邏輯跑一遍,只要能夠渲染出字元串,那你理論上來說用什麼語言都是無所謂的。但是 Node 天生 js,所以 Node 最方便。
- 某些 Vue 無法做到的事情,Node 可以做。沒錯,這部分不能做的事情就是伺服器邏輯,包括,數據存儲,數據緩存,用戶登錄鑒權等等等等..
- 前後統一語言,都是 JavaScript
搞清概念:什麼是 Vue + Nginx
Vue 只是一個 UI 層的框架,因此他打包出來的就是一套 UI 的靜態文件:html + js-bundle。對於靜態文件,其實 Node 也是可以處理的,但是鑒於 node 一般用來作為邏輯伺服器的存在,我們會把靜態伺服器放在 Nginx 這一層返回給用戶,因為 Nginx 在靜態文件處理上來說很專業,自帶的一些功能也非常多,譬如 Gzip 配置一下就可以了。
因此,這個層面來看,如果只是 Vue + Nginx 的話,你大概就能做出一個靜態的頁面,如果你想要動態的頁面,可能需要一個邏輯伺服器幫助你,那麼這個邏輯伺服器就是 Nodejs (當然也可以是其他任何語言,python 、Cc++、java、go)
伺服器到底多線程還是單線程?
還有一個就是node之前,server多數都是線程池的模式,一個請求對應一個線程處理
其實這麼說非常不準確。首先, I/O 操作分為 網路 IO 和 文件 IO,就目前操作系統的成熟度而言,只有網路 IO 是能夠單線程事件循環,文件 IO 暫時只能用線程池來模擬事件循環(協程就不說了,因為是另外的故事)。
也就是說,無論是 node 還是 libevent 還是什麼什麼的事件循環機制,都只是對 IO 做了一個封裝,使得不能單線程事件循環的文件 IO 通過多線程池模擬之後,擁有網路 IO 一樣的介面,那麼就可以把 IO 統一起來了。
所以,要說伺服器沒有多線程,其實是假的,無論是 Node 還是 Nginx,都是有多線程的,只是 Node 的多線程不提供多線程的介面給用戶調用(當然新版本的可以了)。
Node 開創了什麼歷史?
node做出了eventloop+non blocking api的模式,開創了一種新的線程模型
所以在原理上也有開創性
還是錯的。 eventloop+non blocking api 的模式其實早在 select 這個函數出現的時候就已經有了,只是寫起來很不方便,而且我在以前說過,程序員一旦有了同步的介面就懶得用非同步介面了。
select 這個函數是最早的提供網路io 非同步的函數,這個函數出現於1980年,在那個時候,40年前,就出現了 eventloop+non blocking api 的模式。只不過 select 的做法其實是很笨的(遍歷文件描述符表),轉而後來有了 epoll 以後(使用 hash map),這種情況纔得到了改觀,使得 C10K問題再也不是問題。
那麼,Node 開創了什麼歷史?
- 使得 JavaScript 變成了伺服器語言
- 更方便的寫非同步回調(注意是更方便,不是開創)
真正的歷史
那等到nginx等其他server軟體抄過去,那是以後的事了
服了,不懂裝懂的典範。
1980年,人們意識到了 prefork 模型已經不能跟上當時的網路 io 節奏,因此發明瞭一個叫做 select 的函數,這個玩意當時叫做 IO 多路復用,也是早期事件循環。select 之後又出了一個優化版本叫做 poll。這兩個函數一直統治了網路編程界長達20來年。
2002年,全球爆發性的互聯網增長,出現了著名的 C10k 問題。人們開始將實現非常笨拙的 select/poll 從遍歷文件描述符表,換成了 Hash-map,使得網路非同步 IO性能發生了根本性的提升。
Nginx 出現於2004年,使用的就是 epoll 為主的非同步iO 手段。那時候 Ry 也在研究 nginx,在做 node 之前 nodejs之父 ry 就是一個 c++ 的伺服器編程高手,因為厭倦了c/c++ 的非同步編程模式,開始尋求另一個出路。
2008年,谷歌發布了 V8 引擎,ry 當時發現 v8 是一個非常不錯的 JavaScript 虛擬機,快!夠快!非常快!而且相比於其他語言來說,JavaScript 是單線程而且使用人數巨大,而且在服務端是空白的。因此愣頭青 ry 一把投入了封裝 V8 之旅中,2009年,Node.js 橫空出世,使得 JavaScript 變成了服務端語言,大獲成功。
很不幸,2012年,ry 移情別戀,跑去玩 Go 去了,留下 nodejs 一堆的問題沒有解決,交給了社區。
2017年,社區將 async/await 引入,解決了 node 回調地獄的問題,越來越多的前端框架使用 node 作為文件處理工具/前端渲染伺服器,使得 node 在前端的地位不可替代。
2018年,ry 發布 deno ,試圖使用 TypeScript 解決 node 沒能解決的問題。
最後
不懂裝懂很可怕,誤人子弟更可怕。
前後端分離,是展現層和後端業務邏輯層的分離,不是前端代碼和伺服器的分離。任何前端框架都可以實現前後端分離,不是 Vue 的專利。
SSR,由於技術方案的限制,Vue 的 SSR 必須依賴於 Node。但在這種模式下是不是前後端分離的,還得參考第一段,有的項目是非前後端分離的,但是是 SSR 的。
純靜態的前端,題主所說的 Vue 和 Nginx 組合屬於這種範疇,很多答主也說了,直接把這些純靜態的資源丟在 CDN 也是可以的。
上面這三個,沒有絕對的區別,不是一個層次的概念,別混為一談。
這個問題其實和 Vue 無關,如大家所說,應該是動態應用和靜態應用的抉擇問題。
我可以假設題主沒有 SSR(服務端渲染)的需求,否則這些現代框架對 Node 基本就是強依賴。
折中方案
我要引出的是一個折中的簡單方案,可能可以解答題主的一些疑惑。如果只是 CSR(客戶端渲染),很多回答中提到的服務端需要的:
- 自定義路由
- 用戶態
- https 控制
- 重定向
- 404 或 error_page 等
- html5 history fallback(為了 serve SPA)
- 灰度和AB
等等動態邏輯其實都是業務無關的通用功能,並不需要在每個Node應用中重複實現,我們很容易想到可以將這些邏輯抽到獨立一層網關(Gateway)實現,並針對每個靜態應用進行配置控制: