幽靈依賴
簡單講,就是包的依賴不需要指定版本。比如你封裝了一個(gè)工具包ABC,該包的package.json在開發(fā)期間依賴了React/moment/dayjs等第三方庫,但實(shí)際發(fā)布到倉庫時(shí)可以從devDependencies、dependencies字段中移除掉這些依賴,但實(shí)際項(xiàng)目import "ABC"使用時(shí)并不會(huì)報(bào)錯(cuò),被包ABC被丟掉的這些依賴叫幽靈依賴。
npm
npm支持幽靈依賴,只要你的項(xiàng)目package.json中有聲明并安裝這些依賴包即可,開發(fā)工具包不需要指定任何依賴。node的包尋址方式從引用文件所在目錄開始,往上不斷找node_modules文件夾,由于npm使用扁平化的方式管理包,所以一定能尋址到node_modules文件夾。
pnpm
pnpm幽靈依賴支持方式比較繞。pnpm一般用于多項(xiàng)目整合(monorepo),用例代碼會(huì)單獨(dú)拆成一個(gè)子項(xiàng)目,使用pnpm開發(fā)工具包項(xiàng)目必須指定包的版本,否則用例項(xiàng)目引用工具包項(xiàng)目會(huì)出現(xiàn)Can't resolve XXX報(bào)錯(cuò)。原因在于pnpm使用軟連接重定向了node的包尋址,直接重定向到工具包項(xiàng)目的源代碼目錄,如果你的工具包項(xiàng)目node_modules中使用幽靈依賴方案,就會(huì)直接拋異常,因?yàn)楦鱾€(gè)子項(xiàng)目的目錄結(jié)構(gòu)是平行的,往上尋址就會(huì)到達(dá)根目錄。
解決
使用pnpm開發(fā),如果工具包子項(xiàng)目必須指定依賴版本,但用例項(xiàng)目又指定依賴版本,就會(huì)造成依賴的實(shí)現(xiàn)差異,這是填了舊坑結(jié)果又引出新坑?實(shí)際上pnpm把所有包都放到了根項(xiàng)目node_modules/.pnpm目錄中,只要你在根項(xiàng)目(項(xiàng)目最外層文件夾)install幽靈依賴,就會(huì)命中依賴。如果工具包被發(fā)布到倉庫,從線上install,那么會(huì)被安裝到根項(xiàng)目node_modules/.pnpm目錄中,幽靈依賴也會(huì)命中。