In this article
JavaScript開発者が知っておくべきnpm上級者向けコマンド10選
上級者向けコマンドを使えば、複雑なタスクを簡素化し、プロジェクトの依存関係や設定について、より深く把握できます。脆弱性の特定からソフトウェア部品表(SBOM)の生成まで、これらのコマンドを活用して、効率的でセキュリティ意識の高い開発者を目指しましょう。
npmパッケージマネージャーは、JavaScriptおよびNode.jsエコシステムに欠かせないツールです。依存関係、スクリプト、設定を管理し、開発ワークフローを効率化する基盤となります。小規模なプロジェクトでも大規模なアプリケーションでも、npmコマンドを使いこなすことで、生産性とコード品質を大きく向上できます。
安全なJavaScriptプロジェクトを実現するSnyk
現代のソフトウェア開発において、セキュリティは欠かせない要素です。SnykはJavaScriptの開発ワークフローにシームレスに統合し、ソースコード、オープンソースパッケージ、コンテナイメージ、クラウド設定の脆弱性をスキャンします。
これらのnpm power-userコマンドを確認しながら、Snykの無料アカウントに登録してセキュリティ態勢を強化することも検討してみましょう。
1. --を使ってコマンドラインフラグをnpm runスクリプトに渡す
複雑なプロジェクトでは、npm runで実行するスクリプトに、追加のコマンドラインフラグを渡す必要がよくあります。スクリプト自体を変更せずに動作を調整したい場合に特に便利です。たとえば、環境を動的に変更したり、デバッグを有効にしたり、設定オプションを渡したりできます。
npm runスクリプトでの使用例
npm runスクリプトが実行するプログラムにコマンドラインフラグを渡すには、ダブルダッシュの--構文を使います。--以降のすべての内容が、スクリプトに直接渡されます。
簡単な例を見てみましょう。
{
"scripts": {
"start": "node app.js"
}
}
次のように実行すると、startスクリプトを起動し、app.jsプログラムに追加のフラグを渡せます。
npm run start -- --port=3000 --env=productionこの場合、--port=3000と--env=productionが、位置引数としてスクリプトapp.jsに渡されます。
セキュリティ上の注意点
フラグを動的に渡すと強力な処理ができますが、セキュリティリスクが生じる可能性もあります。スクリプトと渡すフラグが安全であることを確認し、機密情報の漏えいや意図しない動作を招かないようにしてください。動的なフラグを扱う場合は、必ず入力値を検証し、サニタイズしましょう。
2. npm lsで依存関係ツリーを調べる
JavaScript開発者にとって、どの脆弱性がどのパッケージに影響するかを特定するには、プロジェクトの依存関係ツリーを理解する必要があります。npm lsは、依存関係ツリーを調べるのに役立つ上級者向けコマンドの1つです。プロジェクトが依存するすべてのパッケージについて、バージョンや階層関係を含むASCIIツリー形式で表示します。
npm lsコマンドの構文と絞り込みオプション
npm lsコマンドの基本的な構文は次のとおりです。
npm ls [<package-name>]このコマンドでは、すべての依存関係を一覧表示することも、パッケージ名を指定して特定のパッケージに絞り込むこともできます。また、--productionまたは--developmentフラグを使って、本番用または開発用の依存関係だけを表示できます。
特定の脆弱性の影響を受ける依存関係を見つける例
たとえば、ms npmパッケージにサービス拒否の脆弱性が見つかったとします。脆弱なバージョンによってプロジェクト内のどの依存関係が影響を受けるかを特定するには、npm lsコマンドを使います。
このコマンドは依存関係ツリーを出力し、msが使われている箇所を示します。出力例は次のとおりです。
> npm ls ms
goof@1.0.1 /Users/lirantal/projects/repos/nodejs-goof
├─┬ express-session@1.17.2
│ └─┬ debug@2.6.9
│ └── ms@2.0.0
├─┬ express@4.12.4
│ ├─┬ debug@2.2.0
│ │ └── ms@0.7.1
│ ├─┬ finalhandler@0.3.6
│ │ └─┬ debug@2.2.0
│ │ └── ms@0.7.1
│ └─┬ send@0.12.3
│ ├─┬ debug@2.2.0
│ │ └── ms@0.7.1 deduped
│ └── ms@0.7.1
├─┬ humanize-ms@1.0.1
│ └── ms@0.6.2
├─┬ method-override@3.0.0
│ └─┬ debug@3.1.0
│ └── ms@2.0.0
├─┬ mongoose@4.2.4
│ ├─┬ mquery@1.6.3
│ │ └─┬ debug@2.2.0
│ │ └── ms@0.7.1
│ └── ms@0.7.1
├─┬ morgan@1.10.0
│ └─┬ debug@2.6.9
│ └── ms@2.0.0ms@0.7.1のように、バージョンを指定して検索することもできます。
3. npm whyでトランジティブ依存関係を把握する
大規模なJavaScriptプロジェクトでは、依存関係の管理が複雑になることがあります。特に、package.jsonに直接記載されていないものの、直接依存するパッケージから必要とされるトランジティブ依存関係を扱う場合はなおさらです。
特定のパッケージがプロジェクトに含まれている理由を特定することは、アプリケーションのデバッグやセキュリティ確保に欠かせません。npm whyコマンドは、特定のパッケージがインストールされている理由を詳しく表示します。
npm whyコマンドは簡単に使えます。基本的な構文は次のとおりです。
> npm why ms@0.7.1
ms@0.7.1
node_modules/send/node_modules/ms
ms@"0.7.1" from send@0.12.3
node_modules/send
send@"0.12.3" from express@4.12.4
node_modules/express
express@"4.12.4" from the root project
send@"0.12.3" from serve-static@1.9.3
node_modules/serve-static
serve-static@"~1.9.3" from express@4.12.4
node_modules/express
express@"4.12.4" from the root project
ms@"0.7.1" from debug@2.2.0
node_modules/send/node_modules/debug
debug@"~2.2.0" from send@0.12.3
node_modules/send
send@"0.12.3" from express@4.12.4
node_modules/express
express@"4.12.4" from the root project
send@"0.12.3" from serve-static@1.9.3
node_modules/serve-static
serve-static@"~1.9.3" from express@4.12.4
node_modules/express
express@"4.12.4" from the root projectご覧のとおり、このnpmコマンドは、msが含まれている理由を詳しく出力し、インストールに至った依存関係の連鎖を表示します。
npm whyコマンドの便利なヒント
バージョンを指定する: 問題の原因となっている特定のバージョンがわかっている場合は、コマンドに追加すると、より正確な結果が得られます。
npm why ms@0.7.1JSON出力を使う: 依存関係の種類やその他のメタデータを含む、より豊富で詳細な出力を得るには、
--jsonフラグを使います。
npm why ms@0.7.1 --json自動化スクリプトや、より詳細な分析を行う場合に特に便利です。
トランジティブ依存関係を理解することは、安全で効率的なコードベースを維持するうえで欠かせません。Snyk Open Sourceなどのツールを使えば、依存関係をスキャンして既知の脆弱性を検出し、実行可能な分析結果を得られます。今すぐプロジェクトを保護するには、こちらからSnykの無料アカウントに登録してください。
依存関係管理について学び始めたばかりで、ロックファイルの仕組みを知りたい方には、「package-lock.jsonとは?yarnとnpmパッケージでのロックファイルの仕組み」もおすすめです。この記事では、セマンティックバージョニング、shrinkwrapロックファイル、ロックファイルのずれなど、npmのロックファイルに関する重要な概念を解説しています。
4. npm runで利用可能なライフサイクルスクリプトを一覧表示する
JavaScriptまたはNode.jsのプロジェクトでは、package.jsonに定義されたさまざまなスクリプトを実行することがよくあります。たとえば、npm run testやnpm run buildなどです。
しかし、こうしたnpm lifecycleスクリプトの名前をすべて正確に覚えておくのは大変です。特に、大規模なプロジェクトや複数のプロジェクト(バックエンドとフロントエンドなど)を定期的に扱う場合はなおさらです。
そんなときに役立つのがnpm runコマンドです。プロジェクトで利用可能なライフサイクルスクリプトをすべて一覧表示するため、どのスクリプトをどう実行できるかを簡単に確認できます。
プロジェクト内のnpm runスクリプトをすべて表示する実用的な例を見てみましょう。
> npm run
Lifecycle scripts included in goof@1.0.1:
start
NODE_OPTIONS=--openssl-legacy-provider node app.js
test
snyk test
available via `npm run-script`:
dev
NODE_OPTIONS=--openssl-legacy-provider nodemon ./app.js
build
browserify -r jquery > public/js/bundle.js
cleanup
mongo express-todo --eval 'db.todos.remove({});'出力には、利用可能なnpm runスクリプトと、それぞれが実行するコマンドが一覧表示されます。IDEやターミナルでpackage.jsonを開く手間を省けます。
5. npm queryで依存関係を高度に検索する
npmパッケージマネージャーに、属性に基づいて依存関係を絞り込み、選択できる機能があることは、あまり知られていないかもしれません。サードパーティー依存関係の影響を把握したり、対象を絞った操作を行ったりする際に便利ですが、目的のnpm依存関係を見つけるのは難しい場合があります。
npm queryコマンドはnpm@8で導入され、クエリ言語を使って依存関係を高度に検索する強力な方法を提供します。属性に基づいて依存関係を絞り込み、選択できるため、プロジェクトの依存関係を管理・監査しやすくなります。
npm queryの構文の使い方
npm queryコマンドの構文は次のとおりです。
npm query "<query>"難しいのはクエリ部分です。さまざまな属性や演算子を使って検索対象を絞り込める専用言語(DSL)です。たとえば、ライフサイクルスクリプト、バージョン、サードパーティーパッケージが持つその他のメタデータに基づいて依存関係を絞り込めます。
例: postinstallスクリプトを持つ依存関係を見つける
プロジェクト内でpostinstallスクリプトを持つ依存関係をすべて見つけたいとします。インストール時にスクリプトを実行するパッケージを特定するのに役立ちます。こうしたパッケージはセキュリティリスクとなったり、ビルドプロセスに影響したりする可能性があります。次のクエリを使います。
npm query ":attr(scripts, [postinstall])"このコマンドは、postinstallスクリプトが定義されたpackage.json ファイルを持つ依存関係の一覧を返します。
出力例は次のようになります。
[
{
"name": "some-package",
"version": "1.0.0",
"scripts": {
"postinstall": "node setup.js"
}
}
]この例では、some-packageにpostinstallスクリプトがあり、node setup.jsを実行します。この情報を使って、依存関係に潜むセキュリティリスクや望ましくない動作を監査できます。
ヒント: オープンソースのサプライチェーンセキュリティツールnpqを使えば、インストール前に依存関係がpostinstallまたはpreinstallスクリプトを含むかどうかを確認し、事前に対処できます。
6. npm diffでバージョンを比較する
パッケージの異なるバージョン間での変更内容を理解することは、安全で安定したコードベースの維持に欠かせません。パッケージの2つのバージョン間で何が変わったかを調べる際にも便利です。
npm diffコマンドを使うと、パッケージの2つのバージョンを比較できます。潜在的なセキュリティ問題、非推奨になった機能、依存関係の変更、アプリケーションに影響する可能性のある大幅な変更を特定するのに特に役立ちます。
npm diffコマンドは簡単に使え、git diffコマンドとよく似ています。
npm diff --diff=<package@version1> --diff=<package@version2>msパッケージのバージョン2.1.2と2.1.3の変更を比較する場合、次のコマンドを実行します。
npm diff --diff=ms@2.1.3 --diff=ms@2.1.2git diffと同様に、コードの差分が出力されます。
diff --git a/index.js b/index.js
index v2.1.3..v2.1.2 100644
--- a/index.js
+++ b/index.js
@@ -23,7 +23,7 @@
* @api public
*/
-module.exports = function (val, options) {
+module.exports = function(val, options) {
options = options || {};
var type = typeof val;
if (type === 'string' && val.length > 0) {
diff --git a/package.json b/package.json
index v2.1.3..v2.1.2 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,8 @@
{
"name": "ms",
- "version": "2.1.3",
+ "version": "2.1.2",
"description": "Tiny millisecond conversion utility",
- "repository": "vercel/ms",
+ "repository": "zeit/ms",
"main": "./index",
"files": [
"index.js"
@@ -28,11 +28,10 @@
},
"license": "MIT",
"devDependencies": {
- "eslint": "4.18.2",
+ "eslint": "4.12.1",
"expect.js": "0.3.1",
"husky": "0.14.3",
"lint-staged": "5.0.0",
- "mocha": "4.0.1",
- "prettier": "2.0.5"
+ "mocha": "4.0.1"
}
}
diff --git a/license.md b/license.md
index v2.1.3..v2.1.2 100644
--- a/license.md
+++ b/license.md
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2020 Vercel, Inc.
+Copyright (c) 2016 Zeit, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/readme.md b/readme.md
index v2.1.3..v2.1.2 100644
--- a/readme.md
+++ b/readme.md
@@ -1,6 +1,7 @@
# ms
-
+[](https://travis-ci.org/zeit/ms)
+[](https://spectrum.chat/zeit)
Use this package to easily convert various time formats to milliseconds.変更内容を確認し、セキュリティ脆弱性や互換性を損なう変更が含まれていないことを確かめましょう。
7. npm sbomでSBOMを作成してスキャンする
SBOMはSoftware Bill of Materials(ソフトウェア部品表)の略で、ソフトウェアに含まれるすべてのコンポーネントと依存関係を詳しく記載した一覧です。料理の材料を記したレシピのようなものです。
ソフトウェアの構成要素を可視化することで、潜在的な脆弱性を特定し、さまざまなセキュリティ基準への準拠を確認できます。SBOMは、ソフトウェアの構成要素を把握することがリスク管理と信頼性の確保に欠かせないサプライチェーンセキュリティにおいて、特に重要です。
セキュリティチームは、業界の基準や規制(サイバーセキュリティに関する大統領令など)への準拠を確認するために、SBOMを頻繁に利用します。
npm sbomの使い方とSnykとの連携
npm sbomコマンドは、プロジェクトまたはワークスペースのSBOMを生成します。
ソースコード、オープンソースパッケージ、コンテナイメージ、クラウド設定の脆弱性をスキャンする開発者向けセキュリティツール、Snykと組み合わせると特に便利です。
パッケージマネージャーとしてnpmを使い、プロジェクトのすべての依存関係についてSBOMを生成したうえで、依存関係ツリー全体をSnykに送信し、脆弱性をスキャンできます。これらの操作はすべてCLIから実行できます。
npm sbomを使ってCycloneDX形式のSBOMを作成する基本的な構文は次のとおりです。
npm sbom --sbom-format cyclonedx > sbom.cdx.json次に、このSBOMをSnykでスキャンして脆弱性を検出します。
snyk sbom test --experimental --file=sbom.cdx.jsonSBOM内で見つかった脆弱性と、その重大度が次のように出力されます。
× [HIGH] Regular Expression Denial of Service (ReDoS)
Introduced through: pkg:npm/negotiator@0.2.8
URL: https://security.snyk.io/vuln/npm:negotiator:20160616
× [HIGH] Uninitialized Memory Exposure
Introduced through: pkg:npm/npmconf@0.0.24
URL: https://security.snyk.io/vuln/npm:npmconf:20180512
× [HIGH] Prototype Override Protection Bypass
Introduced through: pkg:npm/qs@2.2.4
URL: https://security.snyk.io/vuln/npm:qs:20170213
× [CRITICAL] Incomplete List of Disallowed Inputs
Introduced through: pkg:npm/babel-traverse@6.26.0
URL: https://security.snyk.io/vuln/SNYK-JS-BABELTRAVERSE-5962463
× [CRITICAL] Prototype Pollution
Introduced through: pkg:npm/handlebars@4.0.11
URL: https://security.snyk.io/vuln/SNYK-JS-HANDLEBARS-534988
× [CRITICAL] Server-side Request Forgery (SSRF)
Introduced through: pkg:npm/parse-url@5.0.1
URL: https://security.snyk.io/vuln/SNYK-JS-PARSEURL-2936249
× [CRITICAL] Arbitrary File Write via Archive Extraction (Zip Slip)
Introduced through: pkg:npm/adm-zip@0.4.7
URL: https://security.snyk.io/vuln/npm:adm-zip:20180415
╭──────────────────────────────────────────────────────────────────────╮
│ Test summary │
│ Organization: a30b7399-4e0c-4f6e-ba84-b27e131db54c │
│ Test type: Software Bill of Materials │
│ Path: sbom.cdx.json │
│ │
│ Open issues: 148 [ 4 CRITICAL 64 HIGH 72 MEDIUM 8 LOW ] │
╰──────────────────────────────────────────────────────────────────────╯8. package.jsonのoverridesで依存関係のバージョンを固定する
すでに実感されているかもしれませんが、依存関係の管理は諸刃の剣です。npmを使えば依存関係を簡単に追加・管理できる一方、トランジティブ依存関係に起因するセキュリティ問題にプロジェクトがさらされる可能性もあります。
開発者が直面する大きな問題の1つは、こうしたトランジティブ依存関係に脆弱性や互換性を損なう変更が持ち込まれることです。たとえば、広く使われているパッケージに脆弱性や互換性を損なう変更が突然導入され、プロジェクト全体に影響することがあります。
npmには、リスクを軽減するための強力な機能として、package.jsonファイル内で使えるoverridesがあります。この機能を使うと、直接依存関係とトランジティブ依存関係の特定のバージョンを固定し、信頼できるバージョンだけをプロジェクトで使用できます。
overridesが非常に役立った実例として、2022年3月に発生したpeacenotwarおよびnode-ipcパッケージのプロテストウェアに関するセキュリティインシデントがあります。パッケージ利用者への影響を軽減するために活用されました。
package.jsonでoverrides設定を使う方法
overrides機能を使うには、package.jsonファイルにoverridesセクションを追加します。このセクションでは、依存パッケージ自身のpackage.jsonファイルに記載された内容にかかわらず、使用する依存関係のバージョンを指定します。
overridesの基本的な使用例を紹介します。
{
"name": "your-project",
"version": "1.0.0",
"dependencies": {
"some-package": "^2.0.0"
},
"overrides": {
"node-ipc@>9.2.1 <10": "9.2.1",
"node-ipc@>10.1.0": "10.1.0"
}
}この例では、次のようになります。
node-ipcパッケージは、9.2.1より大きく10未満のバージョンに対して、バージョン9.2.1に固定されます。node-ipcパッケージは、10.1.0より大きいバージョンに対して、バージョン10.1.0に固定されます。
Snykでセキュリティを強化
依存関係のバージョン固定は一部のリスクを軽減できますが、万能ではありません。プロジェクトの脆弱性を定期的にスキャンすることが重要です。Snykのような開発者ファーストのセキュリティツールなら、依存関係に含まれるマルウェアやプロテストウェア、その他のセキュリティ脆弱性をすばやく検出し、修正を支援します。
Snykを始めるには、こちらから無料アカウントに登録してください。
9. npm installを使ったローカルパッケージ開発
npmパッケージをローカルで開発する際は、別のプロジェクト内でテストする必要がよくあります。npmに組み込まれた機能を知らないと、パッケージをnpmレジストリに公開することになります。頻繁に変更を加える場合は特に、手間と時間がかかります。
npm install <path-to-package-in-disk-directory>コマンドを使えば、開発ディレクトリからローカルパッケージを直接インストールしてリンクできます。パッケージを開発しているディスク上のディレクトリへのソフトリンクが作成されるため、何度も公開しなくてもシームレスに更新やテストを行えます(シンボリックリンクのおかげで、ローカルでアンインストールして再インストールする必要もありません)。
このコマンドを使うには、ローカルパッケージをインストールするプロジェクトのルートディレクトリに移動し、次のコマンドを実行します。
npm install /path/to/local/package/path/to/local/packageを、ローカルパッケージのディレクトリへの実際のパスに置き換えてください。このコマンドによって、プロジェクトのnode_module'sディレクトリからローカルパッケージのディレクトリへのシンボリックリンクが作成されます。
npmでパッケージをローカルにインストールするメリット
すぐに反映:ローカルパッケージへの変更がプロジェクトに即座に反映されるため、再公開する必要がありません。
デバッグを簡素化:大規模なプロジェクトの中で、パッケージをリアルタイムにデバッグ、テストできます。
効率的なワークフロー:パッケージのバージョン管理や公開に伴う負担を減らし、開発プロセスを効率化できます。
10. .npmrc設定によるセキュリティと互換性
.npmrcファイルはnpmの設定ファイルで、npmコマンドの動作をカスタマイズできます。Node.jsプロジェクトのセキュリティと互換性の両方を高めるうえで重要な役割を果たします。.npmrcファイルで特定の設定を行うと、悪意のあるパッケージからプロジェクトを保護し、依存関係が特定のNode.jsランタイムバージョンと互換性を持つようにできます。
スクリプトを無効にしてセキュリティを強化
有害なパッケージや悪意のあるパッケージからプロジェクトを守る効果的な方法の一つは、ライフサイクルスクリプトの実行を無効にすることです。これらのスクリプトはインストール中に任意のコマンドを実行できるため、セキュリティリスクとなります。
.npmrcファイルでignore-scripts=trueを設定すると、これらのスクリプトが実行されないようにできます。
# .npmrc
ignore-scripts=trueこの設定により、npmはpreinstall、postinstallなどのライフサイクルスクリプトを実行しなくなり、悪意のあるコードが実行されるリスクを抑えられます。
Node.jsランタイムのバージョン互換性
安全で安定したプロジェクトを維持するには、特定のNode.jsランタイムバージョンとの互換性を確保することも重要です。古いバージョンやサポート対象外のNode.jsバージョンに依存するプロジェクトでは、特に役立ちます。.npmrcファイルでnode-versionを設定すると、指定したNode.jsバージョンと互換性のある依存関係だけをnpmがアップグレードするよう指示できます。
# .npmrc
node-version=14.0.0この設定により、npmはenginesマニフェストファイルの設定で指定されたNode.jsバージョン範囲に適合する依存関係のみを対象とします。
次のステップ
Power-user npmのパワーユーザー向けコマンドは、依存関係の管理だけでなく、開発ワークフローのセキュリティと効率の向上にも役立ちます。
Node.js関連の記事もぜひご覧ください。
JavaScriptプロジェクトを守るnpmセキュリティのベストプラクティス10選。
DockerでNode.jsウェブアプリケーションをコンテナ化するベストプラクティス10選
Brian Clarkによるセキュリティを考慮した最新npmパッケージ作成のベストプラクティス。