package.json的認識

bug之所措發表於2021-08-25

前言

感覺這塊也是一個知識點,雖然我現在還不能系統的用xmind總結每個知識點的串聯關係,但是隻能看一個記一個了

package.json是什麼

我個人理解,package.json是描述包,管理包的一個資訊json檔案,給npm用的,比如你可以寫一個包,發到npm,那這個json就是記錄這個包的資訊,或者對用vue腳手架開發的專案而言,它就是管理包的檔案,npm install會讀這個檔案的denp配置包資訊然後下載

package.json 如何產生的

用npm init初始化,一路回車,這裡說一句,npm init,這句話,我們是用shell視窗輸入的,就是在這種image.png
要知道,這個視窗裡面的指令,其實執行的是shell指令,也就是說,npm init,打下去後,它內部跑了一個sehll的指令,這個指令呼叫系統建立文字的指令,然後巴拉巴拉,最後輸出到本資料夾。

dependenices和devDependenices

這兩個欄位,從始至終,我只知道,dependenices的依賴包是本地,線上開發都需要,比如UI框架,而devDependenices的依賴包,只是本地開發才需要,比如eslint;

(1)什麼叫本地需要,線上開發需要?
我的理解啊,就是npm run dev的時候,這兩個欄位的依賴包全部都會載入,而npm run build的時候,devDependenices的依賴包不會打包進去,從而減少了整個包的體積,訪問更快一點

(2)鎖版本
我今天才知道,原來安裝依賴的時候,把包前面的倒三角刪掉,版本就鎖定了
image.png

那麼這樣做有什麼用呢??
你的同事,拉程式碼,跑npm install的時候,如果依賴包前面帶倒三角,它其實是預設拉最新的包,如果它跑完了,程式碼一推,這個package.json被更新了,重點來了!
依賴A版本是1.0,它匹配依賴B版本是1.0,後面依賴B更新了2.0,你安裝依賴的 時候,A還是1,但是B被你更新變成2了,結果就報錯了

(3)指令

// 安裝最新到dependenices(預設)
npm i xxxxx

// 安裝最新到dependenices
npm i xxxxx -S

// 安裝指定版本到dependenices
npm i xxxxx@2.0.0

// 安裝最新到devDependenices
npm i xxxxx -D

bin

在介紹這個欄位之前,先來舉一個例子,
大家在新的電腦安裝環境的時候,裝那個node的時候,如果那個node安裝後,沒有配置PATH(環境變數地址),在shell視窗輸入node -v的時候,會報錯說找不到,配了path後,其實就是把安裝目錄路徑填進去,就可以

好了說完上面那個之後,回到這個bin,這個bin欄位的作用其實也類似。
在我們的依賴包裡,比如gulp,有這個bin欄位配置
image.png

一旦有這個配置,那麼其實我們裝npm i gulp的時候,它會讀取到這個欄位,並且,會寫一份檔案到node_modules下的.bin資料夾(這個資料夾的由來就是這樣)
image.png

image.png

然後呢,當我們npm run dev的時候,都知道,這句程式碼,其實跑的是scripts那裡的
image.png

gulp dev-local,問題來了,gulp我沒有全域性安裝,PATH我沒有配,為什麼這樣跑不會報錯!!!

答案就是,下面我引入大佬文章的一段解釋

(1) 我們每次在執行 scripts 中的一個屬性時候(npm run),實際系統都會自動新建一個shell(一般是Bash),在這個shell裡面執行指定的指令碼命令。因此 凡是能在 shell 中允許的指令碼,都可以寫在npm scripts中

(2) 特別的點,npm run 新建的 shell,會在當前目錄的 node_modules/.bin 子目錄加入到 PATH 變數,執行結束後,再將 PATH 變數恢復原樣。也就是說,當前專案目錄 node——modules/.bin 子目錄中所有的指令碼,都可以直接用指令碼名稱呼叫,不需要增加路徑.(簡單總結:透過 npm 啟動的指令碼,會預設把 node_modules/.bin 加到 PATH 環境變數中。)

比如本來我們應該要這樣寫的

"scripts": {
    "dev": "./node_modules/.bin/gulp  dev-local",
    "server": "gulp dev-local",
    "build": "gulp deploy && gulp dev-server"
  },

但是有這個機制在,就可以

"scripts": {
    "dev": "gulp dev-local",
    "server": "gulp dev-local",
    "build": "gulp deploy && gulp dev-server"
  },

大家也可以聯想到webpack,webpack我沒有全域性安裝,為什麼用依賴的形式安裝webpack卻可以執行,一樣的道理

"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "build": "node build/build.js"
  },

未完待續
資料參考這位大佬
【Node進階】你應該知道的NPM知識都在這!