Java及Node.js對dependency module的不同管理方式

自己有玩過Java又玩過Node.js,兩者對於library dependency是頗不同的做法,這篇文是想講講兩者的分別。

Java

Java,多數是用maven or gradle來做library dependency management。
而我作為一個application developer,常常遇到一個問題:
我需要用到的libraries分別用到不同version的Spring或Jackson的不同version。
maven做法是會幫你resolve成同一個version。
但有時version conflict會出問題。

在Java裡面,不同library大多都是直接把class load到同一個class loader來用,所以不能存在multiple version的class。
很多時一些針對某些library來做的動作,都是直接hack/inject logic到那些class。

換句話說,Java的做法就像是有一個global空間,然後不同的library都放在裡面。
這樣把library都放在global空間好處就是,如果我是身為framework developer,這會較方便我去做middleware library,因為我可以直接掌控不同library。
而壞處就是,global空間如果library都各自有dependency,就很難統一manage,所以當library upgrade時就會較多問題/較痛苦。

Node.js

另一方面,Node.js的dependency management是另一種做法。
node.js裡,每個module之下都可以有自己的dependency及version。
如果你用上module A與module B而它們分別depends on module C的不同version,
那麼module A會在其下depends on它需要的module C的某version,
而module B會在其下depends on它需要的module C的另一個version。
兩個module分別用到自己需要的version,而不會conflict。

Node.js的做法,其實都是一個Global空間。
只是它容許不同module的不同version同時存在,而每個module都只會用到自己需要的version。
這樣的design的好處是,較易適應library的upgrade,upgrade的impact只會impact到adopt新version的module/code,而不是所有用某個module的module/code。

而這亦是為什麼node.js的開發能很快的其中一個原因。
因為module順手沾來就能用,較少機會會有module version conflict的問題。

不過Node.js這樣的design的short side是,假如我是framework developer,我就較難去建構middleware library。
我不是說你不能做middleware(express.js的那種),我是指你很難去針對其他library來作出一套全面掌控的framework library。
當然你不是真的不能,就像express.js那樣。
但express是較為多人adopt的web framework,而它本身也沒有很aggressive地去inject logic到其他library之上。

所以寫Node.js的話,如果你是app developer,你固然能把你到手的library都hack掉來for your usage。
但如果你是作為framework developer,你的心態就可能要調整一下,不要用寫java framework的心態及思維去做這件事。

Leave a Reply

Your email address will not be published.