コンテンツにスキップ

Express/裏技集

出典: フリー教科書『ウィキブックス(Wikibooks)』

Express.js をさらに便利に使いこなすためのテクニックをまとめました。コードの簡潔化やパフォーマンス向上、エラーハンドリングの強化など、すぐに活用できるヒントが満載です。

1. 動的なルートの生成

[編集]

ルートを動的に生成することで、コードの保守性を向上させます。

const routes = [
  { path: '/', handler: (req, res) => res.send('Home Page') },
  { path: '/about', handler: (req, res) => res.send('About Page') },
  { path: '/contact', handler: (req, res) => res.send('Contact Page') },
];

routes.forEach(({ path, handler }) => {
  app.get(path, handler);
});

2. 非同期関数をミドルウェアで使う

[編集]

非同期関数を使う際、例外をキャッチするヘルパーを作成するとエラーハンドリングが簡単です。

const asyncHandler = (fn) => (req, res, next) =>
  Promise.resolve(fn(req, res, next)).catch(next);

app.get(
  '/data',
  asyncHandler(async (req, res) => {
    const data = await fetchData(); // 非同期処理
    res.json(data);
  })
);

3. ミドルウェアを条件付きで使用する

[編集]

特定の条件下でのみミドルウェアを適用する例です。

const isProduction = process.env.NODE_ENV === 'production';

if (isProduction) {
  app.use(require('helmet')()); // 本番環境でのみ適用
}

または、ルートごとに条件付きミドルウェアを設定します。

app.use('/secure-route', (req, res, next) => {
  if (!req.headers['x-custom-header']) {
    return res.status(403).send('Forbidden');
  }
  next();
});

4. 複数のパスで同じ処理を共有

[編集]

同じロジックを複数のパスで共有する場合、配列で指定できます。

app.get(['/path1', '/path2', '/path3'], (req, res) => {
  res.send('This handler works for multiple routes!');
});

5. サブアプリケーションを活用

[編集]

サブアプリケーションを使用してコードをモジュール化します。

const admin = express();
admin.get('/dashboard', (req, res) => res.send('Admin Dashboard'));

const app = express();
app.use('/admin', admin); // サブアプリケーションをマウント

6. カスタムのレスポンスメソッド

[編集]

レスポンスオブジェクトを拡張し、便利なカスタムメソッドを追加します。

app.use((req, res, next) => {
  res.success = (data) => res.json({ success: true, data });
  next();
});

app.get('/test', (req, res) => {
  res.success({ message: 'It works!' });
});

7. エラーハンドラーの強化

[編集]

Express のエラーハンドラーをカスタマイズして、エラー内容を一元管理します。

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Something went wrong!' });
});

環境ごとにエラーハンドリングを変更する例も追加します。

app.use((err, req, res, next) => {
  if (process.env.NODE_ENV === 'development') {
    res.status(500).send(err.stack);
  } else {
    res.status(500).send('Internal Server Error');
  }
});

8. 静的ファイルのキャッシュ制御

[編集]

静的ファイルを効率的に配信するためのキャッシュ設定です。

app.use(
  express.static('public', {
    maxAge: '1d', // 1日間キャッシュ
    etag: false,  // ETag を無効化
  })
);

9. 複数のミドルウェアをチェーンで設定

[編集]

複数のミドルウェアをまとめて指定することでコードが簡潔になります。

app.use('/api', [
  (req, res, next) => {
    console.log('Middleware 1');
    next();
  },
  (req, res, next) => {
    console.log('Middleware 2');
    next();
  },
]);

10. メモリリークを防ぐためのイベントリスナー解除

[編集]

サーバー終了時にリソースを適切に解放します。

const server = app.listen(3000, () => console.log('Server running on port 3000'));

// 終了時にイベントリスナーを解除
process.on('SIGINT', () => {
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });
});

これらのテクニックを活用することで、Express.js の開発がより効率的で快適になります。ぜひ必要に応じて取り入れてください!