前言
上一篇 npm入門(一)—瞭解基本組成與概念 簡單介紹了一下npm的相關知識,這篇可以說是npm的核心知識。
分類
關於pacakge,是有分為public pacakge(公共包)、private pacakge(私有包)。前面我們也知道npm賬號也有兩種,一直的免費使用者,一個是付費使用者。私有包是付費使用者才能釋出的。
直觀地,在npn website上看,package前面會有個標籤標註該包是公有的還是私有的
scopes
在此之前,我們先了解這麼一個概念——scopes(中文意思是作用域)。我們在註冊npm賬號和建立組織時,你將被授予一個與你的使用者或組織名稱匹配的範圍,即你獲得了一個適用範圍(scope),這個範圍是你的使用者名稱或者建立的組織名。你可以將此範圍用作相關包的名稱空間。如你有一個package名叫mypackage
,你的使用者名稱為myusername
,則你可以把這個package放到你的域裡
@myusername/mypackage
複製程式碼
這樣有什麼作用呢?
- 避免與別人的包重名,發生衝突。
- 限制該包的訪問許可權。假設你是付費使用者,想要建立一個私有包,那麼可以在你的域裡授權哪些使用者才能訪問
public package
預設地,如果我們不對registry進行了任何設定,那麼釋出的包就是基於預設的registry(http://registry.npmjs.org
)的,釋出出來的包是公共的,任何人都可以訪問使用。
public package也有兩種:
- unscoped package:這個就是普通的共用包了,沒有指定範圍
- scoped package:這個是在劃分了範圍的包,預設是私有的,但是手動轉化為共有的。
private package
私有包,只有付費使用者才能建立。私有包,是指只有授權使用者才能進行下載釋出等管理,而且還能指定各種許可權,例如只讀只寫之類的。
私有包肯定是指定了範圍的(scoped),預設地,指定了範圍的包都是私有包(當然後面可以手動更改)
私有包可以劃分兩種
- 使用者範圍的私有包:只能由你和你授予讀或讀/寫訪問許可權的協作者訪問。
- org(組織)範圍的私有包:只能被授予讀或讀/寫訪問許可權的團隊訪問。
包型別的轉換
上面我們知道包的一些分類,那麼,如何在需要時改變它們的型別呢?
公有轉私有
在npm website上操作的方法就不說了,直接說敲命令的方式:
npm access restricted <pacakge-name>
複製程式碼
<pacakge-name>
替換為真實包名
私有轉公有
在npm website上操作的方法就不說了,直接說敲命令的方式:
npm access public <pacakge-name>
複製程式碼
<pacakge-name>
替換為真實包名
需要注意的是,只有是付費使用者才能轉為私有。
私有包授權使用者
私有包有時候為了協作,需要新增其他開發者進行一起管理,所以需要把私有包授權給某些使用者。根據私有包型別
使用者私有包
在npm website上操作的方法就不說了,直接說敲命令的方式:
npm owner add <user> <your-package-name>
複製程式碼
組織私有包
要授予npm使用者對私有組織包的訪問權,您必須有一個組織所有者將它們新增到您的組織中,然後將它們新增到有權訪問私有包的團隊中。具體步驟參考 這裡
建立package
說了那麼多,是時候應該知道,如何建立一個package了。
進入你想要建立package的資料夾根目錄中,執行以下命令
npm init
複製程式碼
進行npm專案(package)的初始化,當執行這個命令後,會出現一個問卷,例如問你專案的名稱,作者,描述等資訊,你按照實際情況輸入迴應即可。填完問卷後,會在該目錄下生成一個package.json
檔案,該檔案裡包含剛回應問卷的一些資訊。
如果你懶得一個個迴應,可以使用預設的情況,執行
npm init --y 或者 npm init --yes
複製程式碼
這樣會自動根據你當前目錄的情況,生成一系列預設資訊在package.json
檔案。
當然我們也可以設定一些init時的固定指定資訊,如
npm set init.author.name xxxx
npm set init.author.email xxxx
複製程式碼
這裡就設定了init時固定作者資訊是啥
如果你想建立的是指定域的包,那麼執行
npm init --scope=@yourscopename
複製程式碼
yourscopename替換成你想要起的域的名稱
package.json
上一篇我們說過,package是由一個package.json檔案描述組織起來的,所以這個檔案至關重要。先大概看一下這個檔案長哪樣
{
"name": "xxxx",
"version": "1.0.0",
"description": "xxx",
"author": "myname <myname@xxx.com>",
"private": true,
"scripts": {
"dev": "concurrently \"webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --env.sysName=eod\" \"node mock-server.js\""
},
"dependencies": {
"vue-router": "3.0.1"
},
"devDependencies": {
"autoprefixer": "7.1.2"
},
...
}
複製程式碼
挑了些常用常見的內容展示出來。
屬性 | 描述 |
---|---|
name | 必需。package的名稱 |
version | 必需。package的版本,遵循semantic versioning spec(語義版本控制規範) |
description | 推薦。用來描述你的package的一些資訊,方便別人在npm website上查詢你的pacakge |
author | 作者的相關資訊。格式Your Name <email@example.com> (http://example.com) 。包含了你的名稱、郵箱和部落格之類的網址,不一定要全寫 |
private | 你的package是私有的還是公有的 |
scripts | 一些npm指令碼,形成npm指令,方便你進行某些工作,如構建 |
dependencies | 這是你的package釋出後,羅列的所需要依賴的一些別人的package,缺乏了這些package,你的package也會不能如期正常工作 |
devDependencies | 這裡是羅列你在開發過程中所依賴的一些package,為了方便你的開發所用的包,缺少他們也不會影響到你的包釋出後的正常使用,就放在這裡了。 |
作用
- 從檔案裡能看出,該包的一些基礎資訊,以及所依賴的一些包
- 能看出所依賴的包的一些版本資訊
- 使你的構建具有可重複性,因此更容易與其他開發人員共享
README.md
顧名思義,這個相當於用該package之前先看它的意思,即使用手冊之類的意思。一般地,推薦package包含這個檔案比較好,方便使用者使用你的包。這個檔案是使用markdown語法
此檔案只有在釋出包的新版本時才會在包頁面上更新。
釋出package
釋出package之前,要好好檢查你的檔案裡是否包含某些私人資訊,敏感資訊。請注意刪除或者釋出時忽略掉。使用.npmignore
或.gitignore
檔案來忽略掉,詳情見 此
釋出包命令:
npm publish
複製程式碼
- 如果要釋出一個未指定域的公用包,直接執行上述命令即可。
- 如果要釋出一個指定域的私有包,直接執行上述命令即可(預設指定域是私有包)。需要注意的是,publish之前要注意npm所在registry,如你要釋出到公司的registry裡,則釋出前需要切換到公司registry下,才執行該命令,例如使用上一篇提到的
npmrc
工具 - 如果要釋出一個指定域的私有包進行公有化,執行
npm publish --access public
複製程式碼
pacakge的版本控制規範
一個package一定要指定某個版本,而為了規範網路上大家各種各樣的package,方便大家交流共享等,就制定了一個版本控制規範,大家在給自己package指定版本/更新版本的時候就好好考慮版本號了。
以當前版本為1.0.0為例子,遵循以下規範:
更新情況 | 位置 | version |
---|---|---|
修復當前版本的一些bug | 第三位 | 1.0.1 |
新增向後相容的新特性 | 第二位 | 1.1.0 |
進行了破壞性地無法向後相容的更改 | 第一位 | 2.0.0 |
在package.json裡,我們看到依賴項裡,包的版本資訊裡會出現^~
符號。這裡要知道這些符號代表什麼意思。例如
"eslint": "^3.19.0",
"css-loader": "~3.19.0",
複製程式碼
代表安裝這個包的版本資訊是浮動的,而不是指定死版本。
-
^代表固定主版本號的,其餘號浮動,如
^1.3.0
,高於等於1.3.0,1.x.x都符合,但是要低於2.0.0 -
~代表固定次版本號的,修訂號浮動,如
~1.3.0
,高於等於1.3.0,1.3.x都符合,但是要低於1.4.0
為package打tag
雖然package已經有版本號作為一些資訊反饋給使用者,但是語義化不夠,不夠直觀明瞭,因此可以為package加上tag,即標籤,為其備註一些資訊,讓使用者更淺顯易懂點。如執行
npm publish --tag beta
複製程式碼
在釋出時,就為package打上了beta標籤了。
預設地,釋出時會自動繼承這個包上次釋出的標籤的資訊,如上次打了個beta標籤,後面直接執行npm publish
時,也會自動應用上beta標籤。
需要注意的是,tag名儘量不要使用數字或者v(不論大小寫)開頭的名字,因為tag的名稱空間和版本號是一起的,會發生衝突。
如果想要指定版本進行打標籤,執行
npm dist-tag add <packagename>@<version> tagname
複製程式碼
如
npm dist-tag add vue@1.2.0 beta
複製程式碼
釋出後對於package的管理
更新版本
當你在維護一個包時,免不得了在調整之後需要對版本進行改變,以告知使用你的包的人,執行以下命令進行更新版本並進行釋出
npm version <new-version>
npm publish
複製程式碼
棄用與取消棄用package
棄用
當你不再想維護一個package,你需要告知那些依賴了你的包的人,讓他們知道你的這個包你不再進行維護了,這是出於你的責任心啦。執行
npm deprecate <package-name> 'message'
複製程式碼
這裡的message就是你需要告知別人你的一些關於棄用的訊息,這裡一定要帶上這個訊息哦,不然就是另一個含義了。
如果你只想棄用某個版本,而不是整個package,執行
npm deprecate <package-name>@<version> 'message'
複製程式碼
注意:棄用之後別人在npm的網站上會搜不出你的包來哦。訪問你的包的網頁也會有標識表名你的包給棄用了。別人在安裝你的包時也會出現棄用的訊息
取消棄用
如果日後你又回心轉意了,想繼續維護這個包,那麼你就可以取消棄用了。執行
npm deprecate <package-name> ''
複製程式碼
大家留意到嗎,這裡跟棄用的命令很像,唯一的區別在於,之前的message替換成'',這樣就可以取消棄用了
轉移package
如果你不想維護你的包了,你可以選擇棄用,也可以選擇轉移你的包,希望它再找個主人吧。你可以把你的包轉移給@npm,執行
npm owner add npm <package-name>
npm owner rm <user> <package-name>
複製程式碼
上面的兩句命令就是,為你的package新增授權給npm,然後刪除你對該包的擁有權。<user>
為你的賬號名
所以,當轉移了包之後,你就沒了對它的使用權了,也不能更新它。
取消釋出
釋出了一個包之後,如果日後你不想讓它再出現了,又不想僅是標誌棄用,那麼可以選擇取消這個包的釋出。當然這個行為可能會對別人產生不好的影響,例如別人依賴你的包,你無聲無息地把這個包給取消掉了,叫別人情何以堪。
當你釋出了一個公共package之後,72小時內後悔了,可以執行
npm unpublish <package-name> -f
複製程式碼
如果你僅想取消某個版本,執行
npm publish <package-name>@<version>
複製程式碼
如果是72小時後,那麼需要聯絡 npm support了。如果你想取消的是一個組織包,非個人包,那麼需要聯絡 enterprise@npmjs.com
安裝package
我們已經瞭解過了pacakge的基本情況,知道從他的建立到釋出,到釋出後的管理。都是從自身作為包的擁有者角度去處理包,那麼現在是時候作為一名使用者角度,知道如何使用別人的包了。
使用別人的包,首先就得安裝下載他們的包,安裝分為兩類:
- local install (本地安裝)
- global install (全域性安裝)
本地安裝
例如在你的某個專案中,需要使用到別人的一些包,那麼需要在你這個專案下下載安裝所需的包,下載下來的包只會在該專案中被引用。
換個思路去理解,就是像很久以前開發一個專案,需要引入某個類庫,如jquery,那麼就下載jquery.min.js,放在專案裡某個資料夾裡,然後在適當的位置引入它來進行使用,如在index.html裡通過script標籤進行引用。這樣的話,其實這個jquery.min.js只會在這個專案裡被引入使用,而不能在第二個專案B中被引用,因為它是被放在專案A裡面了,這種就是本地安裝
執行以下命令進行本地安裝:
npm install
複製程式碼
會依據專案中的package.json
檔案的依賴項以及宣告的semver規則的最新版本來進行安裝對應的包。如果該專案裡沒有node_modules
資料夾,那麼會新建一個,裡面內容就是安裝的package程式碼,如果有,那麼直接在這個資料夾下新增pacakge
如果想要安裝指定某個包(私有包請帶上@域名/
),執行
npm install <package-name>
複製程式碼
如果專案裡沒有package.json
檔案,那麼會下載指定包的最新版本,如果存在,會下載package.json
中宣告的semver規則的最新版本。
如果想要指定依賴的型別(dependencies, devDependencies等)
npm install <package-name> --save
複製程式碼
加上--save
是指該package是生產依賴項,存放在package.json
的dependencies
裡,其實這是個預設的行為,即就算不加上--save
,預設也是放在dependencies
裡。
如果想放在開發依賴裡,執行
npm install <package-name> --save-dev
複製程式碼
如果想要安裝指定版本或者tag的包,執行
npm install <package-name>@<version>
npm install <package-name> <tag>
複製程式碼
需要注意的是,如果是指定了某個tag的package進行安裝,那麼下載安裝如果不帶上tag,會自動預設依據上次的tag資訊進行安裝,例如,
npm install loadash beta
複製程式碼
下次安裝loadash的時候,預設是下載beta標籤的loadash
全域性安裝
全域性安裝,就是指安裝一些共用的包,在你的本地計算機下的專案,都能共用這些包。例如npm了,每個專案都需要使用npm,那麼全域性安裝就好了,不必要每個專案都獨立安裝一遍。指令也很簡單
npm install -g
npm install -g <package-name>
複製程式碼
其實跟本地安裝介紹的意思是一樣的,只不過區別就在於,多了個-g
來標記是全域性安裝
更新package
隨著時間的變化,可能你本地下載的包已經是比較老的了,需要更新一下別人的包,那麼在專案根目錄下執行
npm update
複製程式碼
即可更新package.json
裡羅列的包。
如果想單獨更新某個包(私有包請帶上@域名/
),執行
npm update <package-name>
複製程式碼
同樣地,如果想更新全域性的包,也是加個-g
即可,如
npm update -g
複製程式碼
如果想看看當前專案裡有哪些過時的包,可以執行
npm outdated
複製程式碼
會顯示當前有哪些包過時了。當然這也可以用來檢驗是否更新成功了
如果想看看有哪些過時的全域性包,執行
npm outdated -g --depth=0
複製程式碼
取消安裝/刪除package
如果某個包你不想要了,為了節省空間以及協作時避免別人下載一些不必要的資源,可以刪除某些不需要的包。執行(私有包請帶上@域名/
)
npm uninstall <package-name>
複製程式碼
指定刪除某個包
npm uninstall -g <package-name>
複製程式碼
指定刪除某個全域性包