:::

Node.js找不到模組?在npm-link底下的處理方法 / How to Handle "Module not found" Error from Modules installed from npm-link?

16-Node_js_npm_link_How_to_Handle_Module.png

Node.js的專案不可或缺的就是豐富的套件。為了避免各個專案重複安裝套件而佔用硬碟大量的空間,我會選擇將套件安裝在全域目錄(global),然後用連結(symlink)的方式放到各自專案底下。這種安裝方式可以透過npm-link的「npm link <package-name>」或是@pulipuli.chen/npm-link-better套件的「nls <package-name>」來安裝。

然而,如果全域目錄的套件經過更新、移除、漏洞修復的話,很可能導致專案底下用npm-link連結的套件會發生「Module not found」錯誤。這時候要先用「npm -g i <package-name>」更新全域目錄的套件、移除專案內的套件連結、最後再重新連結套件。


「找不到模組」的問題 / Error "Module not found"

2019-10-18_154701_-_Copy.png

正要打開專案、啟動伺服器與Webpack、開始工作時,結果console居然跑出了錯誤訊息:

ERROR in C:/Users/.../AppData/Roaming/npm/node_modules/...
Module not found: Error: Can't resolve 'sortablejs' in 'C:\Users\...\AppData\Roaming\npm\node_modules\...'

當時我第一個反應是:我有用到sortablejs這個套件嗎?我記得並沒有這回事。讓我更仔細的看看這個錯誤訊息:

2019-1018-161104.png

ERROR in C:/Users/.../AppData/Roaming/npm/node_modules/vuedraggable/dist/vuedraggable.common.js

這邊可以注意到兩件事請:發生錯誤的檔案是位於npm的全域目錄底下。在Windows 7中,npm的全域套件會安裝在「%USERPROFILE%\AppData\Roaming\npm\node_modules」底下,其他作業系統的目錄位置請參考「Where does npm install packages?」這篇的說明。

另一件事情是發生錯誤的套件名稱為「vuedraggable」。我的確有用到這個套件,而且我還是用@pulipuli.chen/npm-link-better套件,以npm-link連結的方式安裝。

好,現在我們知道是「vuedraggable」出問題了,我們要怎麼處理呢?

修復問題 / Fix error

要修復以npm-link安裝在專案底下的「vuedraggable」出現的「Module not found」問題,我們有三個步驟要進行:

1. 重新安裝全域套件 / Reinstall global package

首先我們先執行重新安裝套件的指令。npm套件的安裝「npm i <package-name>」。因為vuedraggable套件是安裝在全域目錄,所以指令還要加上「-g」。完整指令如下:

npm -g i <package-name>

我們要把<package-name>替換成我們要安裝的套件vuedraggable。

2. 移除專案內的套件連結 / Remove package symlink in project's node_modules folder

2019-1018-162635-OO-VB-repute-Sart-ct-eve-Jmg-om.png

有時候前述的重新安裝會造成專案內的套件連結失效。我們需要再重新建立專案中的套件連結。

接下來我們到專案內安裝套件的目錄「node-modules」中,找到欲修復套件的目錄,例如這次要修復的「vuedraggable」。如果你從這裡要進入該目錄的時候發生了錯誤,那就表示這個連結失效了。

請刪除這個目錄,然後繼續下一步吧。

3. 重新連結套件 / Create symlink to package

再來就是重新用套件連結的指令來建立連結,指令如下:

npm link <package-name>

這時候回到專案,重新執行會用到該套件的指令時,應該就不會再出現找不到模組「Module not found」的錯誤了。


結語 / In closing

2019-1018-170018-pulipuli-chen-npm-link-better-Public.png

我把這篇的做法整理到@pulipuli.chen/npm-link-better套件裡面。未來也可以用以下指令來重新連結:

nls -U <package-name>

不過老實說,我不確定這是不是最佳的做法。對於Node.js這塊領域,我還有很多需要學習的地方。最後來講講一些其他的事情:

為什麼會發生錯誤? / Why "Module not found" occured?

我並不是完全瞭解這背後的原因,但我推測有兩個可能性。一個是發生在安裝AdonisJs套件的時候,另一個是執行「npm audit fix」的時候。

我在「Node.js前後端CORS網頁應用試作:AdonisJs聊天室」這篇有提到我開始使用了AdonisJs框架。雖然AdonisJs預設安裝只需要執行「npm i -g @adonisjs/cli」,但這只是基本功能而已。如果要用到其他功能,例如File Storage的@adonisjs/driveWebSocket的@adonisjs/websocket,那就需要再執行安裝套件的指令。

然而,執行這個指令之後,「Module not found」的錯誤就層出不窮。

npm-audit-fix.png

(圖片來源:HTMLHint)

另一個可能性是在執行「npm audit fix」之後。npm會自動檢查套件的版本,挑出有安全性漏洞的危險版本,告訴開發者記得要用「npm  audit fix」來修正它。根據npm-audit的說明,這個指令將有安全性漏洞的套件更新到穩定的版本。有時候單純執行「npm audit fix」並無法成功,需要改成「npm audit fix --force」才行。

不過,在執行這個指令之後,好像就很容易遇到「Module not found」錯誤。

我不太確定背後運作的詳細細節,這兩個只是我觀察推測的原因。希望大家可以幫我解釋一下。

為什麼是npm-link? / Why install package with npm-link

對於大部分開發者來說,大家好像比較少人在用npm-link安裝套件。對我來說,比較常用npm-link的原因在於我會使用Chromebook開發,而Chromebook的儲存空間相當的少,就連重複套件所佔用的空間都不夠用,所以我才會使用npm-link、讓各個專案都用全域目錄中的套件。

然而用到現在,我的Chromebook連開發用的套件都裝不下了,Electron實在是太佔空間。儘管如此,我那臺只有32GB的Chromebook已經使用了一年了,市面上擁有64GB儲存空間的Chromebook仍然未成主流,只有在中、高階機型才有出現,例如Pixelbook Go


那麼,這次關於「Module not found」問題的處理方法就講到這裡了。寫到最後,我有些問題想問問大家:

  • 你有遇過Node.js模組安裝的問題嗎?
  • 你遇到的是什麼問題呢?
  • 你是怎麽處理它呢?

歡迎在下面的留言處跟我們分享你的想法。大家的意見是我繼續分享的動力喔!如果你覺得我這篇實用的話,請幫我在AddThis分享工具按讚、將這篇分享到Facebook等社群媒體吧!

感謝你的耐心閱讀,我是布丁,讓我們下一篇見。