🐉 7つのボールを集めてモノレポ神召喚した話
🌟 はじめに
「7つの言語を統合したモノレポを作れば、技術力の神龍が召喚されるのでは?」
そんな思いから始まった、無謀とも思える挑戦の記録です。Zig、C++、Rust、Go、Kotlin、Python、TypeScriptという7つのプログラミング言語を、Turborepoで統合管理するモノレポを構築しました。
結果的に、Bazelとの格闘、Windows環境での苦労、そして最終的な勝利まで、技術選択の重要性を痛感する旅となりました。
🎯 なぜ7言語なのか?
技術的カバレッジの完全性
現代のソフトウェア開発で求められる全領域をカバーしたかったのです:
領域 | 言語 | 選択理由 |
---|---|---|
Next-gen System | 🔮 Zig | 最新技術への感度アピール |
Classic System | 🔧 C++ | 企業での根強い需要 |
Modern System | 🦀 Rust | 安全性・パフォーマンス |
Network/Cloud | 🐹 Go | クラウドネイティブ標準 |
JVM Modern | 🟣 Kotlin | エンタープライズ対応 |
Data/AI | 🐍 Python | ML/AI開発の中心 |
Web Frontend | ⚛️ TypeScript | モダンWeb開発 |
時代的な完全性
- 過去: C++ (1985-)
- 現在: Rust, Go, Kotlin, Python, TypeScript
- 未来: Zig (2024-)
🌪️ 第一の試練:Bazel地獄編
当初は「Google使ってるし、Bazelでしょ!」と安易に考えていました。
Bazelとの格闘記録
Rust統合での絶望
# cargo razeのインストールでつまずく
cargo install cargo-raze --locked --version 0.14.0
# → インストールできない
# rules_rustでのlockfileエラー
CARGO_BAZEL_REPIN=true bazel sync
# → lockfile version 4が理解できない
# → Cargoバージョンの非互換性
Windows環境での地獄
# シンボリックリンクエラー
WARNING: Failed to create symlink
# → 開発者モード有効化が必要
# UTF-8エンコーディング問題
couldn't read src\main.rs: stream did not contain valid UTF-8
# → VSCodeで再作成が必要
設定ファイルの複雑さ
# WORKSPACE.bazel(抜粋)
load("@rules_rust//crate_universe:repositories.bzl", "crate_universe_dependencies")
crate_universe_dependencies()
load("@rules_rust//crate_universe:defs.bzl", "crates_repository")
crates_repository(
name = "crate_index",
cargo_lockfile = "//:Cargo.lock",
lockfile = "//:Cargo.Bazel.lock",
manifests = ["//:Cargo.toml"],
)
# ... 延々と続く設定
敗北宣言
数時間格闘した結果、以下の結論に至りました:
Bazelは企業レベルの巨大プロジェクト用。個人・中小規模には複雑すぎる
💡 第二幕:Turborepo による救済
「実用性を重視しよう」と方針転換し、Turborepoを採用しました。
Turborepoを選んだ理由
1. 学習コストの低さ
// turbo.json - これだけ!
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", "target/**", "build/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
2. 各言語のネイティブツールを活用
# Rust
cargo build --release
# Go
go run .
# Python
poetry run python src/main.py
# Kotlin
gradle run
# C++
cmake --build build
# Zig
zig build run
3. 統一されたコマンド体系
# 全言語同時実行
npm run dev
# 特定言語のみ
npx turbo dev --filter=rust-api
npx turbo dev --filter=python-api
🎪 各ドラゴンボール(言語)の召喚過程
🔮 一星球:Zig
最も困難だった最新言語の統合。
const std = @import("std");
const print = std.debug.print;
pub fn main() !void {
print("Zig Next-Gen System Tools in Turborepo!\n", .{});
// 現在時刻の計算
const timestamp = std.time.timestamp();
const days_since_2000 = @divTrunc(timestamp, 86400) - 10957;
print("Days since 2000-01-01: {}\n", .{days_since_2000});
}
課題: AppDataDirUnavailable
エラー
解決: 環境変数でキャッシュディレクトリを明示指定
{
"scripts": {
"dev": "set ZIG_GLOBAL_CACHE_DIR=%LOCALAPPDATA%\\zig && zig build run --cache-dir .zig-cache"
}
}
🔧 二星球:C++
安定の高性能システム言語。CMake統合で意外と簡単。
class SystemAnalyzer {
public:
void performAnalysis() {
std::cout << "C++ System Analyzer in Turborepo!" << std::endl;
// メモリ管理デモ
auto numbers = std::make_unique<std::vector<int>>();
for(int i = 1; i <= 1000000; ++i) {
numbers->push_back(i);
}
auto sum = std::accumulate(numbers->begin(), numbers->end(), 0LL);
std::cout << "Sum: " << sum << std::endl;
}
};
ポイント: 絵文字文字化け問題で英語出力に統一
🦀 三星球:Rust
期待通りの安全性とパフォーマンス。
fn main() {
println!("🦀 Hello from Rust in Turborepo!");
let numbers = vec![1, 2, 3, 4, 5];
let sum: i32 = numbers.iter().sum();
println!("Sum: {}", sum);
}
🐹 四星球:Go
シンプルで高速。環境変数のGOCACHE問題以外はスムーズ。
func main() {
fmt.Println("🐹 Hello from Go in Turborepo!")
numbers := []int{1, 2, 3, 4, 5}
sum := 0
for _, n := range numbers {
sum += n
}
fmt.Printf("Sum: %d\n", sum)
}
🟣 五星球:Kotlin
JVM版ヘルスチェッカー。Gradleで安定動作。
fun main() {
println("🟣 Kotlin CLI Health Checker in Turborepo!")
val numbers = listOf(1, 2, 3, 4, 5)
val sum = numbers.sum()
println("Sum: $sum")
// システム情報
println("OS: ${System.getProperty("os.name")}")
println("JVM: ${System.getProperty("java.version")}")
}
🐍 六星球:Python
FastAPIでHTTPサーバー化。Poetry管理で依存関係もクリア。
from fastapi import FastAPI
from datetime import datetime
app = FastAPI(title="Python API", version="0.1.0")
@app.get("/")
async def hello():
return {
"message": "🐍 Hello from Python in Turborepo!",
"framework": "FastAPI",
"timestamp": datetime.now().isoformat()
}
⚛️ 七星球:TypeScript
Next.js 15で最新Web技術。Turborepoの本領発揮。
export default function Home() {
return (
<main>
<h1>⚛️ Next.js in Turborepo!</h1>
<p>TypeScript + React 18 + Server Components</p>
</main>
)
}
🐉 神龍召喚の瞬間
すべての球が集まった時、ついにモノレポ神が召喚されました:
$ npm run dev
• Packages in scope: cpp-system, docs, go-api, kotlin-api, python-api, rust-api, web, zig-tools
• Running dev in 8 packages
rust-api:dev: 🦀 Hello from Rust!
go-api:dev: 🐹 Hello from Go!
cpp-system:dev: C++ System Analyzer completed!
kotlin-api:dev: 🟣 Kotlin CLI Health Checker!
python-api:dev: 🐍 FastAPI running on port 8000
zig-tools:dev: Zig Next-Gen System Tools completed!
web:dev: ⚛️ Next.js on http://localhost:3000
docs:dev: 📚 Docs on http://localhost:3001
📊 Bazel vs Turborepo 最終決戦の結果
項目 | Bazel | Turborepo |
---|---|---|
セットアップ時間 | ❌ 数時間〜数日 | ✅ 45分で完成 |
Windows対応 | ❌ エラー地獄 | ✅ 完全対応 |
学習コスト | ❌ 非常に高い | ✅ 適切 |
実用性 | ❌ 企業専用 | ✅ 即戦力 |
言語サポート | ❌ 複雑設定 | ✅ ネイティブ対応 |
Rust統合 | ❌ 複雑・エラー多数 | ✅ 3分 |
Go統合 | ❌ 複雑 | ✅ 5分 |
Python統合 | ❌ 非常に困難 | ✅ 10分 |
🚀 現在の状況と今後の展望
現在できること
- ✅ 7言語の統一コマンドでの実行
- ✅ 各言語の特性を活かした実装
- ✅ 並列ビルド・キャッシュ
- ✅ Windows/Linux/macOS対応
今後の予定
Phase 1: CI/CD統合(次の目標)
# .github/workflows/ci.yml
name: Multi-Language CI
on: [push, pull_request]
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- name: Install dependencies
run: npm install
- name: Run tests
run: npm run test
- name: Build all
run: npm run build
Phase 2: Docker統合
# マルチステージビルドで各言語を統合
FROM rust:alpine as rust-builder
FROM golang:alpine as go-builder
FROM node:alpine as web-builder
# ... 各言語のビルド
FROM alpine:latest
COPY /app/target/release/rust-api /usr/local/bin/
COPY /app/go-api /usr/local/bin/
# ... 統合実行
Phase 3: 本格的なマイクロサービス化
- API Gateway(Next.js)
- 各言語サービス間通信
- 共通スキーマ定義(OpenAPI)
- 分散トレーシング
- 監視・ログ統合
Phase 4: パフォーマンス最適化
- 各言語のベンチマーク比較
- 最適化手法の実装
- 負荷テスト
- キャッシュ戦略の改善
💡 学んだこと
技術選択の重要性
「最新技術 ≠ 最適解」
Bazelは確かに強力ですが、目的に対して過剰でした。Turborepoは:
- 学習コスト適切
- 実用性重視
- 各言語の良さを活かす
- チーム開発に優しい
実用性 First の価値
企業での評価は「動かない高度な技術」より「動く実用的な技術」です。
Windows対応の重要性
開発者の多くがWindows環境。Windows軽視は機会損失につながります。
🎯 ポートフォリオとしての価値
技術幅の証明
- システムプログラミング: Zig, C++, Rust
- アプリケーション開発: Go, Kotlin
- データ・AI: Python
- Web開発: TypeScript
問題解決思考の証明
- Bazel → Turborepo の判断プロセス
- 各言語の環境問題の解決
- 実用性重視の技術選択
実行力の証明
- 動作する成果物
- 統一されたワークフロー
- 継続的な改善計画
🤝 おわりに
7つのプログラミング言語を統合したモノレポの構築は、技術選択の重要性を改めて教えてくれました。
「最新技術を追うだけでなく、目的に最適な技術を選択する」
これこそが、エンジニアに求められる本質的なスキルなのかもしれません。
現在のモノレポは基本動作のみですが、今後CI/CD、Docker、マイクロサービス化と段階的に進化させていく予定です。
リポジトリ
関連記事
あなたなら、どの技術選択をしますか?
Discussion