Node.jsアプリのCI/CDをCircleCI と CircleCI Orbsで簡単に構築する
モダンなフロントエンド開発において、コードの品質を保ちながら効率的にデリバリーするには CI/CD パイプラインが欠かせません。本記事では、Vite と TypeScript で作成したプロジェクトへのCircleCI プロジェクトの基本的なセットアップから、Node.js Orb を使った効率的な CI 設定、そして Vite プロジェクトのビルドパイプライン構築までを順を追って見ていきます。
前提条件
基本的なアカウントセットアップなどについては省略します。以下の環境またはアカウントについては、各自で事前にセットアップしてください。
- Node.js 環境がセットアップ済み
- GitHub アカウント
- CircleCI アカウント(GitHub と連携済み)
プロジェクトの準備
まずは、Vite で新しいプロジェクトを作成しましょう。
npm create vite
プロンプトに従って設定を進めます:
- Project name:
first-cci-app - Framework:
Vanilla - Variant:
TypeScript - Use rolldown-vite:
No - Install and start:
Yes
これで以下のような構成のプロジェクトが作成されます:
.
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── counter.ts
│ ├── main.ts
│ ├── style.css
│ └── typescript.svg
└── tsconfig.json
GitHub リポジトリへの push
プロジェクトを Git で管理し、GitHub に push します:
git init
git remote add origin git@github.com:your-username/practice-vite-app.git
git add .
git commit -m 'init'
git push origin main
これで準備完了です。
CircleCI プロジェクトのセットアップ
CircleCI のダッシュボードにアクセスし、新しいプロジェクトをセットアップしていきましょう。CircleCIのTOPページで「Set up a project」をクリックしましょう。

CircleCIに接続しているGitHubアカウントにあるリポジトリの一覧が表示されます。もしここで作成したリポジトリが表示されない場合は、GitHubとの連携設定をチェックしてください。CIパイプラインを作りたいプロジェクトを特定したら、「Set up」ボタンをクリックします。

セットアップオプションの選択
CircleCI におけるパイプラインのセットアップは、3つのオプションから開始できます。

- Fastest: リポジトリに既存の
.circleci/config.ymlを使用 - Faster: スターター CI パイプラインを新しいブランチにコミット(推奨)
- Fast: config.yml テンプレートを編集してから開始
今回は「Faster」を選択します。これにより、CircleCI が自動的に .circleci/config.yml を含むブランチを作成してくれます。
デフォルト設定の確認
CircleCI が生成するデフォルトの config.yml は以下のような内容になっています。リポジトリをチェックアウトして、”Hello, World”と出力するだけのとてもシンプルな内容ですね。
version: 2.1
jobs:
say-hello:
docker:
- image: cimg/base:current
steps:
- checkout
- run:
name: "Say hello"
command: "echo Hello, World!"
workflows:
say-hello-workflow:
jobs:
- say-hello
とてもシンプルな内容ですが、CircleCIにおけるパイプラインの基本構造がおさえられています。。jobs では実行する処理の単位を定義し、docker で実行環境となるコンテナイメージを指定します。steps にはジョブ内で実行する処理を記述し、workflows でジョブの実行順序や条件を定義するといった具合です。

このデフォルト設定を push すると、すぐにパイプラインが実行され、”Hello, World!” が出力されます。
Node.js Orb を使って、Viteプロジェクトのビルドを実施する
これで1回目の CI パイプラインは実行できました。しかし現状では Vite アプリに向けたジョブはまだ何も設定されていません。そこでここからは Node.js プロジェクト用にパイプラインをカスタマイズしていきます。
Orbを利用して、Node.jsアプリのセットアップをショートカット
本来 CI ジョブ上で Node.js アプリをセットアップする際、以下のようなステップを定義する必要があります。
- 過去のジョブから利用できるキャッシュがないか調べる
- キャッシュがあれば利用する。なければnpm ci を実行
- インストール結果を元に、キャッシュを更新
また、プロジェクトによってはnpmではなくpnpmやyarnなどを利用しているケースもあり、パイプラインの設定はプロジェクトに応じて変更する必要があります。途中で利用するパッケージマネージャーを変えた場合も同様ですね。
CircleCIの場合、Orbという仕組みを利用してこれらの手間を省くことができます。
Orb とは
Orb は、CircleCI が提供する再利用可能な設定パッケージです。言語やツールに特化した設定をカプセル化しており、複雑な設定を簡潔に記述できます。Node.jsなど、主要な言語については、CircleCI が公式で Orbを提供しています。公式のNode.js ガイドを参考に、circleci/node Orb を導入しましょう。
config.yml の更新
config.yml を以下のように更新します。orbsというブロックが追加されていますが、ここではパイプライン上で利用する Orb の定義を実施しています。今回はcircleci/nodeのバージョン5.0.2を利用することが宣言されています。
version: 2.1
orbs:
node: circleci/node@5.0.2
jobs:
build_app:
executor: node/default
steps:
- checkout
- node/install-packages:
pkg-manager: npm
- run:
command: npm run build
name: Build app
- persist_to_workspace:
root: ~/project
paths:
- .
workflows:
build_app_workflow:
jobs:
- build_app
ジョブについても変化があります。1つ目の変化が、Executor の指定です。
executor: node/default
これにより、Orb が提供するデフォルトの Node.js 実行環境を使用するようになります。よってこのジョブで利用する Docker イメージの設定やバージョン管理などの手間を省くことができます。
続いて、パッケージのインストールを見てみましょう。
- node/install-packages:
pkg-manager: npm
この1ステップで、以下の処理がすべて自動化されます。まず package.json の確認、lockfile の判定(package-lock.json の検出)、キャッシュの復元と続きます。その後 npm install を実行し、キャッシュを保存、最後に一時リンクを削除するという流れが、この2行で実現しています。
実際のパイプライン実行画面を見ると、node/install-packages が以下のステップに展開されていることがわかります:

- Checking for package.json
- Determine lockfile
- Restoring cache
- Installing NPM packages
- Saving cache
- Remove temporary links
キャッシュを活用し、利用しているパッケージマネージャーに応じたコマンドを利用する設定を行うことは、CI / CD のジョブ実行時間を短縮し、アプリケーションの QA やデプロイの時間を短縮することにつながります。 CircleCI の Orb を活用することで、このようなチューニングについても CircleCI 側が提供するベストプラクティスを簡単に導入できます。
インストール周りを設定したら、あとはビルドの実行を定義しましょう。ビルドコマンドをジョブのステップに追加してあげましょう。
- run:
command: npm run build
name: Build app
最後にビルド結果をワークスペースに保存するステップを追加します。
- persist_to_workspace:
root: ~/project
paths:
- .
ビルド成果物をワークスペースに保存しておくことで、後続のジョブ(デプロイなど)で利用できるようになります。
これでシンプルな Vite アプリをビルドするパイプラインが出来上がりました。
パイプラインの実行
設定を push すると、パイプラインが自動的に実行されます。CircleCI のダッシュボードで各ステップの進行状況を確認できます。

すべてのステップが成功すると、以下のような流れで処理が完了します。
- Checkout code (0s)
- Checking for package.json (0s)
- Determine lockfile (0s)
- Restoring cache (0s) – 初回は空
- Installing NPM packages (数秒)
- Saving cache (0s)
- Remove temporary links (0s)
- Build app (数秒)
2回目以降の実行では、キャッシュが効くため、パッケージインストールのステップについてはより短い時間で完了するようになります。今回はnpm create viteでセットアップしたばかりのアプリなので元々短時間でしたが、 React アプリや E2E テストでの Playwright インストールなどが追加されると、このキャッシュステップが次第に大きな効果を生み出すようになります。
まとめ
CircleCI では、 Orbを利用することでライブラリのインストールのような一般的・汎用的なタスクのジョブ定義を YAML から除外できます。全てのコマンドが Orb として公開されているわけではありませんが、パイプライン上でのキャッシュ管理や利用するパッケージマネージャーの選択など、パイプラインで実現したいこととは直接関係ない作業について考える手間を省けます。
他にもさまざまなOrbが公開されていますし、独自の private な orbを定義することも可能です。ぜひCircleCIを利用して、CI / CDパイプラインにおける「差別化されていない重労働」を削減しましょう。
