一、初始化一個 package.json
npm init 手動配置
npm init -y 使用預設配置
1.1 各參數說明
- name 是項目的名稱 (必須)
- version 是目前項目的版本号 (必須)
- description 是描述資訊,很多時候是作為項目的基本描述 (釋出到npm上的簡介);
- author 是作者相關資訊(釋出時用到)
- license 是開源協定(釋出時用到)
private屬性:
private屬性記錄目前的項目是否是私有的;
當值為true時,npm是不能釋出它的,這是防止私有項目或子產品釋出出去的方式;
main 入口檔案,前端項目中如果使用webpack配置了入口檔案則該配置失效。
main 主要作用是,當我們把包釋出到npm上去的時候,别人下載下傳後,引入的是哪個檔案就是在這裡指定的。
例如:包名稱是 utils-format
main配置是: “main”: “main.js”
則 const format = require(‘utils-format’) 引入的實際是 main.js
{
"name": "npmdemo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"private":true, //是否是私有的
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
1.2 dependencies devDependencies 屬性
dependencies
屬性是指定無論開發環境還是生成環境都需要依賴的包;
通常是我們項目實際開發用到的一些庫子產品;
devDependencies
一些包在生成環境是不需要的,比如webpack、babel等;
這個時候我們會通過 npm install xxx --save-dev,将它安裝到devDependencies屬性中;
但是對于 前端 項目來說,意義并不大,因為webpack在打包的時候,從入口檔案開始查找并生成依賴樹,如果檔案存在于依賴樹中,那麼它還是會被打包的。
真正的意義:
在我們開發伺服器的時候,或者開發一個共享出去的包工具的時候(釋出到npm上),别人在安裝你這個工具的時候,它則是根據這兩個屬性來的。
疑問:那麼在生成環境如何保證不安裝這些包呢?
生成環境不需要安裝時,我們需要通過
npm install --production 來安裝檔案的依賴;
1.3 版本管理問題
我們在寫Vue項目的時候,經常能夠看到某些依賴的版本号前面有一個
~ 或者 ^
,那麼這兩個符号到底是什麼意思呢?
npm的包通常需要遵從semver版本規範:
semver規範:semver
npm semver:npm sermver 規範
semver版本規範是X.Y.Z:
- X主版本号(major):當你做了不相容的 API 修改(可能不相容之前的版本);
- Y次版本号(minor):當你做了向下相容的功能性新增(新功能增加,但是相容之前的版本);
- Z修訂号(patch):當你做了向下相容的問題修正(沒有新功能,修複了之前版本的bug);
我們這裡解釋一下 ^和~的差別:
- ^x.y.z:表示x是保持不變的,y和z永遠安裝最新的版本;
- ~x.y.z:表示x和y保持不變的,z永遠安裝最新的版本;
1.4 engines屬性
engines 中譯為 引擎
engines屬性用于指定Node和NPM的版本号;
在安裝的過程中,會先檢查對應的引擎版本,如果不符合就會報錯;
事實上也可以指定所在的作業系統
"os" : [ "darwin", "linux" ]
,隻是很少用到;
例:
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
}
1.5 browserlist 屬性
- 用于配置打包後的JavaScript浏覽器的相容情況,參考;
- 否則我們需要手動的添加polyfills(更新檔)來讓支援某些文法;
- 也就是說它是為webpack等打包工具服務的一個屬性
例:
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
二、npm install 指令
安裝npm包分兩種情況:
- 全局安裝(global install): npm install yarn -g;
- 項目(局部)安裝: npm install
全局安裝
- 全局安裝是直接将某個包安裝到全局:
- 比如yarn的全局安裝:
- npm install yarn -g
但是很多人對全局安裝有一些 誤會 :
- 通常使用npm全局安裝的包都是一些工具包:yarn、webpack等;
- 并不是類似于 axios、express、koa等庫檔案;
- 是以全局安裝了之後并不能讓我們在所有的項目中使用 axios等庫;
那全局安裝有什麼用呢?
全局安裝一般不會安裝普通的包,如
axios、express
等,一般安裝的都是工具包,比如
yarn、webpack、gulp
之類的,安裝之後會生成對應的可執行檔案的(
.exe
),并且會自動配置環境變量的。
這裡推薦一手yarn,具體差别看: yarn和npm的差別
npm或yarn切換為國内鏡像可檢視我的這邊文章:Yarn 和 NPM 國内鏡像(淘寶鏡像)
2.1 安裝開發和生産依賴
npm install axios
npm i axios
2.2 開發依賴
npm install webpack --save-dev
npm install webpack -D
npm i webpack –D
2.3 根據package.json中的依賴包
npm install
三、npm install 原了解析
很多朋友之前應該已經會了
npm install <package>
,但是你是否思考過它的内部原理呢?
- 執行 npm install它背後幫助我們完成了什麼操作?
- 我們會發現還有一個成為package-lock.json的檔案,它的作用是什麼?
- 從npm5開始,npm支援緩存政策(來自yarn的壓力),緩存有什麼作用呢?
這是 coderwhy大神總結出來的一幅原理圖:
四、package-lock.json
package-lock.json檔案解析:
-
:項目的名稱;name
-
:項目的版本;version
-
:lock檔案的版本;lockfileVersion
-
:使用requires來管理子依賴;requires
-
:項目的依賴dependencies
- 目前項目依賴axios,但是axios依賴follow-redireacts;是以安裝
的時候,會連帶安裝axios
follow-redireacts
- 目前項目依賴axios,但是axios依賴follow-redireacts;是以安裝
- axios中的屬性如下:
-
表示實際安裝的axios的版本;version
-
用來記錄下載下傳的位址,registry倉庫中的位置;resolved
-
記錄目前子產品的依賴;requires
-
用來從緩存中擷取索引,再通過索引去擷取壓縮封包件;integrity
-
示例檔案:
五、npm 其他常用指令
強制删除
node_modules
并重新安裝:
rm -rf node_momdules && npm install
(windows不支援)
檢視緩存路徑:
npm config get cache
解除安裝某個依賴包(效果都是一樣的):
-
npm uninstall package
-
npm uninstall package --save-dev
-
npm uninstall package -D
強制重新build
-
npm rebuild
清除緩存
-
npm cache clean
npm的指令其實是非常多的:
- https://docs.npmjs.com/cli-documentation/cli
- 更多的指令,可以根據需要查閱官方文檔
六、cnpm 工具
由于一些特殊的原因,某些情況下我們沒辦法很好的從 https://registry.npmjs.org下載下傳下來一些需要的包。
檢視npm鏡像:
npm config get registry
我們可以直接設定npm的鏡像:
npm config set registry https://registry.npm.taobao.org
但是對于大多數人來說(比如我),并不希望将npm鏡像修改了:
- 第一,不太希望随意修改npm原本從官方下來包的管道;
- 第二,擔心某天淘寶的鏡像挂了或者不維護了,又要改來改去;
這個時候,我們可以使用cnpm,并且将cnpm設定為淘寶的鏡像:
npm install -g cnpm --registry=https://registry.npm.taobao.org
七、npx工具
npx是npm5.2之後自帶的一個指令。
npx的作用非常多,但是比較常見的是使用它來調用項目中的某個子產品的指令。
我們以webpack為例:
- 全局安裝的是webpack5.1.3
- 項目安裝的是webpack3.6.0
- 如果我在終端執行 webpack --version使用的是哪一個指令呢?
- 顯示結果會是 webpack 5.1.3,事實上使用的是全局的,為什麼呢?
- 原因非常簡單,在目前目錄下找不到webpack時(沒有自動注冊環境變量),就會去全局找,并且執行指令;
如何解決這個問題呢?
使用項目(局部)的webpack,常見的是兩種方式:
方式一:明确查找到node_module下面的webpack
在終端中使用如下指令(在項目根目錄下):
./node_modules/.bin/webpack --version
方式二:在 scripts定義腳本,來執行webpack;
修改package.json中的scripts:
npm run webpack
"scripts": {
"webpack": "webpack --version"
}`
方式三:使用npx
npx webpack --version
npx的原理非常簡單,它會到目前目錄的node_modules/.bin目錄下查找對應的指令;