Justfile: Task runner đơn giản thay thế Makefile và script shell

Justfile: Task runner đơn giản thay thế Makefile và script shell

Justfile (câu lệnh just) là task runner hiện đại được viết bằng Rust, thay thế Makefile, npm scripts, bash script với cú pháp rõ ràng, hỗ trợ tham số, biến môi trường và cross-platform. Với 25.000+ stars trên GitHub và được sử dụng bởi hàng ngàn dự án open source (Rust, Go, Node.js), Justfile đang trở thành tiêu chuẩn cho việc tự động hóa quy trình build, test, deploy trong team dev.

Khác với Makefile (40 năm tuổi, cú pháp dựa trên tab, chỉ chạy trên Unix), Justfile chạy được trên Windows, macOS, Linux, hỗ trợ comment, string interpolation, điều kiện if/else, và tích hợp sẵn với shell completion.

So sánh Makefile vs Justfile: Makefile dùng tab, không có kiểu dữ liệu; Justfile dùng cú pháp hiện đại, hỗ trợ parameter, cross-platform

Tại sao chọn Justfile?

  • Cú pháp đơn giản: Giống Makefile nhưng không yêu cầu tab, hỗ trợ comment dòng (#), string có dấu ngoặc kép.
  • Cross-platform: Chạy như nhau trên Windows (PowerShell/CMD), macOS (zsh/bash), Linux — không cần Cygwin hay WSL.
  • Hỗ trợ tham số: Task nhận argument, có default value, validation.
  • Variable interpolation: Biến môi trường, biến nội bộ, biến từ file .env.
  • Shell completion: Tự động sinh completion cho bash, zsh, fish, PowerShell.
  • Dry-run mode: just --dry-run xem lệnh sẽ chạy mà không thực thi.
  • Watch mode: just --watch tự động chạy lại khi file thay đổi.
Bảng so sánh Makefile vs npm scripts vs Justfile theo các tiêu chí: cross-platform, parameter, syntax, shell completion

Cài đặt Justfile

# macOS
brew install just

# Linux (Debian/Ubuntu)
sudo apt install just
# hoặc từ binary release
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin

# Windows
scoop install just
# hoặc winget
winget install --id Casey.Just

# Rust (nếu có cargo)
cargo install just

Justfile cơ bản

Tạo file justfile (hoặc Justfile) ở root dự án:

# Biến toàn cục
version := "1.0.0"
build_dir := "target/release"

# Task mặc định (chạy khi gõ `just`)
default: build

# Task đơn giản
build:
    cargo build --release

test:
    cargo test

clean:
    rm -rf target

# Task với tham số
deploy env="staging":
    echo "Deploying {{version}} to {{env}}..."
    ./scripts/deploy.sh {{env}}

# Task phụ thuộc
release: test build
    echo "Release {{version}} ready!"

# Variable từ môi trường
docker_build:
    docker build -t myapp:{{version}} .

Tính năng nâng cao

1. Tham số (Parameters)

Task có thể nhận tham số vị trí hoặc named parameter:

# Tham số vị trí
greet name:
    echo "Xin chào {{name}}!"

# Tham số có default
build profile="release":
    cargo build --profile {{profile}}

# Tham số biến thể (variadic)
test *args:
    cargo test {{args}}

# Validation
lint fix=false:
    if fix == "true"
        cargo clippy --fix
    else
        cargo clippy

Chạy: just greet "Chu Húng", just build profile=debug, just test -- --nocapture

2. Biến và interpolation

# Biến cục bộ
name := "my-project"
version := "1.0.0"

# Biến từ file .env (tự động load nếu có .env)
# .env nội dung: DATABASE_URL=postgres://localhost:5432/mydb
# Just tự động load các biến này

# Biến từ lệnh shell
git_hash := `git rev-parse --short HEAD`
git_branch := `git branch --show-current`

# Sử dụng
build:
    echo "Building {{name}} v{{version}} ({{git_hash}} on {{git_branch}})"

# String interpolation trong lệnh
tag_image:
    docker tag myapp:{{version}} myregistry/{{name}}:{{version}}

3. Điều kiện (Conditionals)

deploy env:
    if env == "prod"
        echo "Deploying to PRODUCTION - are you sure?"
        read -p "Type 'yes' to confirm: " confirm
        if confirm != "yes"
            echo "Cancelled"
            exit 1
    else
        echo "Deploying to {{env}}..."
    ./scripts/deploy.sh {{env}}

# Shorthand condition
test coverage=false:
    if coverage == "true"
        cargo test -- --coverage
    else
        cargo test

4. Private tasks và groups

# Private task (không hiện trong `just --list`, không chạy trực tiếp)
_install-deps:
    cargo install cargo-watch cargo-expand

# Group: chạy nhiều task cùng lúc
lint: _fmt _clippy _check

_fmt:
    cargo fmt --check

_clippy:
    cargo clippy -- -D warnings

_check:
    cargo check

# Alias
_ := _install-deps
setup: _install-deps
    echo "Development environment ready!"

5. Shell completion

# Tự động sinh completion
just --completions bash > ~/.bash_completion.d/just
just --completions zsh > ~/.zsh/completions/_just
just --completions fish > ~/.config/fish/completions/just.fish
just --completions powershell > just.ps1

# Sau đó reload shell

Ví dụ thực tế: Dự án Rust web service

# justfile cho dự án Rust web service (axum + sqlx)

version := "0.1.0"
docker_image := "myorg/my-service"
registry := "ghcr.io"

# Default task
default: help

# Help custom
help:
    @just --list

# Development
dev:
    cargo watch -x run

# Database
db-up:
    docker compose up -d postgres

db-down:
    docker compose down

db-migrate:
    sqlx migrate run

db-reset: db-down db-up db-migrate

# Testing
test:
    cargo test

test-integration:
    cargo test --test integration

# Linting
fmt:
    cargo fmt

clippy:
    cargo clippy -- -D warnings

lint: fmt clippy

# Build
build:
    cargo build --release

build-docker:
    docker build -t {{docker_image}}:{{version}} .
    docker tag {{docker_image}}:{{version}} {{registry}}/{{docker_image}}:{{version}}

# Release
release: lint test build build-docker
    docker push {{registry}}/{{docker_image}}:{{version}}
    echo "Released {{version}} to {{registry}}"

# Deploy
deploy env:
    kubectl set image deployment/{{name}} {{name}}={{registry}}/{{docker_image}}:{{version}} -n {{env}}

# Clean
clean:
    cargo clean
    docker rmi {{docker_image}}:{{version}} || true

So sánh với các công cụ khác

Tính năng Makefile npm scripts Justfile
Cross-platform Không (chỉ Unix) Có (Node.js required) Có (binary đơn lẻ)
Cú pháp Tab-based, cryptic JSON string, escaping Modern, readable
Tham số task Khó (biến môi trường) Khó (– truyền vào script) Native, validation
Biến Gán đơn giản package.json + env Mạnh mẽ, shell command
Shell completion Không Không Có (bash/zsh/fish/pwsh)
Watch mode Không Cần nodemon/chokidar Có (–watch)
Dry-run Không Không Có (–dry-run)
Dependencies Chỉ file timestamp Không có Task dependencies

Best practices

  1. Đặt task mặc định là help: default: help hoặc custom help task.
  2. Dùng prefix _ cho private task: Task nội bộ không muốn expose ra ngoài.
  3. Load .env file: Just tự động load .env — hữu ích cho secrets.
  4. Tách config và logic: Biến ở đầu file, task ở dưới.
  5. Dùng @ để ẩn lệnh: @echo "Done" chỉ hiển thị output, không hiển thị lệnh.
  6. Group task liên quan: lint: fmt clippy check chạy toàn bộ lint pipeline.
  7. Commit justfile vào repo: Toàn team dùng chung một task runner.

Kết luận

Justfile mang lại sự cân bằng giữa đơn giản của Makefile và tính năng của task runner hiện đại. Với binary ~3MB, zero dependency, cross-platform thực sự và cú pháp thân thiện, Justfile xứng đáng trở thành task runner mặc định cho mọi dự án — từ side project cá nhân đến production system quy mô lớn. Nếu bạn đang dùng Makefile, npm scripts, hoặc tập hợp các bash script rời rạc, hãy thử chuyển sang Justfile trong 15 phút — bạn sẽ thấy sự khác biệt ngay lập tức.

Just GitHub Repository, Just Manual, Just Cookbook (Ví dụ thực tế)

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

8 tính năng ẩn trên iPhone: Back Tap, Khóa ứng dụng, SOS khẩn cấp không cần app

iOS 18 mang đến hàng loạt tính năng mới: Apple Intelligence, màn hình khóa tùy biến, RCS, Game Mode. Nhưng bên cạnh những thay đổi lớn, nhiều “mẹo ẩn” (hidden…

Xem thêm
Kitty terminal emulator rendering code

GitHub CLI (gh) nâng cao: Tự động hóa PR, issue, release trực tiếp từ terminal

GitHub CLI (gh) nâng cao: Tự động hóa PR, issue, release trực tiếp từ terminal GitHub CLI (`gh`) là công cụ chính thức của GitHub giúp developer thao tác GitHub…

Xem thêm

rsync backup Linux: Sao lưu dữ liệu tự động qua SSH đầy đủ

rsync là tiêu chuẩn sao lưu trên Linux, nhưng phần lớn người dùng chỉ dùng cờ -avz cơ bản. Công cụ này thực sự có thể chuyển file delta (chỉ…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất