|
34 | 34 | special name used to identify the root directory of the monorepo. |
35 | 35 | </Callout> |
36 | 36 |
|
37 | | -Configuration in a package can override any of [the configurations for a |
38 | | -task](/docs/reference/configuration#defining-tasks). Any keys that are not included are inherited |
39 | | -from the extended `turbo.json`. |
| 37 | +## Inheritance behavior |
| 38 | + |
| 39 | +When a Package Configuration extends the root `turbo.json`, task properties are inherited differently depending on their type. |
| 40 | + |
| 41 | +### Scalar fields are inherited |
| 42 | + |
| 43 | +Scalar fields like `outputLogs`, `cache`, `persistent`, and `interactive` are **inherited** from the root configuration. You only need to specify them in a Package Configuration if you want to override them. |
| 44 | + |
| 45 | +For example, if your root `turbo.json` sets `"outputLogs": "hash-only"` for a task, all packages inherit that setting automatically. |
| 46 | + |
| 47 | +### Array fields replace by default |
| 48 | + |
| 49 | +Array fields like `outputs`, `env`, `inputs`, `dependsOn`, and `passThroughEnv` **completely replace** the root configuration's values by default. |
| 50 | + |
| 51 | +```jsonc title="./turbo.json" |
| 52 | +{ |
| 53 | + "tasks": { |
| 54 | + "build": { |
| 55 | + "outputs": ["dist/**"], |
| 56 | + "env": ["NODE_ENV"] |
| 57 | + } |
| 58 | + } |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +```jsonc title="./apps/my-app/turbo.json" |
| 63 | +{ |
| 64 | + "extends": ["//"], |
| 65 | + "tasks": { |
| 66 | + "build": { |
| 67 | + // This REPLACES the root outputs - "dist/**" is NOT included |
| 68 | + "outputs": [".next/**"] |
| 69 | + } |
| 70 | + } |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +### Extending arrays with `$TURBO_EXTENDS$` <ExperimentalBadge>Pre-release</ExperimentalBadge> |
| 75 | + |
| 76 | +To **add** to inherited array values instead of replacing them, use the [`$TURBO_EXTENDS$` microsyntax](/docs/reference/configuration#turbo_extends-pre-release): |
| 77 | + |
| 78 | +```jsonc title="./apps/my-app/turbo.json" |
| 79 | +{ |
| 80 | + "extends": ["//"], |
| 81 | + "tasks": { |
| 82 | + "build": { |
| 83 | + // Inherits "dist/**" from root AND adds ".next/**" |
| 84 | + "outputs": ["$TURBO_EXTENDS$", ".next/**"] |
| 85 | + } |
| 86 | + } |
| 87 | +} |
| 88 | +``` |
| 89 | + |
| 90 | +The `$TURBO_EXTENDS$` marker must be the first element in the array. It works with `outputs`, `env`, `inputs`, `dependsOn`, `passThroughEnv`, and `with`. |
40 | 91 |
|
41 | 92 | ## Examples |
42 | 93 |
|
@@ -143,40 +194,9 @@ but continue to inherit any other tasks defined at the root. |
143 | 194 |
|
144 | 195 | ## Comparison to package-specific tasks |
145 | 196 |
|
146 | | -At first glance, Package Configurations may sound a lot like the |
147 | | -[`package#task` syntax](/docs/crafting-your-repository/configuring-tasks#depending-on-a-specific-task-in-a-specific-package) in the root `turbo.json`. The features are |
148 | | -similar, but have one significant difference: when you declare a package-specific task |
149 | | -in the root `turbo.json`, it _completely_ overwrites the baseline task |
150 | | -configuration. With a Package Configuration, the task configuration is merged |
151 | | -instead. |
152 | | - |
153 | | -Consider the example of the monorepo with multiple Next.js apps and a Sveltekit |
154 | | -app again. With a package-specific task, you might configure your root |
155 | | -`turbo.json` like this: |
156 | | - |
157 | | -```jsonc title="./turbo.json" |
158 | | -{ |
159 | | - "tasks": { |
160 | | - "build": { |
161 | | - "outputLogs": "hash-only", |
162 | | - "inputs": ["src/**"], |
163 | | - "outputs": [".next/**", "!.next/cache/**"] |
164 | | - }, |
165 | | - "my-sveltekit-app#build": { |
166 | | - "outputLogs": "hash-only", // must duplicate this |
167 | | - "inputs": ["src/**"], // must duplicate this |
168 | | - "outputs": [".svelte-kit/**"] |
169 | | - } |
170 | | - } |
171 | | -} |
172 | | -``` |
173 | | - |
174 | | -In this example, `my-sveltekit-app#build` completely overwrites `build` for the |
175 | | -Sveltekit app, so `outputLogs` and `inputs` also need to be duplicated. |
| 197 | +The [`package#task` syntax](/docs/crafting-your-repository/configuring-tasks#depending-on-a-specific-task-in-a-specific-package) in the root `turbo.json` **completely overwrites** all task configuration—nothing is inherited. |
176 | 198 |
|
177 | | -With Package Configurations, `outputLogs` and `inputs` are inherited, so |
178 | | -you don't need to duplicate them. You only need to override `outputs` in |
179 | | -`my-sveltekit-app` config. |
| 199 | +With Package Configurations, scalar fields are inherited and only the fields you specify are overridden. This means less duplication when you only need to change one or two properties. |
180 | 200 |
|
181 | 201 | <Callout type="info"> |
182 | 202 | Although there are no plans to remove package-specific task configurations, we |
@@ -218,18 +238,18 @@ Package Configuration for `my-nextjs-app`: |
218 | 238 | { |
219 | 239 | "tasks": { |
220 | 240 | "my-nextjs-app#build": { |
221 | | - // ❌ This is not allowed. Even though it's |
| 241 | + // This is not allowed. Even though it's |
222 | 242 | // referencing the correct package, "my-nextjs-app" |
223 | 243 | // is inferred, and we don't need to specify it again. |
224 | 244 | // This syntax also has different behavior, so we do not want to allow it. |
225 | 245 | // (see "Comparison to package-specific tasks" section) |
226 | 246 | }, |
227 | 247 | "my-sveltekit-app#build": { |
228 | | - // ❌ Changing configuration for the "my-sveltekit-app" package |
| 248 | + // Changing configuration for the "my-sveltekit-app" package |
229 | 249 | // from Package Configuration in "my-nextjs-app" is not allowed. |
230 | 250 | }, |
231 | 251 | "build": { |
232 | | - // ✅ just use the task name! |
| 252 | + // Just use the task name! |
233 | 253 | } |
234 | 254 | } |
235 | 255 | } |
|
0 commit comments