文档章节

為什麼 Node.js 不適合大型和商業專案?

临江仙卜算子
 临江仙卜算子
发布于 05/25 15:22
字数 2007
阅读 28
收藏 2

JavaScript 和 Node.js 一直都是這幾年的話題,無論是前端還是後端,到處都可見 JavaScript,就好像爬滿了你全身上下,他們不斷地對你說道「嘿!老兄!快來用我吧!」。

為什麼 Node.js 會這麼夯?主要是因為效能快過於 PHP 和 Python 與 Ruby,寫法簡單又容易,而且前後端能夠使用同個語言當然是最好不過了。不過當然也有人簡單就是因為「潮」(嗨!歡迎加入潮流式驅動開發)。

但⋯⋯如果你只是因為這些原因而選用 Node.js,你可以考慮轉往其他語言了(甚至回到 PHP 和 Python 的懷抱),為什麼?這裡有幾點你需要考慮。

毫無結構性

事實上,Node.js 很適合小型和輕量級專案,但當結構越來越龐大的時候,你會遇上這件鳥事。沒錯,Node.js 是弱型態語言,這也令 Node.js 暴露在不具結構性的問題下,令開發者難以掌控物件所擁有的屬性為何、函式會回傳什麼內容。

就算你的編輯器支援了型態提示,多數情況下他們都是 any(任意),這根本沒有幫助。

說到這裡,你可能會想起 TypeScript,但那只是「一時之選」,用上 TypeScript 會使你的專案變得更加複雜,但結構變得更明確了。然而效能還是 Node.js,那麼為什麼不直接轉換到強型態語言呢?

原因很簡單,因為 Node.js 的生態完善,是其他語言所沒有的,但除此之外呢?沒了。

型態難以判斷

如果你曾去面試 Node.js 相關職位的工作,你可能會對 undefined == null 這個問題不陌生,而其答案是 true

沒錯,在 JavaScript 裡面你永遠無法預料兩個形態是否相等。當然,在你有不少採坑經歷之後這對你來說可能已經不成問題了。

在 CodeMash 2012 中 Gary Bernhardt 所演講的「Wat」影片透過有趣的方式點出了 JavaScript 的型態是很神奇的一件事情。

然後如果你不知道,JavaScript 還有 Set 跟 Map 型態

文件、註釋不易撰寫

撰寫 Node.js 的文件與註釋是個難題,比起文件,更多專案擁有的是 README,這讓初心者更好上手,但進階開發者則需要花上更多時間查找自己所需的函式。

至於什麼叫做註釋難以撰寫?通常撰寫 JavaScript 註釋的時候會遵循 JSDoc(或 APIDoc)的方式,像下面這樣。

/**
 * Hello 會透過 WebSocket 並向使用者傳遞指定的打招呼訊息。
 *
 * @param  {String} greeting - 欲發送的打招呼訊息。
 * @return {Boolean} 傳送是否成功。
 */

function Hello(greeting) {  
    // ...
    return true
}

看起來不成問題,對吧?很有條理,又很明確,然而在幾個星期後你就會發現不斷地標記函式的參數、回傳值是多麽累人的事情,過了不久,註釋就會跟不上函式真正的功能,當然你能說這是取決於工程師自己的怠惰,更多能說的是在 JavaScript 中,註釋其實沒有這麼好用。

設想一下你的函式會回傳一個物件,你可以保持勤勞,寫成這樣。

/**
 * @typedef  {Object} User
 * @property {String} nickname 暱稱。
 * @property {String} username 帳號。
 * @property {String} password 密碼。
 */
/**
 * Foo 會建立一個新的使用者並且回傳一個註冊後的使用者物件。
 * 
 * @param  {User} 來自表單的使用者物件。 
 * @return {User} 註冊後的使用者物件。
 */

function Foo(user) {  
    return {
        nickname: "",
        username: "",
        password: "",
    }
}

然後你就可以開始回想起你到底是在哪個文件中定義 User 這個物件了。所以更多時候我會直接打上 @return {Object} User 物件 然後叫其他開發者自己去看統一集中的文件,因為那樣還更好管理物件結構。

可用函式跟不上時代

如果你是個標準的 Node.js 工程師,你就會常常去看 Node Green,因為你永遠不知道 Node.js 到底支援了這個函式沒有。然而你會看到一堆紅色的錯誤表明尚未支援。

接著你就會抱頭痛哭,沒過多久,所有的專案都會直接使用 Babel,這能將尚未支援的函式轉換成相容舊 Node.js 的程式碼,但令程式更長。

套件佔了空間一大半

Node.js 的生態真的很好,然後你就會用上一堆 npm 裡的套件,接著發現 node_modules資料夾比起你的專案大概多用了二十幾倍的空間。

如果你有兩個專案,還會因為版本相容性的問題而多上另一個 node_modules 資料夾。順帶一提,現在有這麼多的 Electron 軟體,每個軟體都有 node_modules⋯⋯佔用了 100 MB 的空間但實際內容其實只有 10 MB。

額外一點,由於 Node.js 不是編譯式語言,所以當你需要部署 Node.js 專案到伺服器的時候,你還需要執行 npm install(或 yarn install)下載你專案所會用到的所有套件,這會額外花上兩分鐘左右的時間,更別說做持續整合測試了。

回呼地獄

這個問題存在很久了,回呼地獄(Callback Hell)在以前一直是個問題,你可能回想說,這不是早就被解決了嗎,像是透過 Q.jsAsync.js?對,但這還沒完。

回想起這個問題的歷史,一直到 jQuery 推出了 Deferred 才被解決,然後最終被一個 Promise 取代。但在那之後人們不滿又推出了基於 Promise 的 Async/Await,接著你就會發現因為有的人腦袋還跟不上,所以一個專案同時出現了 Callback 還有 Promise 跟 Async/Await。

Node.js 推出的新功能一直以來都是用膠帶在填補以往的坑,除非像 Python 2 到 Python 3 那樣的大轉變,否則這些坑可能都還會在吧。

多工異步麻煩

Node.js 預設就是一個程序只使用單個核心(這大概也是為什麼叫做 Node 的原因),不是很多人都有機會用到 Node.js 中的 Cluster 模塊,一但接觸之後,你就要開始區分 Master 跟 Worker 然後他們是怎麼互相溝通與聯繫的。

到目前為止我對 Node.js 如何發出多工請求、最終取得「所有多工的結果」還不是很清楚。但我能知道的是⋯⋯如果你會用上 Cluster,那麼你就會需要在初期時花上更多時間來有個周詳的規劃(就像規劃微服務那樣)。

後記與逃離 Node.js

其實原本還要寫上 Node.js 在測試方面上的問題,主要是因為 Node.js 沒有內建良好的測試工具與環境,導致需要額外花費時間處理像 Mocha 等⋯的設置問題,不過因為看了看發現已經寫夠多文字了,我想應該也不需要額外補上這一點啦⋯⋯。

不過這也不代表 Node.js 是完全不需要的,畢竟用在客戶端上還是十分地方便(例如 Webpack)。如果你正在考慮在後端使用另一個語言的話,不妨看看比起 Node.js 還要更快而且簡短的語言:Go。

Go 所內建的工具和環境令開發與測試十分容易,而且效能與部署也極快,撰寫 WebSocket 聊天室和 Node.js 相同,十幾行就能搞定了。如果你有興趣學習 Node.js 或者是其他語言(而且比較偏向 Web 服務的話),也可以參考看看。

本文转载自:https://yami.io/you-might-not-need-nodejs/

共有 人打赏支持
临江仙卜算子
粉丝 14
博文 279
码字总数 215289
作品 0
郑州
CEO
加载中

评论(7)

wuyaSama
wuyaSama

引用来自“临江仙卜算子”的评论

引用来自“wuyaSama”的评论

大写的摸你傻在背景。。。

引用来自“临江仙卜算子”的评论

读不懂,请说普通话

引用来自“wuyaSama”的评论

好吧,我以为是你自己截的图,第一张截图背景是东方project里面的角色,雾雨魔理沙:sweat:
原来这个角色叫雾雨魔理沙:fearful:才知道

23333 你搜索 东方project 小心入坑
临江仙卜算子
临江仙卜算子

引用来自“wuyaSama”的评论

大写的摸你傻在背景。。。

引用来自“临江仙卜算子”的评论

读不懂,请说普通话

引用来自“wuyaSama”的评论

好吧,我以为是你自己截的图,第一张截图背景是东方project里面的角色,雾雨魔理沙:sweat:
原来这个角色叫雾雨魔理沙:fearful:才知道
wuyaSama
wuyaSama

引用来自“wuyaSama”的评论

大写的摸你傻在背景。。。

引用来自“临江仙卜算子”的评论

读不懂,请说普通话
好吧,我以为是你自己截的图,第一张截图背景是东方project里面的角色,雾雨魔理沙:sweat:
临江仙卜算子
临江仙卜算子

引用来自“wuyaSama”的评论

大写的摸你傻在背景。。。
读不懂,请说普通话
wuyaSama
wuyaSama
大写的摸你傻在背景。。。
临江仙卜算子
临江仙卜算子

引用来自“hlStack”的评论

一派胡言
我这也是刚转载的文章,请理性斧正:clap:如果阁下有更高明的见解还希望不吝赐教
hlStack
hlStack
一派胡言
专访 OpenStack 主席 Alan Clark- 快速成长

下個月將滿3歲的開源雲端計畫OpenStack,已經有超過190家廠商加入,使用者社群也遍布全球,OpenStack快速成長將左右雲端產業的未來 OpenStack基金會主席Alan Clark:「我相信在未來的5年內,...

oschina
2013/06/26
1K
1
Laravel 的中大型專案架構

初學者學習 Laravel 時分兩種,一種是乖乖的將程式填入 MVC 架構內,導致 controller 與 model 異常的肥大,日後一樣很難維護;一種是常常不知道程式該寫在哪一個 class 內而猶豫不決,畢竟傳...

botkenni
2016/10/21
33
0
如何打造一個 Remote 工作的環境

如何打造一個 Remote 工作的環境 禮拜三跟 Teahour 的主持人玎玎和這期的嘉賓 Tinyfool 聊創業(會前會)。中間岔題講到 Tinyfool 開始想把自己的創業公司轉換成 Remote 工作環境。有過 Remo...

markYun
2013/08/08
0
0
官方的 OpenNMS® 安裝指南

OpenNMS安裝指南 < DOCMANAGER DOCUMENT START > THIS DOCUMENT IS FOR OpeNNMS 1.2! OpenNMS 1.6 IS VERY DIFFERENT, AND THIS INFO MAY NOT APPLY. OpenNMS® 安裝指南 安裝OpenNMS網管系統......

小编辑
2010/06/17
6K
1
OpenDarwin

OpenDarwin 是一種自由、多重平台的 BSD 和以 Mach 3.0 為基礎的 UNIX-like 作業系統。它有 PowerPC 和 IA32 架構的版本。 在 2002年4月 成立,OpenDarwin 專案的目標,是建立一個獨立的 Da...

匿名
2009/10/25
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7防火墙firewalld操作

firewalld Linux上新用的防火墙软件,跟iptables差不多的工具。 firewall-cmd 是 firewalld 的字符界面管理工具,firewalld是CentOS7的一大特性,最大的好处有两个:支持动态更新,不用重启服...

dingdayu
今天
1
0
关于组件化的最初步

一个工程可能会有多个版本,有国际版、国内版、还有针对各种不同的渠道化的打包版本、这个属于我们日常经常见到的打包差异化版本需求。 而对于工程的开发,比如以前的公司,分成了有三大块业...

DannyCoder
今天
2
0
Spring的Resttemplate发送带header的post请求

private HttpHeaders getJsonHeader() { HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); ......

qiang123
昨天
3
0
Spring Cloud Gateway 之 Only one connection receive subscriber allowed

都说Spring Cloud Gateway好,我也来试试,可是配置了总是报下面这个错误: java.lang.IllegalStateException: Only one connection receive subscriber allowed. 困扰了我几天的问题,原来...

ThinkGem
昨天
27
0
学习设计模式——观察者模式

1. 认识观察者模式 1. 定义:定义对象之间一种一对多的依赖关系,当一个对象状态发生变化时,依赖该对象的其他对象都会得到通知并进行相应的变化。 2. 组织结构: Subject:目标对象类,会被...

江左煤郎
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部