再也不讓 npm 成爲面試絆腳石了

前言

Hello 你們好!我是壹甲壹!html

對於日常只會用到簡單的 npm 命令的我來講,面試的時候就被考官按在地上摩擦過前端

  • 請問 package.json 中版本 ~1.2.3^1.2.3 有什麼區別?
  • 請問執行 npm install 時,是怎麼安裝依賴包的?相同的依賴包怎麼處理?

面試結果可想而知,因而便有了這篇文章,好好總結下 npm 相關的知識啦node

1、npm 安裝

當咱們在安裝 node 後,npm 也會一塊兒安裝好,此時須要另外兩個包來協助開發react

  • nvm 管理 node 版本
  • nrm 管理 npm 的源,國內通常都使用 taobaocnpm

詳細安裝信息,請參考 Node.js的3m安裝法jquery

2、npm 命令

2.1 npm init

npm init 命令用來初始化項目webpack

  • 直接執行 npm init,  會依次詢問 name, version, description 等配置信息,比較麻煩
  • 添加 --yes-y 後綴,直接生成 package.json 文件,配置信息使用默認值 ( 默認值在 npm config 中定義), 可手動修改

對於每一個項目而言,例如 author.name , author.email 都是固定的,能夠給這些字段設置默認值git

// 查看全部配置信息
npm config list --json  // 設置默認值 npm config set init.author.name "userName" npm config set init.author.email "userEmail" 複製代碼

接下來,執行 npm init -y, 生成的  package.json 文件以下github

{
 "name": "pkg-a",  "version": "1.0.0",  "description": "",  "scripts": {  "test": "echo \"Error: no test specified\" && exit 1"  },  "keywords": [],  "author": "userName <userEmail>",  "license": "ISC" } 複製代碼

2.2 npm install

npm install  命令用來全局安裝或本地安裝第三方的依賴。npm install 簡寫爲 npm iweb

2.2.1 global

npm i create-react-app -g  會進行全局安裝,安裝成功後,可在終端任何地方使用 create-react-app 命令。面試

  • 全局安裝路徑

執行 npm root -g 輸出全局安裝路徑爲

/Users/xxx/.nvm/versions/node/v14.2.0/lib/node_modules
複製代碼

(Tip: 此時能夠看出 nvm 管理node 版本時,每一個版本都有對於的 node_modules )

  • 全局使用

之因此可以全局使用,是由於將 xxx/v14.2.0/lib/node_modules 目錄下每一個依賴的可執行文件軟連接 到 xxx/v14.2.0/bin 目錄下。

每一個依賴包的可執行文件在其 package.json 文件中的 bin  字段指定

{
 "name": "create-react-app",  "bin": {  "create-react-app": "index.js"  } } 複製代碼

那麼,在  xxx/v14.2.0/bin 目錄就會建立  create-react-app 命令,在執行該命令時,就是在執行 index.js 文件

2.2.2 local

npm i moment --save 會在當前項目進行安裝,安裝成功後,須要在項目中引入後,才能使用

依賴來源

npm i 默認會從 npm registry 上去下載依賴的模塊 (使用 nrm 切換),除此以外,還有哪些安裝途徑呢?

  • from  folder 能夠從本地的文件夾中安裝 pkg。本地建立 pkg-a 文件夾,並經過 npm init -y 進行初始化,接下來執行 npm i ~/pkg-a 就能夠安裝了,成功以後 pkg-a的值爲相對連接的 file 協議地址
npm_install_floder.png
npm_install_floder.png
  • from tarball 對於👆的本地模塊 pkg-a,  執行 npm pack 命令就可對其打包了 截屏2020-07-09下午9.38.12.png 接下來,就能夠執行   npm i ~/pkg-a/pkg-a-1.0.0.tgz 安裝模塊了,安裝成功後 pkg-a的值爲相對連接的 file 協議地址 npm_install_tgz.png

npm install tarball 比較適合離線安裝包或者包不想發佈的 npm 源上,但須要手動維護

  • from http(s) url 前面介紹的是本地包,對於已經發布的依賴,例如 react,使用 npm view react 能夠查看最新版本的 react 壓縮包地址

截屏2020-07-09下午5.39.22.png     此時能夠直接使用  npm install [https://r.cnpmjs.org/react/download/react-16.13.1.tgz](https://r.cnpmjs.org/react/download/react-16.13.1.tgz)     來安裝 react。安裝完成後,在 package.jsonreact 值爲 https 地址 npm_install_tgz_url.png npm install http(s) 比較適合不想發佈的 npm 源上,但須要別人也能安裝

  • from git

咱們還能夠從 git 上安裝,還以 react爲例,執行 npm i [https://github.com/facebook/react.git](https://github.com/facebook/react.git) 來安裝 npm_install_git.png 以上就是其它的幾種 npm install  方式,在平常開發中仍是推薦從 npm 源上面安裝依賴

依賴分類

對於不一樣的依賴功能不一樣,常見會將依賴分紅 開發環境依賴 和 生產環境依賴,例如 babel 屬於開發依賴,而react 就屬於生產依賴了。在 npm install 時能夠添加不一樣的後綴來區分依賴,--save (-S) 表示生產依賴,下載的依賴會保存到 package.jsondependencies 字段中,而 --save-dev (-D) 表示開發依賴,會保存到 devDependencies 字段中。

npm 5 中,不添加後綴,下載的依賴默認會保存到 dependencies

除去 -S -D後綴,npm install 還存在如下後綴

  • -P: --save-prod , 當保存到 dependencies字段中, 當不存在 -D-O時, -P就是默認值
  • -O: --save-optional , 保存到 optionalDependencies字段中
  • --no-save, 將不會進行保存
  • -B: --save-bundle , 不只保存到 dependencies字段,還會保存到 bundleDependencies 列表中 (可選)
  • -E: --save-exact , 不只保存到 dependencies字段,還會鎖定 pkg 的準確版本,而不是使用一個範圍 不加 -E,版本 ^16.13.1 是一個範圍,表示的是   >=16.13.1 < 17.0.0 這個範圍 npm_install_react.png 加上 -E , 就會鎖定 react 的版本 code1.png

(Tips: 關於 dependencies 這些字段,以及 ^16.13.1表示的具體版本範圍,後續 package.json 中會講解)

安裝位置

本地安裝是,全部的依賴都會放到 ./node_module/ 文件夾下面,同時每一個依賴的可執行文件都會軟連接到 ./node_module/bin/ 目錄下,這樣就能夠在 package.json  中設置 script 時使用到這些命令,如 code.png

2.2.3 How to Work?

當僅執行 npm install 時,npm 會根據 package.json 來安裝項目依賴,究竟是如何工做的呢? 這部分請參考 npm install 如何工做 - node_modules 目錄結構 總結以下,若想實踐,可經過下面 Tips來切換 npm 版本

  • **npm 2 ** 遞歸安裝依賴

缺點:重複安裝相同版本的依賴包       Tips: 執行 nvm install 4.2.0 後,node 版本 4.2.0npm 版本 2.14.7

  • npm 3 扁平化管理, 在安裝時遍歷整個依賴樹,計算出最合理的文件夾安裝方式, 避免重複安裝

Tips: 執行 nvm install 6.9.0 後,node 版本 6.9.0npm 版本 3.10.8

  • npm 5

增長 package.json 文件, 鎖定依賴版本,確保任何環境運行 npm install 獲得相同的 node_modules 結            構。禁用命令 npm config set package-lock false

2.3 npm view(info)

npm view(info) xxx ,查看包 xxx 的一些信息,最新穩定版本,在線壓縮包地址,依賴等信息。

2.4 npm home(docs)

npm home(docs) xxx ,都會打開在線 github 地址,前提須要在包 xxx 的 package.json 文件中設置 homepage 字段

2.5 npm repo(bugs)

npm repo(bugs) xxx, 跳轉到對應的 github repo頁面,前言也是須要配置

2.6 npm ls

顯示依賴 tree

3、package.json

一個項目的所有信息都在 package.json 文件中了,具體看下有哪些屬性吧

3.1 必備屬性

若是該項目打包發佈到 npm 源上,那麼 name 和 version 兩個字段是必須的

3.2 version

版本號必須可以被 node-semver 正確解析。

3.2.1 版本號

標準版本號格式爲: X.Y.Z , 有下面幾點說明

  • X.Y.Z  均爲非負整數,X: 主版本號、Y:此版本號、Z:修訂號。每一個元素依次遞增
  • 任何修改都要用新的版本號發佈
  • 當 X 爲 0 時(0.y.z),此時屬於開發初期,任務公共API 均可能改變,屬於非穩按期。1.0.0 用於界定公共 API 的造成
  • 修改 Z,   必須在作了向下兼容的修正時才遞增,例如 修復 bug
  • 修改 Y,   必須在有向下兼容的新功能時才遞增,當 Y 修改後,Z 必須歸 0
  • 修改 X,   必須在有任何不兼容的修改被加入公共 API 時遞增,當 X 修改後, Y, Z 必須歸  0

**

3.2.2 預發版本號

eg: 2.1.0-beta.1

  • alpha(α):預覽版,或者叫內部測試版
  • beta(β):測試版,或者叫公開測試版
  • rc(release candidate):最終測試版本

預發版本代表當前版本並不是穩定,可能不符合要求。

3.2.3 版本號優先級

版本優先級也就是指版本的高低

  • 首先記住 2.1.0-beta 的優先級低於 2.1.0 ,先有預發,再有穩定;
  • 對於正常版本格式 X.Y.Z ,都是數值,比較每一位大小就OK;
  • 而對於預發版本,有數字比數值大小,非數字比較每一個字符的 ASCII 大小;

因此: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0

3.2.4 範圍版本號

(1)運算符:> , >=, <, <=
  • 正常: >= 1.2.7 , 那麼匹配的版本能夠是 1.2.71.2.83.4.2
  • 預發: >1.2.3-alpha.3,那麼匹配的版本的 X.Y.Z 必須是 1.2.3
(2)字符範圍:X.Y.Z  -  A.B.C
  • 1.2.3 - 2.3.4 , 那麼匹配的版本範圍是 >=1.2.3 <=2.3.4
  • 1.2 - 2.3.4,第一個版本缺失,會進行補零,因此匹配的版本範圍是 >=1.2.0 <=2.3.4
  • 1.2.3 - 2.3,第二個版本缺失,會要求匹配的版本的 X.Y 兩位不得大於 2.3,也就是 < 2.4.0, 因此版本範圍是 >=1.2.3 <2.4.0,
(3)X-Range: 1.2.X , 1.2.x, 1.2.*
  • * , 匹配任意版本,也就是 >= 0.0.0
  • 1.2.x ,匹配的版本 X.Y 兩位不變,因此版本範圍是 >=1.2.0 < 1.3.0
  • 1.x ,匹配的版本 X 位不變,因此版本範圍是 >=1.0.0 < 2.0.0
(4)Tilde Ranges : ~

若是Y被指定,則容許Z被改變;若是沒有,容許Y被改變

  • ~1.2.3 , Y 被指定爲 2, 那麼匹配的範圍爲 >=1.2.3 <1.3.0
  • ~1.2, Y 被指定爲 2, 那麼匹配的範圍爲 >=1.2.0 <1.3.0
  • ~1, 沒有指定 Y, 那麼 Y 能夠被改變,匹配的範圍爲 >1.0.0 <2.0.0
(5)Garet Range: ^

匹配的版本,會保證最左邊的第一個非 0 位不修改

  • ^1.2.3, 最左邊非 0 位爲 X 位,因此匹配的範圍爲 >=1.2.3 <2.0.0
  • ^0.2.3, 最左邊非 0 位爲 Y 位,因此匹配的範圍爲 >=0.2.3 <0.3.0
  • ^1.2.x , 當版本缺失,缺失位會降到 0 ,因此匹配的範圍位 >=1.2.0 <2.0.0

3.3 dependency

3.3.1 dependencies

生產環境依賴,對應 npm install 時後綴 -S

3.3.2 devDependencies

開發環境依賴,對應 npm install 時後綴 -D

3.3.3 peerDependencies

同等依賴,若是安裝了依賴包 pkg-a, 最好也安裝下 pkg-a 對應的依賴

// pkg-a package.json
{  "peerDependencies": {  "jquery": "2.2.0"  } } 複製代碼

上面表示 pkg-a 的運行依賴於 jquery,因此當 npm install pkg-a 時,控制檯會提示如下信息 截屏2020-07-10下午2.03.39.png 在 npm 2.x 版本時,peerDependencies 會被強制安裝,3.0 版本後不被強制安裝

3.3.4 bundleDependencies

捆綁依賴, 也叫 bundledDependencies,屬性值是個數組

// pkg-a package.json
{  "bundledDependencies": [  "moment"  ] } 複製代碼

npm pack 時會將捆綁依賴一同打包,在安裝 tgz 壓縮包時,捆綁依賴也會被安裝。但注意捆綁依賴並無指定版本號

3.3.5 optionalDependencies

可選依賴,屬性值爲對象。當項目依賴 pkg A, 但 pkgA 安裝失敗或者找不到並不會影響項目的運行,就能夠在 optionalDe.... 中指定 pkgA 了

3.4 homepage

指定項目主頁,設置後可經過 npm docs(info) xxx 打開

3.5 bugs

指定項目 issues 頁面, 設置後經過 npm bugs xxx 可打開

3.6 license

截屏2020-07-10下午2.21.26.png
截屏2020-07-10下午2.21.26.png

3.7 main

指定項目入口文件,當 require(xxx) 時,返回的就是入口文件導出的內容

3.8 bin

當 pkg 中的可執行文件須要安裝到 PATH 中,可在 bin 中指定。以 http-server 爲例

"bin": {
 "http-server": "./bin/http-server",  "hs": "./bin/http-server" } 複製代碼

http-server 全局安裝,會將執行文件軟鏈接到 xxx/node/v14.2.0/bin/http-server 中,本地安裝就會連接到 ./node_module/bin/http-server  中。 可執行文件須要在文件頂部增長 #!/usr/bin/env node  指定 node 執行

3.9 config

設置 config 可經過 npm_package_config_xxx 來獲取,但同名變量會被本地 npm config 所覆蓋

3.10 script

這部分請參考 阮一峯 npm scripts 使用指南

4、npx

npx 命令是 npm v5.2 以後引入的新命令,npx 能夠幫咱們直接執行 node_modules/.bin文件夾下的文件

  • 執行腳本
npx webpack
複製代碼

這樣就省略了配置scripts腳本

  • 避免安裝全局模塊

全局安裝的模塊會帶來不少問題,例如:多個用戶全局安裝的模塊版本不一樣

npx create-react-app react-project
複製代碼

咱們能夠直接使用 npx 來執行模塊,它會先進行安裝,安裝執行後會將下載過的模塊刪除,這樣能夠一直使 最新版本

5、npm 發佈

npm 包的發佈比較簡單

  • 首先使用 nrm 切換到 npm 官方源
  • 使用 npm login 進行登陸(提早註冊)
  • npm publish (確保 name 是惟一值)
  • 對於不想打包的可在 .npmignore 文件中進行忽略

6、參考連接

本文使用 mdnice 排版

相關文章
相關標籤/搜索