簡述
npm 全稱為 node package manager, 即 node的包管理器。 我覺得正是因為有npm 這一大生態,才有了現在node 社群的繁榮。我這篇文章會歸納總結一些我們常用的 npm 知識,包括npm 命令、版本管理、依賴、以及如何釋出一個包。
package.json
package.json 是npm包的入口, 涵蓋了這個包的基本資訊, 如圖我在資料夾中進行 npm init
, 會讓我填寫以下資訊:
一個 常見的package.json 檔案如下:
{
"name": "foo",
"version": "1.0.0",
"description": "test ",
"main": "index.js",
"scripts": {
"test": "jest"
},
"dependencies": {
"ramda": "^0.25.0",
"react": "^16.0.0"
},
"repository": {
"type": "git",
"url": "test.git"
},
"keywords": [
"some",
"keywords"
],
"author": "Bob",
"license": "MIT"
}
複製程式碼
- 其中
main
代表此包的入口檔案, 當別的包進行var foo = require ('foo')
的時候, 引用的其實就是這個main
欄位代表的index.js
檔案 scripts
代表 在這個npm包中執行的命令dependencies
代表這個npm 包依賴的包, 當npm install foo
的時候,會將這個包的依賴包也一起安裝
version
一個npm包從誕生開始,程式碼庫會不斷地迭代,developer可能會不斷地新增新功能、增加新特性、修改bug等,那麼這個包的版本也會不斷變化, 如何比較好的管理(迭代)一個包的版本呢? 我們可以參考react的CHANGELOG 我們可以用 npm version
命令, 而不是手動地去更改 package.json
檔案。常用的命令如下:
官方: npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
假如當前包的版本號是1.0.5
-
npm version 1.0.5-beta17
"version": "1.0.5" => "version": "1.0.5-beta17"
明確指定需要更新到的版本號, 開發階段,一般用alpha, beta, rc
-
npm version prerelease
"version": "1.0.5" => "version": "1.0.5-2"
基於現在版本的先行版本
-
npm version patch
"version": "1.0.5" => "version": "1.0.6"
Fix bug, 小改動 ,仍向後相容
-
npm version minor
"version": "1.0.5" => "version": "1.1.0"
增加新特性,仍向後相容
-
npm version major
"version": "1.0.5" => "version": "2.0.0"
大改動,大版本,無法向後相容
-
npm version premajor
"version": "1.0.5" => "version": "v2.0.0-0"
大改動,大版本的先行版本,無法向後相容
所有的
npm version pre(xxx)
命令都會是一個先行版本, 會在版本號後面 多出-n
,代表這不是一個正式版本.
~
與^
代表什麼?
我們 常會在程式碼中看到這樣一段:
"ramda": "^0.25.0",
"react": "~16.0.0"
複製程式碼
~
代表 你在專案中更新包(npm update)的時候, 可以更新到最新的一個 patch版本 即 從 0.25.0 => 0.25.x
,但不包括 0.26.x
^
代表 你在專案中更新包(npm update)的時候, 可以更新到最新的一個 minor版本 即 從 16.0.0 => 16.x.x
,但不包括 17.x.x
update
一般我們用npm 的話, 直接npm i packageName 這樣就可以直接安裝最新的包了, npm update用的比較少,不如直接npm install 來的方便。 yarn 除外, yarn 需要自己 yarn upgrade packageName@x.x.x 這樣。
registry
由於國外的伺服器訪問速度可能比較慢,有時候我們需要訪問映象源,這時候我們可以使用 cnpm 或者設定國內的映象源
- 全域性使用:
- npm set registry https://registry.npm.taobao.org (或者 npm config set registry otherUrlPath , 具體config使用請看
npm config -h
) - 官方registry地址: http://registry.npmjs.org
- npm set registry https://registry.npm.taobao.org (或者 npm config set registry otherUrlPath , 具體config使用請看
- 專案中使用: .yarnrc或者.npmrc中設定
registry "http://npm.xxx.com/"
- npm config get registry (或者npm get registry) 可以獲取當前使用的源 地址資訊
npm info
npm info packageName 檢視指定包的發版資訊, 一般我用它來檢視此包的最新發版記錄
npm publish
激動人心的時刻!如果想釋出一個包到 npm 上,那麼按照如下步驟進行操作
- npm adduser --registry https://registry.npmjs.org
- npm publish用於將當前模組釋出到npmjs.com。執行之前,需要向npmjs.com申請使用者名稱。(adduser)
npm publish --tag beta (如果當前包是一個beta版)
注意: 不能釋出npm中已經存在的包
npm unpublish
- npm unpublish packageName --force
- 根據規範,只有在發包的24小時內才允許撤銷釋出的包( unpublish is only allowed with versions published in the last 24 hours)
- 即使你撤銷了釋出的包,發包的時候也不能再和被撤銷的包的名稱和版本重複了(即不能名稱相同,版本相同,因為這兩者構成的唯一標識已經被“佔用”了)
npm link 本地關聯包
當我們在發包前需要進行本地測試的時候,往往需要 npm link 進行管理包測試
相關連結:
javascript.ruanyifeng.com/nodejs/npm.…
使用步驟:
-
在需要關聯的包(比如packageName)資料夾內執行 sudo npm link 然後會顯示:
/usr/local/lib/node_modules/packageName -> /Users/shaoqianfei/Desktop/work/packageName
-
然後在需要用到此包的專案中執行 npm link packageName 然後顯示
added 1 package in 0.756s
/Users/shaoqianfei/Desktop/test-sth/node_modules/packageName -> /usr/local/lib/node_modules/packageName
複製程式碼
刪除
如果需要刪除關聯 可以在專案目錄內使用npm unlink
命令
有一些坑:
如果在outer
包目錄(此包有package.json)下面有兩個包package1 和package2,在package2 目錄下執行 npm link
命令,則會link outer 這個包 , 而不是package2:heavy_exclamation_mark: (它會link最外層包)
解決辦法,先把最外層的package.json改為 package.json-xxx, 然後在內層包進行npm link, 然後再改回原來名字。如果link有改動,需要重新npm start.否則快取的是原來的檔案 (或者嘗試先將 import 語句註釋掉,然後再import來解決)
npm 包依賴
devDependencies也會被打包
我 從網上 看到, 大多數人都說 dependencies與devDependencies的區別是: 前者是生產環境需要的,比如 react , lodash , 後者是 開發環境才需要的,比如 babel, eslint,jest
等等。還有人說:"如果安裝到 devDependencies 則 npm run build
打包的時候,不會打包到最終的檔案中去,上到生產環境會報錯(比如 lodash安裝到devDependencies中)".
然而,我親自試了一下,將jquery包安裝到 devDependencies, 然後
import $ from "jquery" // 當然此處是需要import 或者 require jquery的,不然jquery不會被打包
console.log("上午11:06:36", $, $('body'))
複製程式碼
無論是在開發環境, 還是打包完成之後到生產環境(用的http-server跑build資料夾)都是 ok 的, 結果都能正常顯示如下:
上午11:06:36 ƒ (e,t){return new Ee.fn.init(e,t)} Ee.fn.init [body, prevObject: Ee.fn.init(1)]
複製程式碼
並且 我在 打包之後的js檔案中搜素 jquery
也能搜尋到. 這說明 ~即便是~, devDependencies的包且被引用的情況下也會被打包到生產環境中,並不會報錯, 網上的說法是錯誤的,把npm包 裝到devDependencies 能減小最終打包的體積也是錯誤的devDependencies
的包也會被打包到生產環境
https://mp.weixin.qq.com/s/i_Zxaie1xMALymQ-1Jqz_Q 此文章說 把npm包 裝到devDependencies 能減小最終打包的體積
專案使用
並且,我看我現在的專案 babel eslint husky
是放在 devDependencies
中的,然而在 create-react-app使用上, npm run eject
之後, 能看到 babel,eslint, react
等都是放在 dependencies中的, 說明其實放到dependencies 和 devDependencies 區別只是 讓開發者能夠辨別 哪些是包主要是用於開發的時候,哪些是無論如何都需要的很重要的包。
~二者最終都會打包的。~ 被引用(import/require)的包會被打包,沒被引用的包或者只是和開發環境相關的包不會被打包如: webpack, eslint
等不會被打包。
總結
npm 生態很大, 本文只是介紹了一些 基本使用, 還有很多東西需要去探索。比如為了更好的開發體驗,可以使用 nrm 進行 registry 的管理, nodemon進行應用開發, 使用pm2進行nodejs程式管理等等。
參考連結
www.ruanyifeng.com/blog/2016/1…