【Webアプリ開発2026 #3】業務で使用するツール群

目次

Linter

Linterとは

lint(linter)とは、コンピュータプログラムなどのソースコードを読み込んで内容を分析し、問題点を指摘してくれる静的解析ツール。また、そのようなツールで解析を行うこと。ツールを指す場合は "linter" (リンター)と呼ぶこともある。
https://e-words.jp/w/lint.html#:~:text=lint%EF%BC%88linter%EF%BC%89%E3%81%A8%E3%81%AF%E3%80%81,%E3%81%A8%E5%91%BC%E3%81%B6%E3%81%93%E3%81%A8%E3%82%82%E3%81%82%E3%82%8B%E3%80%82

Linterは、ソースコードを実行せずに解析して、潜在的なバグやルール違反を検出する静的解析ツールである。

コンパイラは「文法が壊れていて実行不可能なコード」しか検出できない。一方Linterは「実行はできるが、将来バグになりうるコード」を指摘してくれる。

たとえば以下のコードはPythonとして実行可能だが、問題を含んでいる。

def calculate_total(items):
    total = 0
    for item in items:
        total += item.price

    unused_variable = "この変数は使われない"  # Linterが検出する

    return total
    print("ここには到達しない")  # Linterが検出する(到達不能コード)

Linterはこのような「動くけど怪しい」コードを機械的に見つけてくれる。

  • 検出できる問題の例
    • 宣言されたが一度も使われていない変数(未使用変数)
    • return文の後に書かれた到達不能なコード
    • 変数を初期化する前に参照している箇所
    • import文の並び順がバラバラ(チームルール違反)
  • なぜ使うのか(運用観点)
    • 人間のコードレビューでスタイルの指摘をする手間がなくなる。レビューはロジックの議論に集中できる
    • CI(後述)に組み込むことで、ルール違反があるコードはそもそもマージできなくなる。チーム全員のコードが自動的に統一される
    • 「本番で動かして初めて気づくバグ」を開発段階で潰せる

Python

  • pep8 → https://pycodestyle.pycqa.org/en/latest/
    • Pythonの公式スタイルガイド PEP8 に準拠しているかをチェックするツール
    • PEP8は「インデントはスペース4つ」「1行は79文字以内」「import文の順序」などを定めている
    • 昔はツール名もpep8だったが pycodestyle にリネームされた
  • https://pypi.org/project/flake8/
    • 3つのチェックツールを1つにまとめたラッパー
      • pyflakes。未使用変数、未定義名の検出
      • pycodestyle。PEP8スタイルのチェック
      • mccabe。コードの複雑度(入れ子が深すぎないか等)の計測
    • プラグインで検査項目を追加できるのが特徴
    • 長年Pythonの標準的Linterだったが、後述するruffに置き換わりつつある
  • https://docs.astral.sh/ruff/
    • Rust製の超高速Linter。flake8と比較して10〜100倍高速
    • flake8 + isort + pyupgrade など、従来は複数ツールを組み合わせていた機能を1ツールで全てカバーする
      • 約800以上のルールを搭載し、ほとんどのPython Linterの機能を代替可能
    • pyproject.toml 1ファイルで設定を管理。ツールごとに設定ファイルが散らばらない
[tool.ruff]
target-version = "py312"
line-length = 120

[tool.ruff.lint]
select = [
    "E",   # pycodestyle errors
    "W",   # pycodestyle warnings
    "F",   # pyflakes
    "I",   # isort(import順序)
    "B",   # flake8-bugbear(よくあるバグパターン)
    "C4",  # flake8-comprehensions(内包表記の改善)
    "DTZ", # flake8-datetimez(タイムゾーン未指定の検出)
    "T20", # flake8-print(print文の検出)
    "C90", # mccabe(複雑度)
    "UP",  # pyupgrade(古い書き方の検出)
    "PT",  # pytest-style(テストの書き方)
    "D",   # pydocstyle(docstringの形式)
]
ignore = [
    "D100", # Missing docstring in public module
    "D104", # Missing docstring in public package
    "D105", # Missing docstring in magic method
    "D400", # First line should end with a period(日本語に不適)
    "D415", # First line should end with a period, question mark, or exclamation point(日本語に不適)
]
使い方
# プロジェクトにruffを追加(開発用依存として)
uv add --dev ruff

# 全ファイルをチェック(問題の報告のみ)
uv run ruff check .

# 自動で直せる問題は直しつつチェック
uv run ruff check . --fix

JavaScript / TypeScript

JS/TS用のLinter。歴史的なツールからモダンな統合ツール、新興ツールの順。

  • https://eslint.org/
    • 事実上の標準
    • プラグインで好きにルールを足せる(TypeScript / React / a11y 等)
    • 設定は eslint.config.js(Flat Config)で管理
  • https://biomejs.dev/ja/
    • Rust製のall-in-one(Lint + Format + Import整列を1ツールでカバー)
    • ESLint + Prettier を置き換える流れ
    • 設定は biome.json 1ファイル
  • https://oxc.rs/
    • Rust製の爆速Linter。Biomeよりさらに高速
    • ESLint互換ルールを実装中
    • ruff / Biome / Oxc という「Rust製linter/formatterの波」の最前線

Formatter

Formatterとは

フォーマッター(formatter)とは、整形や区画付けといった意味を持つ「フォーマット」(format)操作を行うためのソフトウェアや機能などのこと。
https://e-words.jp/w/%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%82%BF%E3%83%BC.html

Formatterは、コードの意味を変えずに見た目(スタイル)を自動で統一するツールである。

Linterとの違いを整理すると以下の通り。

  • Linter → 「このコードにはバグがあるかもしれない」と指摘する(修正は人間がやる)
  • Formatter → 「このコードの見た目を統一する」と自動で書き換える(ロジックは変えない)

たとえば以下の2つのコードは動作が全く同じだが、見た目が異なる。

# 整形前(人によってバラバラ)
def greet( name:str,age :int)->str:
    return f"Hello {name}, you are {age} years old"

# 整形後(Formatterが自動で揃える)
def greet(name: str, age: int) -> str:
    return f"Hello {name}, you are {age} years old"
  • 整形される内容の例
    • スペースの位置(name:strname: str
    • インデントの深さ、改行位置
    • クォートの統一(' or "
    • 一行の最大文字数を超えた場合の自動折り返し
    • 末尾カンマの追加・削除
  • なぜ使うのか(運用観点)
    • 「タブ vs スペース」「シングルクォート vs ダブルクォート」というスタイル論争が消滅する。チームで議論する時間がゼロになる
    • git diff にスタイル変更が混ざらなくなる。レビュー時に「ロジックの変更だけ」が見えるようになる
    • ファイル保存時やCI上で自動実行すれば、開発者が意識しなくても常にコードが整っている状態を維持できる

Python

  • https://pypi.org/project/autopep8/
    • PEP 8 違反を自動修正するツール
    • 修正範囲が限定的で、現在では Black や Ruff に置き換えられている
  • https://black.readthedocs.io/en/stable/
    • 「意見の強いフォーマッター(opinionated formatter)」として登場
    • 設定オプションをあえて極端に絞ることで、「どう整形するか」の議論自体を排除する設計思想
    • 「Black に従う or 従わない」の二択。チームで揉めることがなくなる
    • Python公式(PSF)も採用しており、事実上の標準だった
  • https://docs.astral.sh/ruff/
    • Linterとして紹介したruffがフォーマット機能も搭載している
    • Black と99%以上互換の整形結果を出力するため、Blackからの乗り換えがスムーズ
    • Lint + Format を1ツールで完結できるのが最大の利点
    • 設定も pyproject.toml に集約される
    [tool.ruff.format]
    quote-style = "double"
    indent-style = "space"
    line-ending = "auto"
使い方
pip install ruff

# 全ファイルを整形する(実際に書き換わる)
uv run ruff format .

# 整形が必要なファイルがないかチェックのみ(CIで使う)
uv run ruff format --check .

JavaScript / TypeScript

JS/TS用のFormatter。Linterと同じく歴史的なツールからモダンな統合ツール、新興ツールの順。

  • https://prettier.io/
    • 事実上の標準
    • 設定は .prettierrc で最低限だけ書く
  • https://biomejs.dev/ja/
    • Linterとして紹介したBiomeがフォーマット機能も搭載
    • Prettier互換の整形結果
    • Lint + Format を1ツールで完結できるのが強み
  • https://oxc.rs/docs/guide/usage/formatter.html
    • Oxc プロジェクト発のRust製formatter。Prettier比30倍・Biome比2〜3倍速い
    • Prettier互換を狙うが現状はBeta(2026/5時点)
    • Oxlintと統合される方向。本番採用はまだ早い

型チェッカー

なぜ型チェッカーが必要なのか

Pythonは「動的型付け言語」なので、型を書かなくてもコードは動く。しかしチーム開発や長期運用では以下のような問題が起きる。

def get_user_name(user):
    return user.name  # userに何が来るのか、コードを読むだけではわからない

# 半年後、別の開発者がこう呼んでしまう
result = get_user_name(None)  # 実行時にAttributeErrorで落ちる

型アノテーションを書き、型チェッカーで検証することで、実行する前にこの手のバグを検出できる。

from dataclasses import dataclass

@dataclass
class User:
    name: str
    age: int

def get_user_name(user: User) -> str:
    return user.name

result = get_user_name(None)  # 型チェッカーがエラーを出す(実行前に検出)

Mypy

  • Python公式の型チェックツール。最も広く使われている
  • 型アノテーション(def func(x: int) -> str:)を読み取り、矛盾がないかを静的にチェックする
  • Python自体は型アノテーションを完全に無視する(実行時にはコメントと同じ扱い)ため、型チェッカーがないとアノテーションを書いても意味がない

  • チェック項目
    機能 説明
    関数の引数・戻り値 型アノテーションと実際に渡される値の型が一致しているか
    クラスの属性 正しい型が使われているか、未定義の属性を参照していないか
    Union, Optional 複数の型が混在する変数の安全な取り扱いができているか
    ジェネリクス list[str], dict[str, int] などの型パラメータが正しいか
    カスタム型エイリアス UserId = NewType("UserId", int) などの型定義が正しく使われているか
使い方
uv add --dev mypy

# プロジェクト全体の型チェック
uv run mypy .

パッケージ マネージャ

パッケージマネージャとは

アプリケーションを作るとき、全てをゼロから書くことはない。「HTTPリクエストを送る」「JSONを扱う」「DBに接続する」といった汎用的な処理はライブラリ(パッケージ)として公開されており、それを取り込んで使う。

パッケージマネージャは、これらのライブラリを追加・削除・バージョン管理するためのツールである。

おおまかに2種類に分けられる。

  • OSレベル
    • OS全体にソフトウェアをインストールする
    • apt(Ubuntu), brew(macOS)など
  • プロジェクトレベル
    • 特定のプロジェクト内でのみ使うライブラリを管理する
    • npm(JavaScript), cargo(Rust)など
    • → 今回扱うのはこちら

参考:https://www.hitachi-solutions.co.jp/sbom/blog/2023033101/

主な機能

  • インストール・アンインストール
    • コマンド1つでライブラリを追加・削除できる
  • バージョン固定(ロックファイル)
    • チーム全員が「同じバージョン」のライブラリを使うことを保証する。「自分の環境では動くのに本番で動かない」を防ぐ
  • 依存関係の自動解決
    • ライブラリAがライブラリBを必要とし、BがCを必要とする…という連鎖を自動で追跡・解決してくれる

Python

poetry
  • Pythonの依存関係管理とパッケージングを統合的に行うツール
  • 社内での使用事例が多い
  • pyproject.toml(直接使いたいパッケージ)と poetry.lock(全依存の正確なバージョン)の2ファイルで管理する
    • poetry.lock をGitにコミットすることで、チーム全員・CI・本番環境が同一のライブラリバージョンを使う
  • 導入方法
    # インストール(pipx経由が公式推奨)
    pipx install poetry
    
    # パッケージ追加
    poetry add package-name
    
    # 開発用パッケージ追加(本番には含めない)
    poetry add --group dev pytest ruff
uv
  • Rust製の高速パッケージマネージャ。ruffと同じAstral社が開発している
  • poetryと比較して依存解決・インストールが10〜100倍高速
  • Python自体のバージョン管理も行える(.python-version ファイルで指定)
  • pyproject.toml + uv.lock で管理する構造はpoetryと同じ
  • 新規プロジェクトではuvを使用する
  • 導入方法
    # インストール(公式推奨)
    curl -LsSf https://astral.sh/uv/install.sh | sh
    # または
    brew install uv
    
    # プロジェクト初期化(pyproject.tomlが作られる)
    uv init
    
    # パッケージ追加
    uv add fastapi
    
    # 開発用依存の追加(本番には含まれない)
    uv add --dev ruff mypy pytest
    
    # 実行(仮想環境を自動で作成・有効化して実行する)
    uv run python app.py

JavaScript / TypeScript

Node.js環境でのライブラリ(パッケージ)はnpmパッケージという形式になっている。

この使用するパッケージやそのバージョンを管理するもの。

ランタイム

https://nodejs.org/en

ChromeのJavaScriptエンジン(v8)を元に、ブラウザ以外でも実行できるようにしたもの。

サーバや開発環境で使う環境は基本これ一択。

代替環境

過去のTech Talk資料

ビルドツール

補足: 開発フローの中での位置づけ

ツールが使われるタイミング

ここまで紹介したツール群は、実際の開発ではどのタイミングで使われるのか。典型的なチーム開発のフローに当てはめると以下のようになる。

  1. コードを書く
  2. ファイル保存時にFormatterが自動整形(エディタ設定)
  3. git commit 前にLinter + 型チェッカーを実行(手動 or pre-commit hook)
  4. Pull Requestを出す
  5. CI(GitHub Actions等)がLint / Format / 型チェック / テストを自動実行 → 1つでも失敗したらマージ不可
  6. コードレビュー(人間はロジックだけを見ればよい)
  7. マージ → デプロイ

運用上のポイント:

  • これらのツールは「開発者の手間を減らす」ためではなく、「チームのコード品質を自動で維持する仕組み」として導入される
  • ツールの設定は pyproject.toml に集約し、全員が同じルールで開発する
  • CIで強制することで、「ルールを知らない新メンバー」が入っても品質が下がらない

なぜVSCode拡張だけでなくツール本体を使うのか:

VSCodeにはruffやmypyの拡張機能があり、エディタ上でリアルタイムに指摘を表示してくれる。便利だが、拡張機能だけに頼るのは運用上危険である。

  • 個人の環境に依存する
    • 拡張の有無・バージョン・設定はメンバーごとに異なる。「Aさんの環境では指摘されるがBさんの環境ではスルーされる」という状態が起きうる
  • AIはVSCode拡張を読めない
    • AIが書いたコードに対しても適用する場合、CLIで実行することが必須
  • 入れ忘れ・無効化を防げない
    • 新メンバーが拡張をインストールし忘れたり、指摘がうるさくて無効化しても誰も気づかない
  • CIで実行するにはツール本体が必要
    • CI(GitHub Actions等)上にVSCodeは存在しない。チームとして品質を担保するには、コマンドラインで実行できるツール本体をCIに組み込み、全員のコードに対して同じチェックを強制する必要がある
    用途 使うもの 役割
    開発中のリアルタイム指摘 VSCode拡張 書きながらすぐ気づける(補助)
    チームとしての品質保証 ツール本体(CLI) CIで全員に強制する(本丸)

拡張機能は「早く気づくための補助輪」、ツール本体は「品質を保証するゲート」と捉えるとよい。