just:用 justfile 替代 Makefile 跑项目任务

起因

每个项目都有一堆"开发命令":

pnpm dev
docker compose up -d
uv run pytest
ruff check . && mypy .
docker compose exec api python manage.py shell

放哪?

  • package.json scripts:JS 项目 OK,但 Python / Rust 项目不自然
  • Makefile:tab vs space / 老语法 / shell 转义恶心 / 不跨平台
  • README 里 copy-paste:散
  • shell alias:项目特定的不该污染全局

just 是 Rust 写的命令记事本 / task runner。justfile 取代 Makefile,
专门为"跑命令" 设计(不为编译 build artifact)。

brew install just                 # macOS
cargo install just                # 通用
sudo apt install just             # ubuntu 22.04+

基础 justfile

# justfile(项目根)

# 默认 task:列出所有
default:
    @just --list

# 装依赖
install:
    uv sync
    pnpm install

# 启动 dev
dev:
    docker compose up -d db redis
    uv run python manage.py runserver

# 跑测试
test:
    uv run pytest -x

# 检查代码质量
lint:
    ruff check .
    mypy .
    pnpm tsc --noEmit

跑:

$ just              # 默认 → just --list
$ just install
$ just test
$ just lint

vs Makefile

# Makefile 等价
.PHONY: install test
install:
    uv sync
    pnpm install

test:
    uv run pytest -x
  • Makefile 要 tab 缩进(编辑器配错就崩)
  • Makefile 假设是"build artifact"(filename dependency),shell 当 side effect
  • $(VAR) $$VAR 转义恶心
  • 跨平台不一致(GNU make vs BSD make)

just 直接 shell 命令 / 空格缩进 / 跨平台一致 / 默认无 dependency
跟踪(这是 feature,不是 bug,跑命令不需要)。

参数

# 带参数
greet name='world':
    echo "hello {{name}}"

# 多 arg
deploy env target:
    ./deploy.sh {{env}} {{target}}
$ just greet
hello world
$ just greet Alice
hello Alice
$ just deploy prod web

参数变量用 {{name}} 引用(Mustache 风格)。

recipe 调 recipe

build:
    pnpm build

deploy: build
    ./deploy.sh

# 或者显式
release:
    just lint
    just test
    just build
    ./release.sh

用 python / node 写 recipe

# bash(默认)
hello:
    echo "hello"

# python
analyze:
    #!/usr/bin/env python3
    import json
    with open('data.json') as f:
        data = json.load(f)
    print(f"items: {len(data)}")

# node
gen:
    #!/usr/bin/env node
    console.log('hi from node');

#! 第一行指定 shebang → 整个 recipe 当一个 script 跑(不是逐行)。

环境变量

# justfile 顶部 set
set dotenv-load        # 自动加载 .env

# 默认变量
NAME := "myapp"
PORT := env_var_or_default("PORT", "8000")

run:
    PORT={{PORT}} ./{{NAME}}

# Linux specific
[linux]
clean:
    rm -rf build/

[macos]
clean:
    rm -rf build/ .DS_Store

[linux] [macos] recipe attribute 让同 recipe 在不同平台用不同命令。

列出 + help

$ just --list
Available recipes:
    default     # 列出所有
    install     # 装依赖
    test        # 跑测试

# recipe 上面的注释自动当 docstring

每个 recipe 顶部加注释 → 自动是描述。新人 clone 项目 just 一下立刻
知道有什么任务。

我的常用模板

# justfile

set dotenv-load
set positional-arguments

PYTHON := "uv run"

default:
    @just --list

# 初始化(一键 onboarding)
init:
    uv sync
    pnpm install
    docker compose up -d db
    {{PYTHON}} python manage.py migrate
    {{PYTHON}} python manage.py createsuperuser --noinput || true

# 开发
dev:
    docker compose up -d db redis
    {{PYTHON}} python manage.py runserver 0.0.0.0:8000

# 测试 + 覆盖率
test *args='':
    {{PYTHON}} pytest -x --cov=. {{args}}

# 代码检查(CI 同样跑)
lint:
    {{PYTHON}} ruff check .
    {{PYTHON}} ruff format --check .
    {{PYTHON}} mypy .

# 自动 fix
fix:
    {{PYTHON}} ruff check . --fix
    {{PYTHON}} ruff format .

# DB migrate / shell / etc
migrate:
    {{PYTHON}} python manage.py migrate

shell:
    {{PYTHON}} python manage.py shell

makemigrations *args='':
    {{PYTHON}} python manage.py makemigrations {{args}}

# 部署相关
deploy env:
    @echo "deploying to {{env}}..."
    ./scripts/deploy.sh {{env}}

*args='' 收尾通过位置传给 recipe(如 just test forum/tests.py)。

与 npm scripts 对比

package.json

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "test": "vitest"
  }
}
  • JSON 单行字符串 → 复杂命令难看
  • 跨平台 (Windows) 转义不一致
  • 只能 cd 到 package.json 所在目录跑

just 更适合多 layer / 多语言项目。npm script 适合纯 JS 单项目。

很多项目我两个都用:package.json 给 JS 的 thin wrapper,justfile
给跨语言 orchestration(justfile 调 npm script)。

CI 集成

GitHub Actions:

- uses: extractions/setup-just@v2
- run: just lint
- run: just test

CI = 本地的 just,绝对一致。

与 mage / task / make 对比

just make task (taskfile.dev) mage
语言 rust C go go
配置 justfile Makefile Taskfile.yml magefile.go
跨平台
学习曲线
适合 通用任务跑 C/C++ build 现代替代 make go 项目

just 是"现代 Make 替代品 for 命令"。如果你在做实际编译依赖跟踪(如 C/C++
build),用 make 或 cmake。

踩过的坑

  1. PATH 不一致:CI 跑 just → recipe 里 npx 找不到。set shell := ["bash", "-cu"] + ensure tool 装好。

  2. dotenv 自动加载敏感变量到子进程set dotenv-load.env
    变量进所有 recipe shell。生产 secrets 不要放项目根 .env,分开。

  3. recipe shell 默认 sh 不是 bashpipefail 等 bash-only。
    set shell := ["bash", "-cu"] 改。

  4. 变量插值与 shell 冲突{{VAR}} 是 just 模板,shell 里用
    ${VAR} 是 shell 变量。混着用要小心。

  5. 递归 just 调 just:可以但易嵌套深 → 跑得乱。一般保持扁平结构。

精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。