npm入門(二)—package(包)的管理

pekonchan發表於2019-04-03

前言

上一篇 npm入門(一)—瞭解基本組成與概念 簡單介紹了一下npm的相關知識,這篇可以說是npm的核心知識。

分類

關於pacakge,是有分為public pacakge(公共包)、private pacakge(私有包)。前面我們也知道npm賬號也有兩種,一直的免費使用者,一個是付費使用者。私有包是付費使用者才能釋出的。

直觀地,在npn website上看,package前面會有個標籤標註該包是公有的還是私有的

npm入門(二)—package(包)的管理

scopes

在此之前,我們先了解這麼一個概念——scopes(中文意思是作用域)。我們在註冊npm賬號和建立組織時,你將被授予一個與你的使用者或組織名稱匹配的範圍,即你獲得了一個適用範圍(scope),這個範圍是你的使用者名稱或者建立的組織名。你可以將此範圍用作相關包的名稱空間。如你有一個package名叫mypackage,你的使用者名稱為myusername,則你可以把這個package放到你的域裡

@myusername/mypackage
複製程式碼

這樣有什麼作用呢?

  1. 避免與別人的包重名,發生衝突。
  2. 限制該包的訪問許可權。假設你是付費使用者,想要建立一個私有包,那麼可以在你的域裡授權哪些使用者才能訪問

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,為了方便你的開發所用的包,缺少他們也不會影響到你的包釋出後的正常使用,就放在這裡了。

作用

  1. 從檔案裡能看出,該包的一些基礎資訊,以及所依賴的一些包
  2. 能看出所依賴的包的一些版本資訊
  3. 使你的構建具有可重複性,因此更容易與其他開發人員共享

README.md

顧名思義,這個相當於用該package之前先看它的意思,即使用手冊之類的意思。一般地,推薦package包含這個檔案比較好,方便使用者使用你的包。這個檔案是使用markdown語法

此檔案只有在釋出包的新版本時才會在包頁面上更新。

釋出package

釋出package之前,要好好檢查你的檔案裡是否包含某些私人資訊,敏感資訊。請注意刪除或者釋出時忽略掉。使用.npmignore.gitignore檔案來忽略掉,詳情見

釋出包命令:

npm publish
複製程式碼
  1. 如果要釋出一個未指定域的公用包,直接執行上述命令即可。
  2. 如果要釋出一個指定域的私有包,直接執行上述命令即可(預設指定域是私有包)。需要注意的是,publish之前要注意npm所在registry,如你要釋出到公司的registry裡,則釋出前需要切換到公司registry下,才執行該命令,例如使用上一篇提到的npmrc工具
  3. 如果要釋出一個指定域的私有包進行公有化,執行
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.jsondependencies裡,其實這是個預設的行為,即就算不加上--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>
複製程式碼

指定刪除某個全域性包

相關文章