Skip to main content

[指令] npm cli

npm init -y # --yes, 接受所有預設值產生 package.json
npm init --scope=@pjchender -y # --scope, 專案屬於某個 scope 底下
npm ls --depth 0 # 列出該專案安裝的套件
npm ls --depth 0 | grep react # 只列出和 react 有關的套件
npm install <package>@latest # latest stable release
npm install <package>@beta # latest beta release
npm view <package> # 檢視該套件有哪些版本
npm home <package> # 進到該套件的官網
npm repo <package> # 進到該套件的 github
npm docs <package> # 進到該套件的文件
npm run # 列出所有該 package 定義的指令
npm prune # 移除多餘沒用到的套件
npm doctor # 檢查 node, npm 版本,並檢驗有無足夠的權限安裝 dependencies
npm dedupe # npm ddp,移除重複的套件(duplicate packages)
npm outdated # 檢查版本過期的套件
npm outdated -l # --long
npx <package> # 執行某個 package 內的指令
npx sort-package-json # 重新排序 package.json 的檔案(第三方)

預設的情況下 scope 的專案是 restricted,但這需要額外付費,因此可以透過設定把它改成 public,設定的方式可以參考這裡

npm init # 專案初始化(建立 package.json)
npm install # 根據 package.json 安裝所需要的檔案
npm install --save <packageName> # 套件會安裝在 dependencies 中(簡寫 -S)
npm install --save-dev <packageName> # 套件會安裝在 devDependencies 中(簡寫 -D)
npm install --global <packageName> # 套件會以全域的方式安裝(簡寫 -g)
npm install <packageName>@~1.14 # 安裝特定版本的模組
npm install <packageName>@latest # 安裝最新的穩定版
npm install <packageName>@next # 安裝最新的版本
npm uninstall <packageName> # 解除安裝〈簡寫 un〉
npm list # 列出所有已安裝的套件
npm update # 更新套件, -dd 顯示詳細資訊
npm prune # 根據 package.json 移除和專案無關的套件
npm outdated # 告訴你有哪些安裝的套件已經不是最新版了
sudo npm i -g npm # 更新 npm
npm -v # 查看 npm 版本
npm init # 初始化 package.json

使用 npm update 時,仍會依據 package.json 所定的版號作為依據,不會直接更新到最新版。

npm documentation @ npm

安裝模組參數說明#

-g, --global 全局安裝(global)
-S, --save 安裝包信息將加入到dependencies(生產階段的依賴)
-D, --save-dev 安裝包信息將加入到devDependencies(開發階段的依賴),所以開發階段一般使用它
-O, --save-optional 安裝包信息將加入到optionalDependencies(可選階段的依賴)
-E, --save-exact 精確安裝指定模塊版本

開發套件相關#

npm init # 建立 npm module (package)
npm ci # 在 CI 環境執行 npm install(確保相依套件是乾淨的)
npm adduser # 建立使用者
npm login # 登入使用者
npm config ls # 檢視本地端記錄了哪些註冊的使用者
npm publish # 上傳 package 到 npm(版本變動時上傳就是更新)
npm version <major | minor | patch> # 透過 cli 更新版本編號
npm deprecate <package-name> "<message>" # 不再維護某一專案
npm deprecate <package-name>@<version> "<message>" # 不再維護專案的某一版本
npm unpublish # 移除 npm 上的 package(需聯絡 npm)
# 將不繼續維護的的套件轉移給 npm 組織
npm owner add npm <package-name>
npm owner rm <user> <package-name>
# 將本地套件建立捷徑以方便測試
npm link # 進到要測試的套件中(例如 foo),執行後會在 global 產生一個捷徑
npm link foo # 進到要使用測試套件的專案中,執行 npm link <local_package>

npm ci 會依據 package-lock.json 中所定義的版號安裝套件,並且會移除 node_modules 以乾淨的環境重新安裝

workspaces#

npm 7 支援 workspaces 的功能,讓開發者可以從單一個上層的 root package 管理底下多個 packages。

定義 workspaces#

只需要在 package.json 中使用 workspaces 這個欄位,裡面指的是 root packages 裡面的其他 packages:

// package.json
{
"name": "my-workspaces-powered-project",
"workspaces": ["workspace-a", "packages/*"]
}

workspaces 中套件安裝的位置#

當我們的資料夾結構是:

.
├── packages
│   ├── bar
│   └── foo
└── workspace-a

. 執行 npm install 時,會在根目錄的 node_modules 內會多一個名為 workspace-afoobar 的捷徑,它會指向 ./workspace-apackages/foopackages/bar 的專案位置。像是這樣:

.
├── node_modules
│   ├── bar -> ../packages/bar
│   ├── foo -> ../packages/foo
│   └── workspace-a -> ../workspace-a
├── packages
│   ├── bar
│   └── foo
└── workspace-a

對於會重複在多個 packages 中使用到的套件,實際套件會安裝在根目錄的 ./node_modules 中。

直接把 workspaces 內的套件當成 package 匯入#

由於會在根目錄的 node_modules 中建立捷徑,因此我們也可以直接把 workspaces 中定義好的套件 workspace-apackages/foopackages/bar 直接匯入。例如:

// ./workspace-a/index.js
module.exports = 'workspace-a';
// ./packages/foo/index.js
module.exports = 'foo';
// ./packages/bar/index.js
module.exports = 'bar';

匯入這些 workspaces 中的套件:

// ./index.js
const a = require('workspace-a'); // 'workspace-a'
const b = require('foo'); // 'foo'
const c = require('bar'); // 'bar'
// ./packages/foo/index.js
const bar = require('bar'); // 也可以直接匯入 'bar'
module.exports = 'foo';

在 root package 執行 npm 指令#

在執行 npm 指令時,可以透過 --workspace="package-name" 這個 option 來執行 workspaces 內某 package 的指令;如果是想要一次執行 workspaces 內的所有 npm script,則可以使用 --workspaces(多 s)。例如,當執行:

# 只執行 workspace-a 裡的 npm script
$ npm run start --workspace=workspace-a
> [workspace-a] I am workspace-a
# 執行 workspace-a 和 bar 裡的 npm script
$ npm run start --workspace=workspace-a --workspace=bar
> [workspace-a] I am workspace-a
> [bar] I am bar
# 執行所有 workspaces,記得要加 s
$ npm start --workspaces

套件更新#

How to Publish an Updated Version of an npm Package @ cloud 4

NPM Scripts and Package.json#

# 使用 && 會依序執行各個指令
$ npm run build && npm run start
# 使用 & 會平行(parallel)執行多個指令
$ npm run build & npm run start
# 使用 -- 可以帶入參數
$ npm run foo -- "hello"
  • preinstall 會在所有套件安裝前執行
  • npm run env 列出 package 中所有環境變數,和在程式中使用 process.env.npm_package_name 類似
  • 在 package.json 中可以新增 config 欄位,來裡面定義的變數將可以透過 npm_package_config_foo 取得
// npm_package_config_foo=Hello World
"config": {
"foo": "Hello World"
},

問題解決與錯誤處理#

解決 package-lock.json 檔案內容異動的問題#

$ rm -rf node_modules/
$ npm cache clean --force
(Revert the changes in your package-lock.json file) # 還原到原本的 package-lock.json
$ npm install

npm install downgrading resolved packages from https to http registry in package-lock.json

npm cache 位置#

有些時候更新了 package.json 中的設定後(例如,browserslist),卻沒有立即產生對應的改變,這有可能是 babel-loader 沒有偵測到 package.json 中的變化,這時候可以刪除 node_modules/.cache 的檔案:

$ ls node_modules/.cache

package.json 範例#

{
"name": "webpack-example",
"version": "0.0.1",
"scripts": {
"build": "webpack --optimize-minimize" // 寫這行之後,我們就可以打 npm run build 來執行這行的指令
"start": "webpack-dev-server"
},
"devDependencies": { // 開發環境會用到的 package
"babel-core": "^6.23.1",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.9.0",
"babel-preset-stage-2": "^6.11.0",
"css-loader": "^0.23.1",
"html-webpack-plugin": "^2.22.0",
"node-sass": "^3.8.0",
"sass-loader": "^4.0.0",
"style-loader": "^0.13.1",
"webpack": "^1.13.1"
},
"dependencies": { // app 運作時會用到的 package
"jquery": "^3.1.0"
}
}

參考#

Last updated on