npm(你怕嗎) 全局安裝與本地安裝、開發依賴和生產依賴

npm(你怕嗎)

npm(Node Package Manager)是 JavaScript 世界的包管理工具,並且是 Node.js 平臺的默認包管理工具。通過 npm 可以安裝、共享、分發代碼,管理項目依賴關係。(與其有同樣功能的另一個包管理工具yarn,速度用體驗比舊版本的npm好,但npm最近的新版本也做出很大努力,與yarn速度和體驗差距越來越小,有興趣可以瞭解下)。

npm這幾年可以說是前端猿日常離不開的工具了,剛開始學習使用node、npm來進行前端項目構建的時候,有很多概念需要理解,各種命令行、各種新js語法、各種環境依賴...就問你怕嗎?:

圖片描述

講真,剛開學時我怕。廢話不多扯,現在我們進入主題,聊聊npm 全局安裝與本地安裝、開發依賴和生產依賴,先拋兩常見疑惑:

  1. 什麼是全局安裝、什麼是本地安裝(或叫局部安裝,下文統一叫本地安裝) ?
  2. 爲什麼要全局安裝?爲什麼又要本地安裝?全局安裝和本地安裝有什麼區別?
  3. 什麼叫開發依賴、生產依賴?什麼又是開發環境、生產環境?

全局安裝與本地安裝

一、全局安裝:

npm install <pageName> -g//(這裏-g是-global的簡寫)

通過上面的命令行(帶-g修飾符)安裝某個包,就叫全局安裝。通常全局包安裝在node目錄下的node_modules文件夾。可以通過執行下面幾條命令查看node、npm的安裝目錄和全局包的安裝目錄。

which node   // 查看node的安裝目錄
which npm   // 查看npm的安裝目錄
npm root -g // 查看全局包的安裝目錄
npm list -g --depth 0 //查看全局安裝過的包

二、本地安裝:

npm install <pageName> (後面可以加幾種修飾符,主要有兩種--save-dev和--save)

通過上面的命令行安裝某個包,就叫本地安裝。包安裝在你當前項目文件夾下的node_modules文件夾中。

三、全局安裝的作用:

全局安裝的包可提供直接執行的命令(例:gulp -h可以查看gulp定義了什麼命令)。 比如gulp全局安裝後,可以在命令行上直接執行gulp -v、gulp -h等(原理:全局安裝的gulp會將其package.json中的bin命令注入到了全局環境,使得你可以全局執行:gulp xxx命令,這另一個話題了,不深入)。倘若只在本地安裝了gulp,未在全局安裝gulp,直接執行這些命令會報錯。你想要執行相應的命令則可能需要例如:node ./node_modules/gulp/bin/gulp.js -v(查看版本) 這樣用一大串命令來執行。因此全局安裝就發揮到他的好處了,一個gulp -v就搞定

當然,不是每個包都必須要全局安裝的,一般在項目中需要用到該包定義的命令才需要全局安裝。比如gulp <taskName>執行gulp任務...等,所以是否需要全局安裝取決於我們如何使用這個包。全局安裝的就像全局變量有點粗糙,但在某些情況下也是必要的,全局包很重要,但如果不需要,最好避免使用。

四、可以全局安裝,那麼直接全局安裝到處使用就行了,幹嘛還需要本地安裝?

  1. 如果只是全局安裝了而沒本地安裝,就得require('<pagePath>') 例:引入一個全局的包可能就是requirt('/usr/local/....')通過全局包的路徑引入,這樣顯然十分的不靈活。如果安裝了本地包,那麼就可以直接require('<pageName>')引入使用
  2. 一個包通常會在不同的項目上會重複用到,如果只全局安裝,那麼當某個項目需要該包更新版本時,更新後可能就會影響到其他同樣引用該包的項目,因此本地安裝可以更靈活地在不同的項目使用不同版本的包,並避免全局包污染的問題,

一個經驗法則:要用到該包的命令執行任務的就需要全局安裝,要通過require引入使用的就需要本地安裝( 但實際開發過程中,我們也不怎麼需要考慮某個包是全局安裝還是本地安裝,因爲這一點在該包的官網上一般會明確指出,以上是爲了理解全局安裝和本地安裝)

開發依賴和生產依賴

順着上面講到的本地安裝,本地安裝有兩種主要的安裝方式:

  1. 保存到開發依賴(devDependencies): npm install <pageName> --save-dev(等同 npm install <pageName>)
  2. 保存到生產依賴(dependencies): npm install <pageName> --save

"開發依賴"顧名思義在開發環境中用到的依賴,"生產依賴"在生產環境中用到的依賴。那麼這裏又延伸出個問題什麼是開發環境、什麼是生產環境?

一、開發環境和生產環境

【開發環境】:指的是你的項目尚且在編碼階段時的環境。你在代碼可能還有各種console.log()、註釋、格式化等。
【生產環境】:指的是你的項目已經完成編碼,併發布上線可供用戶瀏覽的階段時的環境。代碼可能經過了壓縮、優化等處理。

這些概念其實並沒有一個很明確的定義,接下來我們舉例個場景,將"開發環境"、"生產環境"和上面的"開發依賴"、"生產依賴"聯繫起來就會比較容易理解的了。假如我們在開發過程中使用jQuery。在以往,可能就是把jQuery這個插件下載的本地,再通<script>引入html中。但這有個不方便的地方,我們每次進行一個項目的時候就得手動複製這個jQuery文件到我們的項目中,如果想要換個版本又得官網上下載、隨着項目越來越多。用到的插件、庫也隨之越繁雜...這樣會造成自家用的插件管理繁瑣的問題。因此就出現了npm(包管理工具)你需要用到什麼,直接通過一條命令行就可以將想要的插件下載下來,並直接引入到項目中,目前幾乎所有的js插件都能在npm上直接下載。

二、生產依賴

回到環境和依賴話題,我們下載的jQuery,在開發時參與源碼編寫,在發佈上線的生產環境中也是需要它的。不僅在開發環境編寫代碼時要依賴它、線上環境也要依賴它,因此將它歸類爲"生產依賴",安裝時執行npm install jquery --save,它就會被記錄在package.json的dependencies。當進行代碼打包時,會將這裏的jQuery打包入我們的項目代碼中。

三、開發依賴

接着,假如我們用gulp對html進行壓縮,我們通常會用到一個插件gulp-htmlmin。我們只希望它把html壓縮完就ok了,並不希望它融入我們的項目代碼中,即只存在於開發環境,因此把他歸類爲"開發依賴"。安裝時執行npm install gulp-htmlmin --save-dev它就會被記錄在package.json的devependencies下,當進行代碼打包時,不會將這裏的gulp-htmlmin插件源碼打包入我們的項目代碼中

devDependencies只會在開發環境下使用,生產環境不會被打入包內;而dependencies不僅在開發環境中要使用,生產環境也需要使用到。根據以上規則,我們就很容易區分哪些插件是用--save-dev模式安裝,哪些用--save模式安裝。

最後

文章開頭的問題以上已經一一回答了。剛開始時自己也會有很多類似這樣的疑問,哪怕已經使用npm的各種包構建過不少項目,對這些概念還是會有點模糊,使用當然是會使用的,但沒有一個比較清晰的總結。所有花了點時間,到各社區、node、npm官網蒐集關於以上問題的一些答案、簡單做個筆記和總結。 畢竟總結並記錄下來的東西纔是自己的。也希望可以幫助有同樣疑問的朋友,如發現文章有不對的地方望指出,謝謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章