Workspace & Feature Flag
npm workspaces → cargo workspaces
หัวข้อที่มีชื่อว่า “npm workspaces → cargo workspaces”เมื่อ TypeScript monorepo เติบโตเกิน package เดียว คุณจะใช้ npm (หรือ pnpm/yarn) workspaces Cargo มีเทียบเท่าแบบ first-class: workspace คือ Cargo.toml เดียวที่ root ซึ่งระบุ member crate ทั้งหมด member ทั้งหมดใช้ Cargo.lock เดียวและ target/ build directory เดียวร่วมกัน
# package.json (root){ "name": "my-monorepo", "workspaces": [ "packages/api", "packages/core", "packages/cli" ]}
# packages/core/package.json{ "name": "@my/core", "version": "1.0.0"}# Cargo.toml (root — workspace manifest)[workspace]members = [ "crates/api", "crates/core", "crates/cli",]resolver = "2" # ใช้ resolver version 2 เสมอ
# crates/core/Cargo.toml[package]name = "core"version = "0.1.0"edition = "2024"รัน command ทั้ง workspace
หัวข้อที่มีชื่อว่า “รัน command ทั้ง workspace”# TypeScript (npm workspaces)npm run test --workspacesnpm run build --workspace packages/api
# Cargocargo build --workspace # build every membercargo test --workspace # test every membercargo build -p api # build only the "api" cratecargo test -p core # test only the "core" crateShare dependency version ข้าม crate
หัวข้อที่มีชื่อว่า “Share dependency version ข้าม crate”# Cargo.toml (root workspace manifest)[workspace.dependencies]tokio = { version = "1", features = ["full"] }serde = { version = "1", features = ["derive"] }
# crates/api/Cargo.toml — inherit without repeating the version[dependencies]tokio = { workspace = true }serde = { workspace = true }วิธีนี้กัน version drift ข้าม workspace member ที่เป็นปัญหาที่พบบ่อยใน Node monorepo ที่ package ต่างตัวดึง patch version ไม่ตรงกันโดยไม่รู้ตัว
Feature flag — conditional compilation
หัวข้อที่มีชื่อว่า “Feature flag — conditional compilation”Feature flag คือคำตอบของ Rust สำหรับ optional peer dependency และการเรียก require() แบบมีเงื่อนไข ช่วยให้ผู้ใช้เลือกใช้ฟังก์ชันเพิ่มเติมโดยไม่ต้องจ่าย compile cost เมื่อไม่ต้องการ
[features]default = ["json"] # features enabled by defaultjson = ["dep:serde_json"] # "json" feature pulls in serde_jsonasync = ["dep:tokio"] # "async" feature pulls in tokiofull = ["json", "async"] # convenience: enable everything
[dependencies]serde_json = { version = "1", optional = true }tokio = { version = "1", optional = true }#[cfg(feature = "json")]pub mod json_support { pub fn parse(s: &str) -> serde_json::Value { serde_json::from_str(s).unwrap() }}# Build with no default featurescargo build --no-default-features
# Enable specific featurescargo build --features "async,json"
# Enable all featurescargo build --all-featuresWorkspace และ feature flag ต้องการ project layout หลาย file จึงไม่มี browser Playground สำหรับบทนี้ สร้าง workspace ใน local ด้วย
cargo new --libและทดลองกับตัวอย่างข้างต้น