awesome-everything RU
↑ Back to the climb

Frontend Architecture

Monorepo: config and pipeline reading

Crux Read real Turborepo and Nx config snippets, predict the task graph and cache behaviour, and pick the highest-leverage fix.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at senior altitude — in orbit
◷ 14 min

The pipeline config and the cache key are where monorepo problems are actually diagnosed. Read the config, predict the task graph and what hashes into the cache, then choose the fix a senior engineer would make first.

Goal

Practise the loop you run on every slow or unsafe monorepo pipeline: read the task config, work out the ordering and the cache key, spot the false hit or false miss, and reach for the structural fix before adding hardware.

Snippet 1 — the task graph

// turbo.json
{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": []
    }
  }
}
Quiz

What ordering does this config produce, and what is the difference between the two dependsOn entries?

Snippet 2 — the cache key

// turbo.json — build task inputs
{
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "inputs": ["src/**/*.ts", "src/**/*.tsx"],
      "outputs": ["dist/**"]
    }
  }
}
Quiz

A change to the shared root tsconfig.json alters compiler output, but every build still cache-hits and ships stale dist. Reading these inputs, what is the bug and the fix?

Snippet 3 — affected detection

# CI: only build/test what this PR could have broken
npx nx affected -t build test --base=origin/main --head=HEAD
Quiz

On a long-lived release branch this command suddenly reports the whole repo as affected for a tiny diff. Most likely cause?

Snippet 4 — module boundaries

// .eslintrc — @nx/enforce-module-boundaries
{
  "depConstraints": [
    { "sourceTag": "type:feature", "onlyDependOnLibsWithTags": ["type:ui", "type:util"] },
    { "sourceTag": "type:ui",      "onlyDependOnLibsWithTags": ["type:util"] },
    { "sourceTag": "type:util",    "onlyDependOnLibsWithTags": ["type:util"] }
  ]
}
Quiz

Which import does this config reject at lint time, and what graph problem does the rejection prevent?

Recap

Every monorepo pipeline problem is read in config and a git range: the caret in dependsOn decides whether upstream packages build first; the inputs glob is the cache key, where a missing tsconfig is a false hit and a volatile path is a false miss; affected scope is a graph walk over a diff, so a wrong —base inflates it to the whole repo; and depConstraints keep low-level libraries from gaining the fan-in that makes every change global. Read the config, fix the key or the boundary, then re-run and confirm the affected set and hit rate behave.

Continue the climb ↑Monorepo: cut CI from the world to a slice
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.