做者: LeanCloud weakish前端
分享一些 npm 包管理工具的實用小竅門,但願可以略微提升下前端、Node.js 開發者的生活質量。
絕大多數前端和 Node.js 開發者天天的平常工做都離不開 npm,不知道你對 npm 的觀感如何?若是你以爲 npm 很棒,那麼不妨看下這篇文章,說不定其中有你以前沒留意過的小竅門,可讓你 npm 用得更順手。若是你以爲 npm 很糟糕,那也能夠看下這篇文章,也許會發現用上一些小技巧,npm 會變得稍微不那麼糟糕。node
別被它的名字騙了。npm ci
並不只僅適用於持續集成系統,在平常開發中,npm ci
很是實用。和 npm install
不一樣,npm ci
根據 package-lock.json
安裝依賴,這能夠保證整個開發團隊都使用版本徹底一致的依賴,避免把時間浪費在排查由於依賴不一致而致使的各類奇怪問題上。不只如此,npm ci
還有一個很好的反作用,加快 node 模塊安裝速度。由於 npm ci
直接根據 package-lock.json
中指定的版本安裝,無需計算求解依賴知足問題,在大多數狀況下均可以大大加速 node 模塊安裝過程。若是你曾經由於嫌 npm install
太慢而換用兼容性不那麼好的 yarn 以及兼容性更很差的 pnpm,那麼不妨試下 npm ci
,也許你會發現,其實 npm 也能夠不那麼慢。webpack
另外,若是 package-lock.json
過期(和 package.json
衝突),那麼 npm ci
會很貼心地報錯,避免項目依賴陷入過期狀態。git
有了 npm ci
,基本上我只在引入新依賴時才使用 npm install
。程序員
注意,npm ci
在安裝前會自動清除現存的 node_modules
,因此 npm ci
自然規避了增量安裝可能帶來的不一致性等問題。(這也意味着,你又能夠少記一條命令 npm prune
。)不過,若是你的網絡很慢,那可能就不那麼妙了。別慌,你能夠用 --prefer-offline
,最大限度地利用 npm 的全局緩存加速安裝過程。github
固然,既然使用 npm ci
,那就別忘了把 package-lock.json
加入 git 倉庫。web
npm ci
基於 package-lock.json
鎖定依賴版本,確保項目開發環境的一致性。但這並不意味着依賴版本是鎖死的。爲了利用新版本帶來的問題修復、新特性以及性能提高,按期仍是須要升級依賴版本的。在這一場景下,推薦使用 npm outdated
。它會列出尚未升到當前最新版本的項目依賴。紅色表示符合指定的語義化版本範圍,理論上能夠無腦升級(npm update
會一次性升級全部紅色依賴)。黃色表示不符合指定的語義化版本範圍,好比大版本升級,升級可能會遇到兼容性問題。npm
有些項目處於維護階段,不打算加新特性了,甚至可能不太嚴重的問題都不打算修復了,可是像安全漏洞這樣的嚴重問題仍是要管的。這時可使用 npm audit
命令,列出項目依賴中有安全漏洞的版本。處於活躍開發階段的項目固然也須要關注安全漏洞問題,可是由於 npm install
引入新依賴時會自動運行 npm audit
,再加上會按期運行 npm outdated
,因此手動運行 npm audit
的機會不太多。json
前面說過基本上只在引入新依賴時才使用 npm install
,沒有提到全局安裝。全局安裝固然也須要使用 npm install
。不過,爲了確保開發環境的一致性,npm install --global
應當慎用。我的建議僅僅在安裝一些平常使用的工具時才使用全局安裝,而項目開發所需的工具,則做爲開發依賴安裝,而後使用 npx
調用。緩存
不推薦:
npm install --global webpack webpack ...
推薦:
npm i -D webpack npx webpack ...
這裏 i -D
是 install --save-dev
的簡寫形式。
對於一些一次性的臨時任務,能夠直接經過 npx 運行相應工具,免去了手動安裝的麻煩,也不會污染 devDependencies
。
例如,以前項目使用 webpack 打包,如今想臨時試下換用 rollup 打包的效果:
npx rollup ...
npx 很智能,若是路徑中找不到 rollup,會自動安裝。
npx 用來測試不一樣版本的兼容性時很是好用。下面是一些例子。
須要用到的 cowsay
的某個特性或修復已經合入 GitHub 主線,可是還沒在 npmjs 上發新版,試一下:
npx github:piuccio/cowsay
臨時測下內部維護的 cowsay
的一個分支:
npx git+ssh://my.hosted.git:cowsay.git#semver:^1
當前使用的是 node 的 LTS 版本(10),想試下 node 12 下構建腳本能不能跑起來:
npx -p node@12 npm run build
從上面咱們能夠看到,當包名和命令名不一樣時(npm
命令由 node
提供),能夠用 -p
選項指定包名。
在 package.json
的 scripts
屬性中加入命令(例如:"foo": "echo foo"
)就能夠經過 npm run foo
運行對應命令。這是 npm 提供的一個很方便的運行項目相關的自動化任務的機制,有一點相似 make
。不過直接運行 make
(不帶任何參數)會運行默認任務,但直接運行 npm run
(不帶任何參數)會列出全部在 scripts
中聲明的命令。
; npm run Lifecycle scripts included in leancloud-realtime: test npm run lint && npm run build && npm run docs && npm run test:node && npm run test:browser available via `npm run-script`: precommit pretty-quick --staged commitmsg commitlint -e $GIT_PARAMS lint eslint --ignore-path .gitignore src test plugins && tsc realtime.d.ts --strict ...
這裏還有一些我我的以爲不是特別實用的小竅門,不過,每一個人的需求和偏好不一樣,說不定你會以爲它們挺有用的。若是你有想要分享的竅門,歡迎留言。
npm init -y
默認狀況下,npm init
會讓你回答一些問題。npm init -y
能夠跳過這些問題,直接上手開發。我之因此不推薦它,是由於,若是你打算儘快上手開發一個應用,絕大多數狀況下會用框架,而幾乎全部框架在 npmjs 上都至少有一個 create-xxx-app
包。因此基本上你沒有機會輸入 npm init
去回答那些問題。而若是你打算寫一個組件或庫,那麼 package.json
中的元信息對組件或庫的使用者很重要(即便是僅供你本身使用的組件或庫,將來的你也未必記得當初寫這個組件或庫的上下文),跳過這些問題並非一個好主意。固然,急躁是程序員的三大美德,你也許會想,我能夠在完成開發後再來補這些。可是,通常來講,每每項目開始的時候是你最有興趣(或者說,稍微不那麼反感)記錄這些上下文的時刻。若是在項目開始的時候都不耐煩作這個,開發完成後,極可能就更沒興趣了。同理,README 也應該在項目開始前寫。npm repo
能夠打開項目的源代碼倉庫(大部分狀況下是 GitHub),它還有一個姊妹命令,npm home
,能夠打開項目的主頁。不過,我我的以爲,比起這兩個命令,一般而言, IDE 或者編輯器的智能提示(速覽類型、速覽文檔、速覽定義之類)更高效。.npmignore
文件能夠列出不想打包的文件,避免把一些無關的文件發佈到 npmjs 上。可是,統一使用 .gitignore
能夠知足絕大部分場景下的需求。並且,只存在 .gitignore
的狀況下,npm publish
會尊重 .gitignore
的聲明,而 .npmignore
和 .gitignore
同時存在的狀況下,npm publish
會忽略 .gitignore
,而不是取二者的並集。換言之,.gitignore
中忽略但 .npmignore
中未忽略的文件會被打包發佈。因此,使用 .npmginore
就意味着須要同時當心翼翼地維護兩份大部份內容重複的列表。同時,一旦團隊中有任何一人由於偶然的疏忽或者不熟悉 .npmignore
和 .gitignore
關係的細節出現了失誤,那就有可能將敏感信息發佈到 npmjs 上,致使安全事故。npm i -D
。這些我的以爲不用專門刻意去記。常常輸入的命令,能夠 npm help
一下看看有沒有簡短版本。不查也沒有關係,npm t
和 npm test
乃至 npm run test
的區別毫不是開發效率的瓶頸所在。不少時候這只是我的偏好問題,好比追求儘量少打字的人會喜歡 npm t
,追求儘量少記東西的人會喜歡 npm run test
(永遠不會由於誤覺得 npm build
表示 npm run build
而碰到問題),其餘人可能會喜歡 npm test
這樣中庸的選項。npm xmas
猜猜輸入這個命令會獲得什麼結果?你能夠親自試一下。提示:這個命令徹底沒有實用性可言。;-)