

























Makefile/Just/Task 哪个更现代,是未来趋势?
Make/Just: 它们本质上是 Shell 转发器。在 Windows 上它们调 powershell,在 Linux 上调 bash。如果你写了 rm -rf,在没有配置好的 Windows 环境下就会直接报错。
Task: 它内置了一个 Go 语言编写的 Shell 解释器。这意味着你在 Taskfile 里写的脚本逻辑,在所有操作系统上运行结果几乎完全一致,不再需要像你之前在 justfile 里那样痛苦地写 if os() == "windows"。
就连 GitHub Actions 官方文档都推荐 Task(虽然和Just的star相差一倍)!
Task两者Just都宣称自己是Make专门用于任务运行的替代方案。
这里介绍的是Task(file)
推荐使用 scope(类似于mac下的brew)来安装它,那我们先安装scope
# 普通用户
irm get.scoop.sh | iex
# admin用户
iex "& {$(irm get.scoop.sh)} -RunAsAdmin"
使用scope来安装just
scoop install task
brew install go-task
最后确认下
task --version
以下是一个 同时启动前后端的配置!
version: '3'
output: prefixed
vars:
VENV_BIN: '{{if eq OS "windows"}}.venv/Scripts{{else}}.venv/bin{{end}}'
PYTHON: '{{.VENV_BIN}}/python'
tasks:
default:
desc: "启动"
cmds:
- task: dev
dev:
desc: "启动开发环境"
cmds:
- "echo ✈ 启动开发环境..."
deps: [backend, frontend]
install-web:
desc: "安装前端依赖"
dir: web
cmds:
- pnpm install
install-server:
desc: "安装后端依赖"
dir: server
cmds:
- uv sync
install:
desc: "安装依赖"
cmds:
- task: install-web
- task: install-server
frontend:
desc: "启动前端"
dir: web
cmds:
- "echo 🚀 启动前端"
- pnpm run dev
backend:
desc: "启动后端"
dir: server
cmds:
- "echo 🚀 启动后端"
- "{{.PYTHON}} -m uvicorn server.app:server --reload --host 0.0.0.0"
stop:
desc: "停止后端服务 (强杀端口)"
cmds:
- "{{if eq OS \"windows\"}}stop-process -Id (Get-NetTCPConnection -LocalPort 8000).OwningProcess -Force{{else}}lsof -t -i:8000 | xargs kill -9{{end}}"
ignore_error: true
restart:
desc: "重启后端服务"
cmds:
- task: stop
- task: backend
build-web:
desc: "构建前端静态文件"
dir: web
cmds:
- pnpm build
# 其实这个意义不大,相当于本地preview,因为部署服务器如果走cd/ci的话(比如 github action),就无法利用task
start:
desc: "启动服务"
cmds:
- "echo 🚀 启动服务: 将前端打包到后端静态目录中,并启动后端服务"
- task: build-web
- "rm -rf server/server/static/* && mkdir -p server/server/static"
- "cp -r web/dist/* server/server/static/"
- task: backend
比如
tasks:
install:
desc: "安装依赖"
cmds:
- "cd web && pnpm install"
- "cd server && uv sync"
Task 提供了一个 dir 参数,专门用来指定该任务执行的工作目录。这样你的命令会变得非常干净。而且把你原来的两行拆成 install-web 和 install-server 有一个巨大的好处-并发执行(Speed!)。
tasks:
install-web:
desc: "安装前端依赖"
dir: web
cmds:
- pnpm install
install-server:
desc: "安装后端依赖"
dir: server
cmds:
- uv sync
# 组合任务
install:
desc: "一键安装所有依赖"
cmds:
- task: install-web
- task: install-server
在 Task (Taskfile) 的语法中,{{.PYTHON}} 是一个变量引用。
你可以把它理解为 Python 里的 f"{PYTHON}" 或者 JS 里的 ${PYTHON}。它的作用是把你在顶部 vars 模块里定义的内容,“填”到你的命令里。
vars:
PYTHON: ".venv/bin/python" # 1. 在这里定义
tasks:
backend:
cmds:
- "{{.PYTHON}} --version" # 2. 在这里引用
deps (Dependencies) 是 Taskfile 中处理并发启动的最佳方式。当你把任务放在 deps 里时,它们会同时启动。
dev:
cmds:
- task: backend # 1. 启动后端,进程在这里被阻塞(因为 uvicorn 会一直运行)
- task: frontend # 2. 只有当前面的后端关闭了,才会运行前端
因为 uvicorn 和 pnpm dev 都是常驻进程(Long-running processes),它们不主动结束,下一行命令就永远不会开始。
# 建议在顶部加上这个,让并发运行的日志带有前缀颜色,方便分辨
output: prefixed
tasks:
dev:
desc: "一键启动前后端"
# deps 里的任务会并行(parallel)执行
deps: [backend, frontend]
为什么方案 A (deps) 更好?
日志交织处理:当你同时启动前后端时,屏幕上会瞬间涌出大量日志。配合 output: prefixed,Task 会在每行日志前加上 [WEB] 或 [API],否则你根本分不清谁是谁。
生命周期管理:当你按 Ctrl + C 时,Task 会作为“父进程”捕捉到信号,然后同时关闭它启动的所有子进程(前端和后端)。
真正的跨平台:不需要去考虑 Shell 的后台运行符(如 &),因为 & 在 Windows 的 PowerShell 下行为很怪异,而 deps 是 Task 内部实现的,全平台表现一致。

关于taskfile支持的vscode插件,一共两个,只用第一个就够了:

当前项目如何利用GitHub action自动部署呢?
参考 .github\workflows\deploy.yml
name: Build & Deploy
on:
push:
branches: [main]
workflow_dispatch:
env:
DEPLOY_DIR: /home/apps/lark-monitor-server
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_PORT: ${{ secrets.REMOTE_PORT || 22 }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ---------- 前端构建 ----------
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
cache-dependency-path: web/pnpm-lock.yaml
- name: Install frontend dependencies
run: pnpm install
working-directory: web
- name: Build frontend
run: pnpm build
working-directory: web
# ---------- 打包产物 ----------
- name: Prepare artifact
run: |
rm -rf server/server/static/*
mkdir -p server/server/static
cp -r web/dist/* server/server/static/
tar -czf release.tar.gz -C server .
# ---------- 部署到服务器 ----------
- name: Deploy to server
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ env.REMOTE_HOST }}
port: ${{ env.REMOTE_PORT }}
username: root
key: ${{ env.SSH_PRIVATE_KEY }}
source: release.tar.gz
target: /tmp
- name: Deploy and restart
uses: appleboy/ssh-action@v1
with:
host: ${{ env.REMOTE_HOST }}
port: ${{ env.REMOTE_PORT }}
username: root
key: ${{ env.SSH_PRIVATE_KEY }}
script: |
mkdir -p ${{ env.DEPLOY_DIR }}
tar -xzf /tmp/release.tar.gz -C ${{ env.DEPLOY_DIR }}
rm /tmp/release.tar.gz
cd ${{ env.DEPLOY_DIR }} && uv sync
# 杀掉旧进程,重新启动
lsof -t -i:8000 | xargs -r kill -9 || true
nohup .venv/bin/uvicorn server.app:server --host 0.0.0.0 --port 8000 > uvicorn.log 2>&1 &
非必看,和本教程无关。
如上的项目我部署的服务器和nginx服务不是同一台,怎么代理过去呢?
# xx.dingshaohua.com
server {
listen 80;
server_name lark.dingshaohua.com;
rewrite ^(.*)$ https://$host$1 permanent;
}
server {
listen 443 ssl;
server_name xx.dingshaohua.com;
include conf.d/common.conf;
location / {
proxy_pass http://xx.xx.xx.xx:8000;
}
}
https://blog.csdn.net/gitblog_00247/article/details/151125318
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。