はじめに:npm scriptsとは?🤔
現代のWeb開発、特にNode.jsエコシステムにおいては、npm
(Node Package Manager) は欠かせないツールです。多くの開発者がライブラリのインストールや管理に npm install
を利用していますが、npm
の真価はそれだけではありません。npm scripts
という強力な機能を使うことで、開発ワークフローにおける様々なタスクを自動化し、劇的に効率化できるのです!✨
npm scriptsは、プロジェクトの package.json
ファイル内に定義されるカスタムコマンドです。これを使うことで、以下のようなメリットがあります。
- タスクの標準化: ビルド、テスト、デプロイといった定型的なタスクを、
npm run build
やnpm test
のような簡単なコマンドで誰でも実行できるようになります。これにより、チーム内での手順のばらつきを防ぎ、新しいメンバーもすぐに開発に参加しやすくなります。 - 依存関係の隠蔽: プロジェクトで利用している特定のツール(例: Babel, webpack, ESLint, Prettier)の実行方法を、npm scripts内に閉じ込めることができます。利用者はツールの詳細な使い方を知らなくても、定義されたスクリプトを実行するだけで済みます。
- クロスプラットフォーム対応の促進: シェルスクリプトはOSによって挙動が異なることがありますが、npm scriptsと関連ツール(後述する
cross-env
など)を組み合わせることで、Windows, macOS, Linuxなど、異なる環境でも動作するスクリプトを作成しやすくなります。 - 複雑なタスクの簡略化: 複数のコマンドを組み合わせたり、特定の順序で実行したりする複雑なワークフローも、一つのnpm scriptとしてまとめることができます。
この記事では、npm scriptsの基本的な使い方から、より実践的で高度なテクニックまで、順を追って詳しく解説していきます。これを読めば、あなたもnpm scriptsを使いこなし、日々の開発をもっと快適で効率的なものにできるはずです!💪
基本的な使い方:package.jsonとnpm run
npm scriptsの心臓部となるのが、プロジェクトルートにある package.json
ファイルです。このJSONファイルには、プロジェクト名、バージョン、依存ライブラリなどの情報が含まれていますが、その中に "scripts"
というキーがあります。ここに、実行したいタスクの名前(キー)と、そのタスクで実行するコマンド(値)を定義します。
scriptsフィールドの構造
以下は、package.json
の scripts
フィールドの簡単な例です。
{
"name": "my-awesome-project",
"version": "1.0.0",
"description": "An awesome project using npm scripts",
"main": "index.js",
"scripts": {
"hello": "echo 'Hello, npm scripts!'",
"greet": "node greet.js"
},
"author": "",
"license": "ISC",
"dependencies": {}
}
この例では、"hello"
と "greet"
という2つのスクリプトが定義されています。
hello
スクリプトは、シェルコマンドecho 'Hello, npm scripts!'
を実行します。これは単にコンソールにメッセージを表示するだけの簡単な例です。greet
スクリプトは、Node.jsを使ってgreet.js
というファイルを実行します。
npm run でスクリプトを実行
これらのスクリプトを実行するには、ターミナル(コマンドプロンプトやPowerShellなど)で npm run <script-name>
というコマンドを使用します。
# hello スクリプトを実行
npm run hello
# greet スクリプトを実行
npm run greet
npm run hello
を実行すると、コンソールに Hello, npm scripts!
と表示されます。npm run greet
を実行すると、greet.js
ファイルの内容がNode.jsによって実行されます(事前に greet.js
ファイルを作成しておく必要があります)。
npm run
コマンドを引数なしで実行すると、利用可能なスクリプトの一覧が表示されます。これも覚えておくと便利です。
事前定義されたスクリプト名
npmには、いくつかの特別な意味を持つスクリプト名が事前定義されています。これらのスクリプト名は、npm run
を省略して実行できる場合があります。
-
start
: プロジェクトを開始するためのスクリプトです。通常、開発サーバーの起動などに使われます。npm start
で実行できます(run
は不要)。"scripts": { "start": "node server.js" }
npm start
-
test
: プロジェクトのテストを実行するためのスクリプトです。npm test
(またはnpm t
) で実行できます(run
は不要)。"scripts": { "test": "jest" }
npm test
-
stop
: プロジェクトを停止するためのスクリプトです。start
と対になることが多いですが、自動で呼び出されることは少なく、明示的にnpm run stop
で実行する必要があります。"scripts": { "start": "node server.js --port 3000", "stop": "kill $(lsof -t -i:3000)" // ポート3000で動いているプロセスを停止(環境依存あり) }
npm run stop
-
restart
: プロジェクトを再起動するためのスクリプトです。stop
,restart
,start
を順に実行する便利なショートカットですが、stop
とstart
スクリプトが定義されている必要があります。npm restart
で実行できます(run
は不要)。npm restart
これらの事前定義されたスクリプト名を使うことで、プロジェクトの基本的な操作が直感的になります。特に start
と test
は多くのプロジェクトで標準的に使われています。
カスタムスクリプトの作成:より複雑なタスクへ
npm scriptsの真価は、独自のカスタムスクリプトを作成して、開発ワークフローを自動化するところにあります。単純なコマンドだけでなく、複数のコマンドを組み合わせることも可能です。
複数のコマンドを連結する
シェルの機能を使って、複数のコマンドを一つのスクリプト内で実行できます。連結方法にはいくつかあり、挙動が異なります。
-
&&
(AND): 左側のコマンドが成功した場合にのみ、右側のコマンドを実行します。ビルドが成功したらテストを実行する、といった依存関係のあるタスクに適しています。
この例では、"scripts": { "build-and-test": "npm run build && npm run test" }
npm run build
が正常に終了(終了コード 0)した場合にのみ、npm run test
が実行されます。ビルドに失敗した場合はテストは実行されません。 -
;
(セミコロン): 左側のコマンドの成功・失敗にかかわらず、右側のコマンドを実行します。順番に実行したいが、互いに依存していないタスクに使えます。
この例では、"scripts": { "cleanup-and-log": "rm -rf ./dist ; echo 'Cleanup done.'" }
rm -rf ./dist
が失敗したとしても(例えばdist
ディレクトリが存在しなくても)、echo 'Cleanup done.'
は実行されます。 -
&
(バックグラウンド): 左側のコマンドをバックグラウンドで実行し、すぐに右側のコマンドを実行します(並列実行に近いですが、完全な制御は難しいです)。主にサーバー起動と他のタスクを同時に行う場合などに使われますが、挙動が不安定になることもあります。"scripts": { "dev": "node server.js & webpack --watch" // 環境によってはうまく動かないことも }
npm-run-all
などのツールを使うのがより堅牢です。
コマンドの並列実行と順次実行:npm-run-all
複数のnpm scriptsを順番に実行したり、並行して実行したりしたい場合、シェルの演算子だけでは限界があります。特にクロスプラットフォーム対応や、複雑な依存関係の管理には、専用のツールを使うのが便利です。その代表格が npm-run-all
です。
まず、npm-run-all
を開発依存としてインストールします。
npm install --save-dev npm-run-all
npm-run-all
を使うと、以下のようにスクリプトを定義できます。
{
"scripts": {
"lint": "eslint .",
"format": "prettier --write .",
"build:css": "sass styles/main.scss dist/style.css",
"build:js": "webpack",
"build": "npm-run-all build:*", // build:css と build:js を並列実行
"check": "npm-run-all lint format", // lint と format を並列実行
"ci": "npm-run-all check build test" // check, build, test を順次実行
}
}
npm-run-all <task1> <task2> ...
: 指定したタスクを並列で実行します。build:*
のようなワイルドカードも使えます。npm-run-all -s <task1> <task2> ...
(またはrun-s
): 指定したタスクを順次実行します。-s
は--sequential
の略です。npm-run-all -p <task1> <task2> ...
(またはrun-p
): 指定したタスクを並列で実行します。-p
は--parallel
の略です。デフォルトの動作と同じですが、明示的に並列を指定したい場合に便利です。
npm-run-all
を使うことで、複雑なタスクの組み合わせも、クロスプラットフォームを意識しながら簡潔に記述できます。
スクリプト内での環境変数利用:cross-env 🌿
npm scripts内で環境変数を使いたい場面はよくあります。例えば、開発モードと本番モードでAPIのエンドポイントを切り替えたり、特定の機能を有効/無効にしたりする場合です。
しかし、環境変数の設定方法はOSによって異なります。
- Linux / macOS (bash, zshなど):
NODE_ENV=production node server.js
- Windows (コマンドプロンプト):
set NODE_ENV=production && node server.js
- Windows (PowerShell):
$env:NODE_ENV="production"; node server.js
このようにOSごとに書き方を変えるのは非常に面倒ですし、package.json
が複雑になってしまいます。ここで役立つのが cross-env
です。
cross-env
は、環境変数を設定するコマンドをクロスプラットフォームで実行できるようにするユーティリティです。まず、開発依存としてインストールします。
npm install --save-dev cross-env
そして、scripts
の中で、環境変数を設定したいコマンドの前に cross-env
を付けます。
{
"scripts": {
"build": "cross-env NODE_ENV=production webpack --mode production",
"dev": "cross-env NODE_ENV=development webpack serve --mode development",
"start:prod": "cross-env NODE_ENV=production PORT=8080 node server.js"
}
}
cross-env
が、実行環境(OS)を判別し、適切な方法で環境変数を設定してから、その後のコマンドを実行してくれます。これにより、package.json
の scripts
はシンプルで、どの環境でも同じように動作します。これはチーム開発において非常に重要です。💯
スクリプトへの引数の渡し方 ➡️
npm scriptsを実行する際に、追加の引数を渡したい場合があります。例えば、テストスクリプトで特定のファイルだけをテストしたい、ビルドスクリプトで特定のオプションを有効にしたい、といったケースです。
npm scriptsに引数を渡すには、npm run <script-name> -- <arguments>
のように、スクリプト名の後に --
を付け、その後に渡したい引数を記述します。--
以降の部分が、スクリプト内で実行されるコマンドにそのまま渡されます。
例を見てみましょう。
{
"scripts": {
"test": "jest",
"serve": "http-server ./public -p 8080",
"greet": "node greet.js"
}
}
- 特定のテストファイルだけを実行したい場合:
これは、内部的にnpm run test -- --watch src/utils.test.js
jest --watch src/utils.test.js
を実行します。--watch
やsrc/utils.test.js
がjest
コマンドに渡されます。 serve
スクリプトでポート番号を変更したい場合:
これは、内部的にnpm run serve -- -p 9000
http-server ./public -p 8080 -p 9000
を実行します(http-server
が最後の-p
を優先する場合)。もしデフォルトのポート指定を上書きしたいなら、スクリプト側での対応が必要かもしれません。より柔軟なのは、スクリプト自体が引数を解釈するように作ることです。// greet.js const name = process.argv[2] || 'World'; // コマンドライン引数の3番目(node greet.js name の 'name')を取得 console.log(`Hello, ${name}!`);
これは、内部的にnpm run greet -- Alice
node greet.js Alice
を実行し、コンソールにHello, Alice!
と表示されます。
npm start
や npm test
のような run
を省略できるコマンドの場合でも、引数を渡すときは npm test -- --watch
のように --
を使う必要があります。
スクリプトのフック:preとpost 🎣
npm scriptsには「フック」と呼ばれる仕組みがあります。これは、特定のスクリプトが実行される前 (pre) または後 (post) に、自動的に別のスクリプトを実行する機能です。
フックスクリプトを定義するには、元のスクリプト名の前に pre
または post
を付けます。例えば、build
スクリプトに対するフックは prebuild
と postbuild
になります。
{
"scripts": {
"prebuild": "npm run clean", // build の前に実行
"build": "webpack",
"postbuild": "npm run deploy", // build の後に実行 (成功時のみ)
"pretest": "npm run lint", // test の前に実行
"test": "jest",
"posttest": "echo 'Tests finished!'", // test の後に実行 (成功時のみ)
"clean": "rm -rf ./dist",
"lint": "eslint .",
"deploy": "echo 'Deploying build artifacts...'" // 仮のデプロイコマンド
}
}
この設定で npm run build
を実行すると、以下の順序でスクリプトが実行されます。
prebuild
(つまりnpm run clean
) が実行される。prebuild
が成功したら、build
(つまりwebpack
) が実行される。build
が成功したら、postbuild
(つまりnpm run deploy
) が実行される。
同様に、npm test
を実行すると、pretest
-> test
-> posttest
の順で実行されます。
フックは、以下のようなシナリオで非常に役立ちます。
- テスト実行前にコードのリンティングを行う (
pretest
)。 - ビルド前に出力ディレクトリをクリーンアップする (
prebuild
)。 - バージョンを上げる前にテストを実行する (
preversion
– これはnpm version
コマンドに対するフックです)。 - npmパッケージを公開する前にビルドとテストを行う (
prepublishOnly
– これはnpm publish
に対するフックです)。
フックをうまく使うことで、スクリプト間の依存関係を暗黙的に定義し、ワークフローをより堅牢にすることができます。
npmパッケージの実行可能ファイルを利用する 🛠️
プロジェクトにローカルインストールしたnpmパッケージには、コマンドラインツール(実行可能ファイル)が含まれていることがよくあります。例えば、webpack
, eslint
, prettier
, jest
, typescript
などです。
これらのツールをnpm scripts内から実行する場合、通常はグローバルにインストールする必要はありません。npm run
でスクリプトを実行すると、npmは自動的に ./node_modules/.bin
ディレクトリを環境変数 PATH
の先頭に追加します。この ./node_modules/.bin
には、ローカルインストールされたパッケージの実行可能ファイルへのシンボリックリンク(またはWindowsの場合は .cmd
ファイルなど)が配置されています。
これにより、npm scriptsの中では、ローカルインストールされたコマンド名を直接記述するだけで実行できます。
{
"scripts": {
"lint": "eslint src/**/*.js", // ローカルのeslintが実行される
"build": "webpack", // ローカルのwebpackが実行される
"test": "jest" // ローカルのjestが実行される
},
"devDependencies": {
"eslint": "^8.0.0",
"webpack": "^5.0.0",
"jest": "^29.0.0"
}
}
npm run lint
を実行すると、グローバルに eslint
がインストールされていなくても、プロジェクトの node_modules
内にある eslint
が使われます。これにより、プロジェクトごとにツールのバージョンを固定でき、開発者間の環境差異による問題を避けることができます。これはnpm scriptsの非常に大きな利点の一つです。🌟
npx との関係
npx
は、npm 5.2.0から同梱されるようになったコマンドラインツールで、ローカルまたはリモートのnpmパッケージのコマンドを実行するのに便利です。
- ローカルパッケージの実行:
npx <command>
は、まずnode_modules/.bin
内に<command>
が存在するか探し、あればそれを実行します。これはnpm scripts内での挙動と似ています。 - 一時的な実行: ローカルに
<command>
が見つからない場合、npx
はそのパッケージを一時的にダウンロードして実行し、実行後に削除します。これにより、一度しか使わないようなツールをグローバルやローカルにインストールせずに試すことができます。例えば、npx create-react-app my-app
のようにプロジェクトの雛形作成ツールを実行する際によく使われます。
npm scriptsの中では、node_modules/.bin
が自動的にPATHに追加されるため、通常は npx
を使う必要はありません。コマンド名を直接書けばOKです。
// npm scripts 内では、以下はどちらもほぼ同じ意味(ローカルのeslintを使う)
"scripts": {
"lint": "eslint .",
"lint-npx": "npx eslint ." // npx を使うこともできるが、冗長な場合が多い
}
ただし、スクリプト内で特定のバージョンのNode.jsを使いたい場合など、npx
が便利なケースもあります(例: npx -p node@18 node myscript.js
)。
より複雑なスクリプト:シェルスクリプト vs Node.jsスクリプト
npm scriptsが長くなったり、複雑なロジック(条件分岐、ループなど)が必要になったりすると、package.json
の scripts
フィールドだけで管理するのは難しくなってきます。可読性も保守性も低下しがちです。
このような場合、2つの主なアプローチがあります。
1. シェルスクリプトファイルを利用する
複雑な処理を別のシェルスクリプトファイル(例: scripts/build.sh
)に記述し、npm scriptからはそのファイルを実行するようにします。
// package.json
{
"scripts": {
"build": "bash ./scripts/build.sh"
}
}
#!/bin/bash
# ./scripts/build.sh
set -e # エラーが発生したらスクリプトを終了する
echo "Starting build process..."
# クリーンアップ
echo "Cleaning up dist directory..."
rm -rf ./dist
mkdir ./dist
# CSSのビルド
echo "Building CSS..."
sass styles/main.scss dist/style.css --style compressed
# JavaScriptのビルド (環境変数を使用)
echo "Building JavaScript for $NODE_ENV..."
cross-env BABEL_ENV=$NODE_ENV webpack --mode $NODE_ENV
echo "Build completed successfully!"
メリット:
- シェルスクリプトに慣れている場合、書きやすい。
- 簡単な処理なら手早く書ける。
デメリット:
- Windows環境での互換性に問題が出やすい(bashが必要、コマンドの違いなど)。WSL (Windows Subsystem for Linux) を使えば緩和できますが、開発者全員にそれを要求するのは難しい場合もあります。
- 複雑なロジック、エラーハンドリング、JSON操作などは苦手。
2. Node.jsスクリプトファイルを利用する
複雑な処理をNode.jsスクリプトファイル(例: scripts/build.js
)に記述し、npm scriptからはそれを node
コマンドで実行します。
// package.json
{
"scripts": {
"build": "node ./scripts/build.js"
// cross-env を使って環境変数を渡すことも可能
// "build:prod": "cross-env NODE_ENV=production node ./scripts/build.js"
}
}
// ./scripts/build.js
const fs = require('fs-extra'); // fs-extra は標準のfsより高機能
const path = require('path');
const { execSync } = require('child_process'); // 同期的に子プロセスを実行
const env = process.env.NODE_ENV || 'development';
const distDir = path.resolve(__dirname, '../dist');
console.log(`Starting build process for ${env}...`);
try {
// クリーンアップ
console.log('Cleaning up dist directory...');
fs.emptyDirSync(distDir); // ディレクトリがなければ作成、あれば中身を空にする
// CSSのビルド (ここでは例としてシェルコマンドを実行)
console.log('Building CSS...');
const sassCommand = `sass ${path.resolve(__dirname, '../styles/main.scss')} ${path.join(distDir, 'style.css')} --style compressed`;
execSync(sassCommand, { stdio: 'inherit' }); // stdio:'inherit' で子プロセスの出力を表示
// JavaScriptのビルド (webpackのNode APIを使うことも可能だが、ここではコマンド実行例)
console.log(`Building JavaScript for ${env}...`);
const webpackCommand = `webpack --mode ${env}`;
// 環境変数を渡す場合は execSync のオプションで設定可能
// execSync(webpackCommand, { stdio: 'inherit', env: { ...process.env, BABEL_ENV: env } });
execSync(webpackCommand, { stdio: 'inherit' });
console.log('Build completed successfully!');
} catch (error) {
console.error('Build failed:', error);
process.exit(1); // エラーで終了
}
メリット:
- Node.js (JavaScript) で記述できるため、フロントエンド/バックエンド開発者にとって親しみやすい。
- ファイルシステム操作、非同期処理、JSON操作、エラーハンドリングなどが得意。
npm install
で追加したライブラリ(例:fs-extra
,chalk
)をスクリプト内で利用できる。- Node.js自体がクロスプラットフォームなので、OS間の互換性問題が起きにくい(シェルコマンド呼び出し部分を除く)。
デメリット:
- 簡単な処理でもファイルを作成する必要がある。
- シェルコマンドの実行には
child_process
モジュールなどを使う必要があり、少し冗長になることがある。
一般的に、スクリプトが数行を超える場合や、クロスプラットフォーム対応が重要な場合は、Node.jsスクリプトを利用する方が堅牢で保守しやすい傾向にあります。👍
実践的な例:よくあるタスクの自動化 🎯
これまでに学んだことを活かして、実際の開発でよく使われるnpm scriptsの例を見てみましょう。
{
"name": "practical-npm-scripts-example",
"version": "1.0.0",
"scripts": {
// --- 開発 ---
"dev": "npm-run-all --parallel dev:*", // 開発サーバーとwatchを並行起動
"dev:server": "cross-env NODE_ENV=development nodemon server.js", // nodemonでサーバー自動再起動
"dev:build": "webpack --watch --mode development", // webpackでファイルの変更を監視して自動ビルド
// --- ビルド ---
"build": "npm-run-all clean build:*", // クリーンアップ後、各ビルドを並列実行
"build:css": "sass src/styles:dist/css --style compressed",
"build:js": "cross-env NODE_ENV=production webpack --mode production",
"build:assets": "cpx 'src/assets/**/*' dist/assets", // ファイル/ディレクトリコピー
// --- コード品質 ---
"lint": "eslint 'src/**/*.js'",
"lint:fix": "eslint 'src/**/*.js' --fix",
"format": "prettier --write 'src/**/*.{js,jsx,ts,tsx,json,css,scss,md}'",
"check-types": "tsc --noEmit", // TypeScriptの型チェック
"validate": "npm-run-all -p check-types lint format", // 型チェック、Lint、Formatを並行実行
// --- テスト ---
"test": "cross-env NODE_ENV=test jest",
"test:watch": "npm run test -- --watch",
"test:coverage": "npm run test -- --coverage",
"pretest": "npm run validate", // テスト前にコード品質チェックを実行
// --- クリーンアップ ---
"clean": "rimraf dist coverage", // rimrafはクロスプラットフォームな rm -rf
// --- CI/デプロイ関連 ---
"ci": "npm-run-all validate build test", // CIパイプラインで実行する一連のタスク
"deploy": "node scripts/deploy.js", // デプロイ用のNode.jsスクリプトを実行
"predeploy": "npm run ci", // デプロイ前にCIタスクを実行
// --- その他 ---
"start": "cross-env NODE_ENV=production node server.js", // 本番サーバー起動
"prepare": "husky install" // husky (Gitフック管理) の設定用 (npm install後に自動実行される)
},
"devDependencies": {
"@babel/core": "...",
"cross-env": "...",
"cpx": "...", // ファイルコピー用ユーティリティ
"eslint": "...",
"husky": "...", // Gitフック管理
"jest": "...",
"nodemon": "...", // ファイル変更監視・自動再起動
"npm-run-all": "...",
"prettier": "...",
"rimraf": "...", // クロスプラットフォーム rm -rf
"sass": "...",
"typescript": "...",
"webpack": "...",
"webpack-cli": "..."
// ... その他必要な開発依存パッケージ
},
"dependencies": {
// ... アプリケーションの依存パッケージ
}
}
この例では、以下のような多くの一般的なタスクがnpm scriptsで定義されています。
- 開発サーバーの起動とファイル変更の監視 (
dev
) - 本番用のビルド (
build
) - コードの静的解析とフォーマット (
lint
,format
,validate
) - ユニットテストの実行 (
test
) - 生成されたファイルのクリーンアップ (
clean
) - CI/CDパイプラインで実行される一連のタスク (
ci
) - デプロイスクリプトの実行 (
deploy
)
このように、関連するタスクをグループ化し (例: build:*
)、npm-run-all
やフック (pretest
, predeploy
) を活用することで、非常に整理され、再利用性の高いスクリプト集を構築できます。
ベストプラクティスと注意点 📝
npm scriptsを効果的に使うために、いくつか意識しておきたい点があります。
-
推奨 命名規則:
- タスクの内容がわかる、一貫性のある名前を付けましょう(例:
build:js
,build:css
)。 - コロン (
:
) を使って、関連するタスクをグルーピングすると見通しが良くなります。 pre
,post
フックを活用し、暗黙的な依存関係を定義します。
- タスクの内容がわかる、一貫性のある名前を付けましょう(例:
-
推奨 クロスプラットフォーム対応:
- 環境変数の設定には
cross-env
を使いましょう。 - ファイルパスの操作にはNode.jsの
path
モジュールを使うか、cpx
やcopyfiles
のようなクロスプラットフォームなツールを使いましょう。 - ファイルの削除には
rimraf
やdel-cli
を使いましょう (rm -rf
の代わりに)。 - 複雑な処理やOS依存のコマンドが多い場合は、Node.jsスクリプトの利用を検討しましょう。
- 環境変数の設定には
-
推奨 可読性と保守性:
- スクリプトが長くなりすぎる場合は、シェルスクリプトやNode.jsスクリプトファイルに分割しましょう。
npm-run-all
を使って、複数のスクリプトの実行フローを明確にしましょう。- コメントを活用しましょう (ただし、JSONなのでコメントは書けません。スクリプトファイル内に書くか、
package.json
の他のフィールドにメモとして残すなどの工夫が必要です)。
-
推奨 ローカル依存を活用:
- 必要なCLIツールは
devDependencies
としてローカルにインストールし、グローバルインストールに依存しないようにしましょう。これにより、プロジェクトの再現性が高まります。
- 必要なCLIツールは
-
注意 シェルの違い:
- npm scriptsはデフォルトでシステムのデフォルトシェル (Linux/macOSでは
sh
、Windowsではcmd.exe
) を使って実行されます。シェルの種類によって使えるコマンドや構文が異なることに注意が必要です。bash
を前提としたスクリプトはWindowsでは動かない可能性があります。 script-shell
設定でnpmが使うシェルを変更することもできますが、開発者全員の環境でそれを統一するのは難しい場合があります。
- npm scriptsはデフォルトでシステムのデフォルトシェル (Linux/macOSでは
-
注意 セキュリティ:
- インターネットから取得した信頼できないプロジェクトで、安易に
npm install
やnpm run
を実行しないでください。install
スクリプトやpreinstall
/postinstall
スクリプトに悪意のあるコードが含まれている可能性があります。npm ci
はinstall
スクリプトを実行しないため、より安全な場合があります。
- インターネットから取得した信頼できないプロジェクトで、安易に
まとめ 🎉
npm scripts
は、Node.js開発におけるタスク自動化のための強力で身近なツールです。基本的な使い方から、cross-env
, npm-run-all
, フック、Node.jsスクリプトの活用といった応用的なテクニックまで見てきました。
これらを活用することで、
- 煩雑なコマンド入力を削減し、タイプミスを防ぐ。
- 開発、ビルド、テスト、デプロイなどのワークフローを標準化・自動化する。
- チームメンバー間の環境差異を吸収し、共同作業をスムーズにする。
- プロジェクトの依存関係を明確にし、管理しやすくする。
といった多くのメリットが得られます。
もし、まだ npm install
くらいしか npm
を使っていなかったなら、ぜひ今日から package.json
の scripts
フィールドを活用してみてください。最初は簡単なスクリプトからで構いません。少しずつ自動化を進めていくことで、開発体験は着実に向上していくはずです。Happy Scripting! 💻
コメント