Skip to content

package.json & Scripts

概述

Walnut Admin 的 package.json 遵循一套严格的脚本约定:每个 workspace 包都有相同的 script 名称,根 scripts 只做委托。这套约定让 Turborepo 能统一编排所有包的任务。

我们做了什么

1. 标准化 script 名称

每个包至少包含以下 scripts(名称一致):

jsonc
{
  "scripts": {
    "build": "tsc",              // 构建产物
    "dev": "tsc --watch",        // 开发模式
    "clean": "rm -rf dist",      // 清理
    "typecheck": "tsc --noEmit", // 纯类型检查(不产出文件)
    "lint": "eslint src/",       // 代码检查
    "lint:fix": "eslint --fix src/",
    "test": "vitest run",        // 单次测试
    "test:watch": "vitest",      // 持续测试
    "test:coverage": "vitest run --coverage"
  }
}

一致性 > 自由度。不要有的包叫 lint,有的叫 eslint——Turbo 需要统一的 task 名来编排。

2. 根 scripts 只做委托

jsonc
// root package.json — 极薄的一层
{
  "scripts": {
    "dev": "turbo dev --filter=@walnut/admin",  // 默认只启前端
    "dev:all": "turbo dev",                      // 全部启动
    "build": "NODE_OPTIONS=--max-old-space-size=8192 turbo build",
    "lint": "turbo lint",
    "lint:fix": "turbo lint:fix",
    "types:check": "turbo types:check",
    "test": "turbo test",
    "clean": "turbo clean",

    // 全局命令(不走 turbo,因为有副作用)
    "format": "prettier --write .",
    "format:check": "prettier --check .",

    // 单包便捷命令
    "dev:admin": "pnpm --filter @walnut/admin dev",
    "dev:server": "pnpm --filter @walnut/server dev",
    "dev:docs": "pnpm --filter @walnut/docs dev",

    // 发布
    "changeset": "changeset",
    "changeset:auto": "tsx scripts/version/auto-changeset.ts",
    "release": "tsx scripts/version/release.ts",
    "changelog": "git-cliff -o CHANGELOG.md",

    // 代码质量
    "knip": "knip",
    "knip:packages": "knip --workspace packages/*"
  }
}

关键规则:根 scripts 不包含构建逻辑。turbo build 会找到所有包的 build script 并按拓扑顺序执行。

3. 按包类型的差异化

包类型buildtypecheckdev
Vue 应用 (@walnut/admin)vue-tsc --noEmit && vite buildvue-tsc --noEmitvite --port 3100
NestJS (@walnut/server)nest build (SWC)tsc --noEmitnest start --watch
纯 TS 包 (@walnut/utils)tsctsc --noEmittsc --watch
源码消费 (@walnut/client)不构建tsc --noEmit

前端构建的特殊性:vue-tsc --noEmit 在 build 阶段跑一次类型检查(Vite 构建本身不做类型检查)。日常开发的类型检查通过 pnpm types:checkturbo types:check)来做。

4. Git Hooks

pre-commit → lint-staged(ESLint fix on staged files,秒级)
pre-push   → pnpm types:check(全仓库类型检查,十秒级)

pre-commit 只跑 ESLint fix,不做类型检查(太慢,阻塞 commit 体验)。类型检查放在 pre-push

没做什么 / 为什么

不写 mega-scripts

不在根 package.json 写复杂的 shell 脚本。所有跨包编排由 Turbo 处理,所有发布逻辑由 scripts/version/ 下的 TS 文件处理。根 scripts 保持"一句话委托"。

不用 concurrently 编排

concurrently 只能并行启动进程,不理解依赖拓扑。turbo dev 不仅并行启动,还按依赖顺序执行(先启动被依赖的包,再启动依赖者),避免"依赖还没准备好就请求"的问题。


关键文件

文件作用
package.json根 scripts,全为委托
apps/admin/package.json前端 scripts(Vite + vue-tsc)
apps/server/package.json后端 scripts(NestJS CLI + SWC)

基于 MIT 许可发布