---
type: Reference
title: "言語別開発ガイド"
description: "本プロジェクトでは、Nix を使用して各プログラミング言語の開発環境を個別に提供しています。"
tags: [reference]
status: stable
generated: { by: human:kakimomokuri, at: 2026-04-06T03:31:33Z }
---

# 言語別開発ガイド

本プロジェクトでは、Nix を使用して各プログラミング言語の開発環境を個別に提供しています。各環境は `nix develop .#<言語名>` コマンドで起動でき、必要なツールや LSP、Vim 設定が自動的に適用されます。

## ソフトウェア開発の三種の神器

開発を効率的に進めるために、以下の3つの要素を重視します。

### 1. バージョン管理 (Git)
全ての変更は Git で管理し、意味のある単位でコミットします。

- **コミットメッセージ規約(Angular形式)**:

  `type(scope): subject` の形式で記述します。

  - `feat`:

    新機能

  - `fix`:

    バグ修正

  - `test`:

    テストの追加・修正

  - `refactor`:

    リファクタリング

  - `chore`:

    雑事(設定変更等)

### 2. テスティング (TDD)
テスト駆動開発 (Test-Driven Development) を実践します。

1. **Red**:

   失敗するテストを書く

2. **Green**:

   テストを通す最小限の実装を書く

3. **Refactor**:

   コードをきれいに整理する

### 3. 自動化
コマンド一つでビルド、テスト、静的解析を実行できるようにします。また、ファイル変更を監視して自動的にテストを実行する「継続的テスト」を活用します。

---

## 共通の開発フロー

1. **環境の起動**:

   `nix develop .#<language>`

2. **プロジェクトの初期化**:

   各言語のパッケージマネージャで初期化

3. **Git初期化**:

   `git init` (まだの場合)

4. **TDDサイクル**:

   継続的テストを回しながら実装

5. **静的解析**:

   リンターやフォーマッタでコード品質をチェック

6. **コミット**:

   `git add .` -> `git commit -m '...'`

---

## 言語別ガイド

### 1. Node.js / TypeScript

- **起動コマンド**:

  `nix develop .#node`

- **主要ツール**:

  Node.js (v22), npm, TypeScript, ESLint, Prettier

- **初期化**:


  ```bash
  npm init -y
  ```
- **TDDチュートリアル**:
  1. **Red**: `hello.test.js` を作成。
     ```javascript
     import assert from 'node:assert';
     import { test } from 'node:test';
     import { hello } from './hello.js';
     
     test('hello returns greeting', () => {
       assert.strictEqual(hello(), 'Hello,World!');
     });
     ```
     実行（失敗）: `node --test hello.test.js`

  2. **Green**: `hello.js` を実装。
     ```javascript
     export function hello() { 
       return "Hello, World!"; 
     }
     ```
  3. **Refactor**: 必要に応じてコードを整理。
- **自動化**:
  - `node --watch --test hello.test.js` で変更を監視。

### 2. Python
- **起動コマンド**: `nix develop .#python`
- **主要ツール**: Python 3.12, uv, pytest, ruff (Linter/Formatter)
- **初期化**:
  ```bash
  uv init
  uv add --dev pytest ruff
  ```
- **TDDチュートリアル**:
  1. **Red**: `test_hello.py` を作成。
     ```python
     from hello import hello
     def test_hello():
         assert hello() == "Hello, World!"
     ```
     実行（失敗）: `uv run pytest`

  2. **Green**: `hello.py` を実装。
     ```python
     def hello():
         return "Hello, World!"
     ```
  3. **Refactor**: `uv run ruff check .` や `uv run ruff format .` で品質を整える。
- **自動化**:
  - `uv run pytest` を使用。

### 3. Go
- **起動コマンド**: `nix develop .#go`
- **主要ツール**: Go, gopls, golangci-lint, delve
- **初期化**:
  ```bash
  go mod init example.com/hello
  ```
- **TDDチュートリアル**:
  1. **Red**: `hello_test.go` を作成。
     ```go
     package hello
     import "testing"
     func TestHello(t *testing.T) {
         want := "Hello, World!"
         if got := Hello(); got != want {
             t.Errorf("Hello() = %q, want %q", got, want)
         }
     }
     ```
     実行（失敗）: `go test`

  2. **Green**: `hello.go` を作成。
     ```go
     package hello
     func Hello() string { return "Hello, World!" }
     ```
  3. **Refactor**: `go fmt ./...` や `golangci-lint run` を実行。

### 4. Rust
- **起動コマンド**: `nix develop .#rust`
- **主要ツール**: cargo, rust-analyzer, clippy, rustfmt
- **初期化**:
  ```bash
  cargo init
  ```
- **TDDチュートリアル**:
  1. **Red**: `src/lib.rs` にテストを記述。
     ```rust
     pub fn hello() -> String { todo!() }
     #[cfg(test)]
     mod tests {
         use super::*;
         #[test]
         fn it_works() {
             assert_eq!(hello(), "Hello, World!");
         }
     }
     ```
     実行（失敗）: `cargo test`

  2. **Green**: `hello` 関数を実装。
     ```rust
     pub fn hello() -> String { "Hello, World!".to_string() }
     ```
  3. **Refactor**: `cargo clippy` で警告を確認し、`cargo fmt` で整形。
- **自動化**:
  - `cargo watch -x test` で変更監視（要インストール）。

### 5. Java
- **起動コマンド**: `nix develop .#java`
- **主要ツール**: JDK, Gradle, Maven, Checkstyle, PMD
- **初期化**:
  ```bash
  gradle init --type java-library --test-framework junit-jupiter
  ```
- **TDDチュートリアル**:
    1. **Red**: `src/test/java/LibraryTest.java` にテスト追加.
       ```java
       @Test
       void testGreeting() {
           Library classUnderTest = new Library();
           assertEquals("Hello, World!", classUnderTest.getGreeting());
       }
       ```
       実行（失敗）: `./gradlew test`

    2. **Green**: `src/main/java/Library.java` を修正.
       ```java
       public String getGreeting() { return "Hello, World!"; }
       ```
    3. **Refactor**: `./gradlew qualityCheck` (Checkstyle/PMD) を実行.
- **自動化**:
    - `./gradlew test --continuous` で継続的テスト.
- **詳細**: [Javaアプリケーション環境構築ガイド](Javaアプリケーション環境構築ガイド.md) を参照.

### 6. .NET (C#)
- **起動コマンド**: `nix develop .#dotnet`
- **主要ツール**: .NET SDK, OmniSharp
- **初期化**:
  ```bash
  # ソリューションの作成
  dotnet new sln --name Hello
  # ライブラリプロジェクトの作成
  dotnet new classlib -o Hello
  # テストプロジェクトの作成
  dotnet new xunit -o Hello.Tests
  # プロジェクトをソリューションに追加
  dotnet sln Hello.sln add Hello/Hello.csproj Hello.Tests/Hello.Tests.csproj
  # テストプロジェクトからライブラリプロジェクトへの参照を追加
  dotnet add Hello.Tests/Hello.Tests.csproj reference Hello/Hello.csproj
  ```
- **TDDチュートリアル**:
  1. **Red**: `Hello.Tests/UnitTest1.cs` を修正。
     ```csharp
     namespace Hello.Tests;
     using Xunit;

     public class UnitTest1
     {
         [Fact]
         public void Test1()
         {
             Assert.Equal("Hello, World!", Hello.Lib.Greet());
         }
     }
     ```
     実行（失敗）: `dotnet test`

  2. **Green**: `Hello/Lib.cs` を実装。
     ```csharp
     namespace Hello;

     public static class Lib
     {
         public static string Greet() => "Hello, World!";
     }
     ```
  3. **Refactor**: `dotnet format` でコードを整形。
- **自動化**:
  - `dotnet watch test` で変更を監視し自動テスト実行。

### 7. Ruby
- **起動コマンド**: `nix develop .#ruby`
- **主要ツール**: Ruby, Bundler, Minitest, RuboCop
- **初期化**:
  ```bash
  bundle init
  echo 'gem "minitest"' >> Gemfile
  bundle install
  ```
- **TDDチュートリアル**:
  1. **Red**: `test_hello.rb` を作成.
     ```ruby
     require 'minitest/autorun'
     require_relative 'hello'
     class TestHello < Minitest::Test
       def test_hello
         assert_equal "Hello, World!", hello()
       end
     end
     ```
     実行（失敗）: `ruby test_hello.rb`

  2. **Green**: `hello.rb` を実装.
     ```ruby
     def hello; "Hello, World!"; end
     ```
  3. **Refactor**: `rubocop -a` でコードスタイルを自動修正.

### 8. PHP
- **起動コマンド**: `nix develop .#php`
- **主要ツール**: PHP, Composer, PHPUnit, PHP_CodeSniffer
- **初期化**:
  ```bash
  composer init -n
  composer require --dev phpunit/phpunit
  ```
- **TDDチュートリアル**:
  1. **Red**: `tests/HelloTest.php` を作成.
     ```php
     use PHPUnit\Framework\TestCase;
     class HelloTest extends TestCase {
         public function testHello() {
             $this->assertEquals("Hello, World!", hello());
         }
     }
     ```
     実行（失敗）: `./vendor/bin/phpunit tests`

  2. **Green**: `src/hello.php` を実装.
     ```php
     function hello() { return "Hello, World!"; }
     ```
  3. **Refactor**: `./vendor/bin/phpcs src` で規約チェック.

### 9. Haskell
- **起動コマンド**: `nix develop .#haskell`
- **主要ツール**: GHC, Stack, Cabal, HLS, hlint, fourmolu
- **初期化**:
  ```bash
  stack new hello
  cd hello
  # package.yaml の tests.hello-test.dependencies に hspec を追加
  stack test
  ```
- **TDDチュートリアル**:
  1. **Red**: `test/Spec.hs` を編集.
     ```haskell
     module Main (main) where
     import Test.Hspec
     import Lib (hello)

     main :: IO ()
     main = hspec $ do
       describe "hello" $ do
         it "returns greeting" $ do
           hello `shouldBe` "Hello, World!"
     ```
     実行（失敗）: `stack test`

  2. **Green**: `src/Lib.hs` を実装.
     ```haskell
     module Lib (hello) where
     hello :: String
     hello = "Hello, World!"
     ```
  3. **Refactor**:

     - `hlint .` でコードの改善案をチェック.
     - `fourmolu -i src/**/*.hs` でコードを整形.
- **自動化**:
  - `stack test --file-watch` で変更を監視し自動テスト実行.

### 10. Clojure
- **起動コマンド**: `nix develop .#clojure`
- **主要ツール**: Clojure CLI, Leiningen, Babashka, Clojure LSP, clj-kondo (Linter), zprint (Formatter)
- **初期化**:
  ```bash
  # Clojure CLI を使用する場合
  clj -T:build new :name my-app
  # または Leiningen を使用する場合
  lein new app my-app
  ```
- **TDDチュートリアル**:
  1. **Red**: `test/my_app/core_test.clj` を作成。
     ```clojure
     (ns my-app.core-test
       (:require [clojure.test :refer :all]
                 [my-app.core :refer :all]))

     (deftest hello-test
       (testing "Greeting test"
         (is (= "Hello, World!" (hello)))))
     ```
     実行（失敗）: `clj -X:test` または `lein test`

  2. **Green**: `src/my_app/core.clj` を実装。
     ```clojure
     (ns my-app.core)

     (defn hello []
       "Hello, World!")
     ```
  3. **Refactor**:

     - `clj-kondo --lint src` で静的解析を実行。
     - `bb -cp $(clojure -Spath) -m zprint.main src` (zprintが利用可能な場合) でコード整形。
- **自動化**:
  - `lein test-refresh` で変更を監視し自動テスト実行（要プラグイン設定）。
  - Babashka (`bb`) を使用して軽量なタスクランナーを構築可能。

### 11. Elixir
- **起動コマンド**: `nix develop .#elixir`
- **主要ツール**: Elixir, Erlang, Mix, Elixir LS
- **初期化**:
  ```bash
  mix new my_app
  cd my_app
  ```
- **TDDチュートリアル**:
  1. **Red**: `test/my_app_test.exs` にテストを記述。
     ```elixir
     defmodule MyAppTest do
       use ExUnit.Case
       test "greets the world" do
         assert MyApp.hello() == "Hello, World!"
       end
     end
     ```
     実行（失敗）: `mix test`

  2. **Green**: `lib/my_app.ex` を実装。
     ```elixir
     defmodule MyApp do
       def hello do
         "Hello, World!"
       end
     end
     ```
  3. **Refactor**: `mix format` でコードを整形。
- **自動化**:
  - `mix test --watch` (要 `mix_test_watch` パッケージ) で変更を監視。

### 12. Scala
- **起動コマンド**: `nix develop .#scala`
- **主要ツール**: Scala 3, sbt, Metals, Scala CLI
- **初期化**:
  ```bash
  # Scala CLI を使用してプロジェクト構造を作成する場合
  mkdir my-app && cd my-app
  # または sbt を使用する場合
  sbt new scala/scala-seed.g8
  ```
- **TDDチュートリアル**:
  1. **Red**: `Hello.test.scala` を作成（Scala CLI + MUnit の例）.
     ```scala
     //> using lib "org.scalameta::munit::0.7.29"
     class HelloTest extends munit.FunSuite {
       test("hello returns greeting") {
         assert(Hello.greeting == "Hello, World!")
       }
     }
     ```
     実行（失敗）: `scala-cli test .`

  2. **Green**: `Hello.scala` を実装.
     ```scala
     object Hello {
       def greeting: String = "Hello, World!"
     }
     ```
  3. **Refactor**: `scala-cli fmt .` でコードを整形.
- **自動化**:
  - `scala-cli test . --watch` で変更を監視し自動テスト実行.

### 13. F#
- **起動コマンド**: `nix develop .#dotnet`
- **主要ツール**: .NET SDK, Ionide (LSP), Fantomas (Formatter)
- **初期化**:
  ```bash
  # ソリューションの作成
  dotnet new sln --name Hello
  # ライブラリプロジェクトの作成
  dotnet new classlib -lang "F#" -o Hello
  # テストプロジェクトの作成
  dotnet new xunit -lang "F#" -o Hello.Tests
  # プロジェクトをソリューションに追加
  dotnet sln Hello.sln add Hello/Hello.fsproj Hello.Tests/Hello.Tests.fsproj
  # テストプロジェクトからライブラリプロジェクトへの参照を追加
  dotnet add Hello.Tests/Hello.Tests.fsproj reference Hello/Hello.fsproj
  ```
- **TDDチュートリアル**:
  1. **Red**: `Hello.Tests/Tests.fs` を修正。
     ```fsharp
     namespace Hello.Tests
     open Xunit
     module Tests =
         [<Fact>]
         let ``Hello returns greeting`` () =
             Assert.Equal("Hello, World!", Hello.Lib.greet())
     ```
     実行（失敗）: `dotnet test`

  2. **Green**: `Hello/Library.fs` を実装。
     ```fsharp
     namespace Hello
     module Lib =
         let greet () = "Hello, World!"
     ```
  3. **Refactor**: `dotnet fantomas .` (インストール済みの場合) でコードを整形。
- **自動化**:
  - `dotnet watch test` で変更を監視し自動テスト実行。

---

## 環境の切り替え
別の環境に切り替える場合は、現在のシェルを終了 (`exit`) してから、新しい環境の起動コマンドを実行してください。
複数の環境を同時に使用したい場合は、新しいターミナルタブを開くか、tmux 等のターミナルマルチプレクサの利用を推奨します。
