はじめに
この記事では、JavaScript/TypeScript 開発で利用する「ランタイム」「パッケージマネージャー」「バンドラー」「テストランナー」という4つのツールカテゴリについて、それぞれの役割と代表的なツールを具体例を交えて解説します。
JavaScript 開発における4つの主要ツール
JavaScript 開発では、以下の4つのカテゴリのツールが中核を担います。
- ランタイム(Runtime):JavaScriptコードを実行する環境
- パッケージマネージャー(Package Manager):ライブラリの管理とインストールを行うツール
- バンドラー(Bundler):複数のファイルを1つにまとめて最適化するツール
- テストランナー(Test Runner):テストコードを実行し結果を報告するツール
これらのツールを組み合わせることで、効率的な開発環境を構築できます。
ランタイム(Runtime)
ランタイムは、JavaScript コードを実際に実行する環境です。ブラウザ以外で JavaScript を動かすために必要なエンジンと、ファイル操作やネットワーク通信などの機能を提供します。
代表的なランタイム
Node.js
最も広く使われているJavaScriptランタイムです。
// Node.jsでファイルを読み込む例
const fs = require('fs');
// ファイルの読み込み
const data = fs.readFileSync('example.txt', 'utf8');
console.log(data);
// HTTPサーバーの起動
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World!');
});
server.listen(3000);
Node.jsの特徴は以下の通りです。
- 豊富なエコシステムとnpmパッケージの互換性
- 長い歴史による安定性と成熟したコミュニティ
- CommonJS(
require)とES Modules(import)の両方をサポート
Deno
Node.js の作者が開発した、セキュリティを重視したランタイムです。
// Denoでファイルを読み込む例
const data = await Deno.readTextFile('example.txt');
console.log(data);
// HTTPサーバーの起動
Deno.serve({ port: 3000 }, () => {
return new Response('Hello World!');
});
Deno の特徴は以下の通りです。
- デフォルトでセキュアな実行(ファイルアクセス、ネットワークアクセスに明示的な許可が必要)
- TypeScript をネイティブサポート
- Web標準APIに準拠
- npmパッケージと Deno モジュールの両方に対応
Bun(ランタイムとして)
2022年に登場した新しいランタイムで、JavaScriptCore エンジンを使用しています。
// Bunでファイルを読み込む例
const file = Bun.file('example.txt');
const data = await file.text();
console.log(data);
// HTTPサーバーの起動
Bun.serve({
port: 3000,
fetch(req) {
return new Response('Hello World!');
},
});
Bun の特徴は以下の通りです。
- Node.js と比較して高速な起動時間と実行速度
- TypeScript と JSX をネイティブサポート(トランスパイル不要)
- パッケージマネージャー、バンドラー、テストランナーを内蔵
- Web標準API(
fetch、Responseなど)を優先的に採用
ランタイムの選び方
// プロジェクトの要件に応じた選択例
// 既存のNode.jsエコシステムを活用したい場合
// → Node.js
const express = require('express');
const app = express();
// セキュリティを重視し、モダンな開発環境が欲しい場合
// → Deno
import { serve } from 'https://deno.land/std/http/server.ts';
// 高速な開発体験とオールインワンツールが欲しい場合
// → Bun
import { serve } from 'bun';
2026年1月時点の npm trends は以下の通りです。
パッケージマネージャー(Package Manager)
パッケージマネージャーは、外部ライブラリのインストール、バージョン管理、依存関係の解決を行うツールです。
代表的なパッケージマネージャー
npm
Node.js に標準で付属するパッケージマネージャーです。
# パッケージのインストール
npm install express
# 開発用パッケージのインストール
npm install --save-dev typescript
# グローバルインストール
npm install -g nodemon
# package.jsonのスクリプト実行
npm run build
{
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"typescript": "^5.0.0"
},
"scripts": {
"dev": "nodemon index.js",
"build": "tsc"
}
}
npm の特徴は以下の通りです。
- Node.js と一緒にインストールされるため追加設定不要
- 最大のパッケージレジストリ(npm registry)にアクセス可能
-
package-lock.jsonで依存関係を厳密に管理
Yarn
Facebook が開発した、npm の代替パッケージマネージャーです。
# パッケージのインストール
yarn add express
# 開発用パッケージのインストール
yarn add --dev typescript
# package.jsonのスクリプト実行
yarn build
# 全パッケージのインストール
yarn install
Yarn の特徴は以下の通りです。
- npm よりも高速なインストール(並列ダウンロード)
-
yarn.lockによる決定論的な依存関係解決 - Yarn v2以降ではPlug'n'Play(PnP)による node_modules 管理
pnpm
効率的なディスク使用を実現するパッケージマネージャーです。
# パッケージのインストール
pnpm add express
# 開発用パッケージのインストール
pnpm add -D typescript
# package.jsonのスクリプト実行
pnpm run build
pnpm の特徴は以下の通りです。
- ハードリンクを使用してディスク容量を大幅に節約
- 厳密な依存関係管理(幽霊依存を防ぐ)
- npm や Yarn よりも高速なインストール
- モノレポに最適化された機能
Bun(パッケージマネージャーとして)
Bunはランタイムだけでなく、パッケージマネージャーとしても機能します。
# パッケージのインストール
bun add express
# 開発用パッケージのインストール
bun add -d typescript
# package.jsonのスクリプト実行
bun run build
# スクリプトの直接実行
bun index.ts
Bunのパッケージマネージャーの特徴は以下の通りです。
- 既存のパッケージマネージャーより圧倒的に高速
-
package.jsonとnode_modulesをそのまま使用(npm 互換) -
bun.lockb(バイナリ形式)で依存関係を管理
パッケージマネージャーの選び方
# プロジェクトの特性に応じた選択例
# 標準的なNode.jsプロジェクト、チーム全員が使える
# → npm
npm install
# モノレポやディスク容量を節約したい
# → pnpm
pnpm install
# 最高速度のインストールが欲しい
# → Bun
bun install
2026年1月時点の npm trends は以下の通りです。
バンドラー(Bundler)
バンドラーは、複数の JavaScript ファイルやアセット(CSS、画像など)を1つまたは少数のファイルにまとめ、最適化するツールです。
代表的なバンドラー
webpack
最も歴史が長く、高度にカスタマイズ可能なバンドラーです。
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif)$/,
type: 'asset/resource',
},
],
},
};
import './styles.css';
import logo from './logo.png';
console.log('アプリケーション起動');
Webpackの特徴は以下の通りです。
- 豊富なプラグインエコシステム
- Code Splitting(コード分割)による最適化
- ローダーシステムで様々なファイル形式に対応
- 複雑な設定が可能だが、学習コストも高い
Vite
モダンなフロントエンド開発に最適化された次世代バンドラーです。
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
outDir: 'dist',
sourcemap: true,
},
});
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Viteの特徴は以下の通りです。
- 開発時はESモジュールをネイティブ活用し、超高速な起動と HMR(Hot Module Replacement)
- 本番ビルドには Rollup を使用し、最適化されたバンドルを生成
- シンプルな設定で即座に開発開始可能
- React、Vue、Svelte など主要フレームワークをサポート
esbuild
Go言語で書かれた超高速バンドラーです。
const esbuild = require('esbuild');
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
minify: true,
outfile: 'dist/bundle.js',
loader: {
'.png': 'file',
'.jpg': 'file',
},
}).catch(() => process.exit(1));
esbuildの特徴は以下の通りです。
- JavaScript バンドラーの中で最速クラスの処理速度
- TypeScript と JSX をネイティブサポート
- シンプルな API と最小限の設定
- Vite や Bun の内部で使用されている
Bun(バンドラーとして)
Bunもバンドラー機能を内蔵しています。
# バンドルの作成
bun build ./src/index.tsx --outdir ./dist --minify
# 複数エントリーポイント
bun build ./src/app.ts ./src/worker.ts --outdir ./dist
// Bunのビルド設定
await Bun.build({
entrypoints: ['./src/index.tsx'],
outdir: './dist',
minify: true,
sourcemap: 'external',
target: 'browser',
});
Bunのバンドラーの特徴は以下の通りです。
- esbuild と同等以上の高速性
- CSS、画像などのアセットも統合的に処理
- ツリーシェイキングとコード分割に対応
バンドラーの選び方
// プロジェクトの要件に応じた選択例
// 複雑な設定やレガシーなプラグインが必要
// → webpack
module.exports = { /* 詳細な設定 */ };
// モダンなフロントエンド開発、高速なHMRが欲しい
// → Vite
export default defineConfig({ /* シンプルな設定 */ });
// ライブラリのビルド、最高速度が必要
// → esbuild
esbuild.build({ /* 最小限の設定 */ });
// Bunエコシステムを使用している
// → Bun
await Bun.build({ /* 統合された設定 */ });
2026年1月時点の npm trends は以下の通りです。
テストランナー(Test Runner)
テストランナーは、テストコードを実行し、結果をレポートするツールです。アサーション、モック、カバレッジレポートなどの機能を提供します。
代表的なテストランナー
Jest
Facebookが開発した、最も人気のある JavaScript テストフレームワークです。
function sum(a, b) {
return a + b;
}
module.exports = sum;
const sum = require('./sum');
describe('sum関数のテスト', () => {
test('1 + 2 は 3 になる', () => {
expect(sum(1, 2)).toBe(3);
});
test('負の数も正しく計算される', () => {
expect(sum(-1, -2)).toBe(-3);
});
});
// モックの使用例
const fetchUser = require('./user');
jest.mock('./api');
const api = require('./api');
test('ユーザー情報を取得できる', async () => {
api.getUser.mockResolvedValue({ name: 'Alice', age: 30 });
const user = await fetchUser(1);
expect(user.name).toBe('Alice');
expect(api.getUser).toHaveBeenCalledWith(1);
});
Jestの特徴は以下の通りです。
- ゼロ設定で即座に使用可能
- スナップショットテスト機能
- 強力なモック機能
- コードカバレッジレポート自動生成
- 並列実行による高速なテスト
Vitest
Vite と統合された、モダンなテストフレームワークです。
export function sum(a: number, b: number): number {
return a + b;
}
import { describe, test, expect } from 'vitest';
import { sum } from './sum';
describe('sum関数のテスト', () => {
test('1 + 2 は 3 になる', () => {
expect(sum(1, 2)).toBe(3);
});
test('負の数も正しく計算される', () => {
expect(sum(-1, -2)).toBe(-3);
});
});
// コンポーネントテストの例(React)
import { render, screen } from '@testing-library/react';
import { describe, test, expect } from 'vitest';
import App from './App';
describe('Appコンポーネント', () => {
test('タイトルが表示される', () => {
render(<App />);
expect(screen.getByText('Hello World')).toBeInTheDocument();
});
});
Vitest の特徴は以下の通りです。
- Vite との完全な統合により設定が簡単
- Jest 互換の API で移行が容易
- esbuild による高速な実行
- HMR に対応したウォッチモード
- TypeScript と ES モジュールのネイティブサポート
Bun Test(Bunのテストランナー)
Bunに組み込まれたテストランナーです。
export function sum(a: number, b: number): number {
return a + b;
}
import { describe, test, expect } from 'bun:test';
import { sum } from './sum';
describe('sum関数のテスト', () => {
test('1 + 2 は 3 になる', () => {
expect(sum(1, 2)).toBe(3);
});
test('負の数も正しく計算される', () => {
expect(sum(-1, -2)).toBe(-3);
});
});
# テストの実行
bun test
# ウォッチモード
bun test --watch
Bun Testの特徴は以下の通りです。
- 既存のテストランナーより圧倒的に高速
- Jest互換のAPIをサポート
- TypeScriptをネイティブ実行(トランスパイル不要)
- モック機能とスナップショット機能を標準装備
Playwright Test
E2E(End-to-End)テストに特化したテストランナーです。
import { test, expect } from '@playwright/test';
test('基本的なナビゲーション', async ({ page }) => {
// ページに移動
await page.goto('https://example.com');
// タイトルを確認
await expect(page).toHaveTitle(/Example Domain/);
// リンクをクリック
await page.click('text=More information');
// URLが変わったことを確認
await expect(page).toHaveURL(/iana/);
});
// フォーム入力のテスト
test('ログインフォーム', async ({ page }) => {
await page.goto('https://example.com/login');
// フォームに入力
await page.fill('input[name="email"]', 'test@example.com');
await page.fill('input[name="password"]', 'password123');
// 送信ボタンをクリック
await page.click('button[type="submit"]');
// ダッシュボードに遷移したことを確認
await expect(page).toHaveURL(/dashboard/);
await expect(page.locator('h1')).toContainText('ダッシュボード');
});
Playwright Testの特徴は以下の通りです。
- Chrome、Firefox、Safari、Edge など複数ブラウザに対応
- 自動待機機能で安定したテスト
- スクリーンショットと動画記録
- 並列実行とシャーディングによる高速化
- デバッグモードとトレースビューア
テストランナーの選び方
// プロジェクトの要件に応じた選択例
// 一般的なユニットテスト、統合テスト
// → Jest(実績豊富)、Vitest(高速)、Bun Test(最速)
describe('ユニットテスト', () => {
test('関数の動作確認', () => {
expect(myFunction()).toBe(expected);
});
});
// E2Eテスト、ブラウザテスト
// → Playwright Test
test('E2Eテスト', async ({ page }) => {
await page.goto('/');
await expect(page.locator('h1')).toBeVisible();
});
2026年1月時点の npm trends は以下の通りです。
実践例:ツールの組み合わせ
実際のプロジェクトでは、これらのツールを組み合わせて使用します。
パターン1:従来型の Node.js プロジェクト
{
"name": "traditional-project",
"scripts": {
"dev": "webpack serve --mode development",
"build": "webpack --mode production",
"test": "jest"
},
"devDependencies": {
"webpack": "^5.0.0",
"webpack-cli": "^5.0.0",
"webpack-dev-server": "^4.0.0",
"jest": "^29.0.0"
}
}
この構成では、Node.js をランタイム、npm をパッケージマネージャー、Webpack をバンドラー、Jestをテストランナーとして使用します。
パターン2:モダンな Vite プロジェクト
{
"name": "modern-project",
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "vitest"
},
"devDependencies": {
"vite": "^5.0.0",
"vitest": "^1.0.0",
"@vitejs/plugin-react": "^4.0.0"
}
}
この構成では、Node.js をランタイム、pnpm をパッケージマネージャー、Vite をバンドラー、Vitestをテストランナーとして使用します。
パターン3:Bun オールインワン
{
"name": "bun-project",
"scripts": {
"dev": "bun run --watch src/index.ts",
"build": "bun build src/index.ts --outdir dist",
"test": "bun test"
}
}
この構成では、Bun がランタイム、パッケージマネージャー、バンドラー、テストランナーの全てを担当します。
パターン4:ハイブリッド構成
{
"name": "hybrid-project",
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "bun test",
"test:e2e": "playwright test"
},
"devDependencies": {
"vite": "^5.0.0",
"@playwright/test": "^1.40.0"
}
}
この構成では、必要に応じて最適なツールを組み合わせています。開発サーバーとバンドルにVite、ユニットテストに Bun、E2Eテストに Playwright を使用します。
まとめ
この記事では、JavaScript/TypeScript 開発における4つの主要ツールカテゴリについて解説しました。
- ランタイム:Node.js、Bun、Denoなど、JavaScriptを実行する環境
- パッケージマネージャー:npm、Yarn、pnpm、Bunなど、依存関係を管理するツール
- バンドラー:Webpack、Vite、esbuild、Bunなど、ファイルをまとめて最適化するツール
- テストランナー:Jest、Vitest、Bun Test、Playwrightなど、テストを実行するツール
プロジェクトの要件、チームの習熟度、パフォーマンス要求に応じて、これらのツールを適切に選択・組み合わせることで、効率的な開発環境を構築できます。





