You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit d459434
Browse filesBrowse the repository at this point in the historyBrowse files
- Accepts configuration objects. For a parameterized preset, call the preset function and pass its return value.
42
+
- Can be called at most once per configuration load, including calls with an empty array.
43
+
- Applies shared configurations from left to right, then project definitions, regardless of call order.
44
+
45
+
See [Shared configurations](./configuration#shared-configurations) for nested inheritance, merge rules, and examples.
46
+
47
+
### `RstackConfig`
48
+
49
+
A type for authoring shared configurations. Its optional `app`, `lib`, `doc`, `test`, `lint`, `fmt`, and `staged` fields accept the same inputs as the corresponding `define.*()` APIs. Its optional `extends` field accepts `readonly RstackConfig[]` for nested inheritance.
-`cwd`: the directory used to search for a configuration file and resolve relative configuration file paths. Defaults to the current working directory.
79
+
-`configFilePath`: a relative or absolute configuration file path. If omitted, uses the CLI's `--config` path when set; otherwise, searches for the [default configuration file names](./configuration#configuration-file) in `cwd`.
80
+
81
+
The returned object contains:
82
+
83
+
-`configs`: effective tool definitions, including shared configurations and project definitions. A tool's field is absent if it was never defined.
84
+
-`filePath`: the loaded configuration file's path, or `null` if no file was found.
85
+
-`dependencies`: configuration dependencies reported by the loader.
86
+
87
+
Configuration functions remain unevaluated. A field may be an async function even when all its inputs were objects, because merging is deferred until that tool is needed. Consumers must resolve definitions with the appropriate tool parameters and follow the tool's configuration and execution flow; this API does not return fully resolved runtime configurations. In particular, loading alone does not apply Rstack's automatic test inheritance or formatting normalization. Staged functions remain task generators that receive file names.
88
+
89
+
`rstack/config` also exports the `Configs`, `LoadedRstackConfig`, and `LoadRstackConfigOptions` types.
90
+
28
91
## Re-exports
29
92
30
93
The tool-specific subpaths below re-export the public APIs from their corresponding core packages. Using these entry points keeps imports unified and APIs aligned with the tool versions integrated by Rstack CLI.
Copy file name to clipboardExpand all lines: website/docs/en/guide/configuration.mdx
+168-1Lines changed: 168 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -74,6 +74,171 @@ define.fmt({
74
74
});
75
75
```
76
76
77
+
## Shared configurations
78
+
79
+
Use `define.extends()` to reuse configurations across projects. A shared configuration is a plain object typed as `RstackConfig`. It can contain `app`, `lib`, `doc`, `test`, `lint`, `fmt`, and `staged`, each accepting the same input as its corresponding `define.*()` API.
This project inherits the test and lint configurations and formats with `singleQuote: true` and `printWidth: 100`. You do not need to call `define.test()` or `define.lint()` to enable inherited settings.
110
+
111
+
Call `define.extends()` at most once per configuration load, with all shared configurations in one array. A second call throws, even if the first call used an empty array. Call it while loading `rstack.config.*`, just like the other `define.*()` APIs.
112
+
113
+
### Merge order
114
+
115
+
Configurations are applied in this order:
116
+
117
+
1. Shared configurations in the `define.extends()` array, from left to right.
118
+
2. Project configurations registered with `define.*()`, regardless of where those calls appear relative to `define.extends()`.
119
+
120
+
Later configurations take precedence according to each tool's [merge rules](#merge-rules).
121
+
122
+
Shared configurations can also extend other shared configurations:
123
+
124
+
```ts title="team.ts"
125
+
importtype { RstackConfig } from'rstack';
126
+
import { sharedConfig } from'./shared.ts';
127
+
128
+
exportconst teamConfig:RstackConfig= {
129
+
extends: [sharedConfig],
130
+
test: {
131
+
retry: 3,
132
+
},
133
+
};
134
+
```
135
+
136
+
Inherited configurations are applied before the object that extends them. Here, the order is `sharedConfig → teamConfig → project configuration`.
137
+
138
+
Each occurrence of a shared configuration is applied. For example, if both `a` and `b` extend `base`, `define.extends([a, b])` applies `base → a → base → b → project configuration`. This can append arrays more than once; plugin deduplication follows the underlying tool's behavior. Circular inheritance throws an error that identifies the reference path.
139
+
140
+
### Merge rules
141
+
142
+
Rstack merges configurations separately for each tool:
|`test`| Uses Rstest's `mergeRstestConfig`, then determines whether to inherit the merged App or Lib configuration. See [Test configuration inheritance](./testing#configuration-inheritance). |
149
+
|`lint`| Concatenates configuration arrays in order; Rslint applies their rules. |
150
+
|`fmt`| Shallow merge: later values replace earlier values for the same option. Arrays and objects, including `overrides`, are replaced as a whole. |
151
+
|`doc`| Uses Rspress's `mergeDocConfig`: recursively merges objects, appends arrays, and replaces ordinary functions with later functions. |
152
+
|`staged`| Shallow merge by glob pattern: later tasks replace earlier tasks for the same pattern, including command arrays and task functions. |
153
+
154
+
For `doc`, when both values are defined and either is an array, Rspress treats the other value as a one-item array before concatenating them. These rules also apply to `builderConfig`: Rstack does not additionally call `mergeRsbuildConfig`. For example, a later `builderConfig.tools.rspack` callback replaces an earlier callback, while callback arrays are concatenated.
155
+
156
+
For `staged`, if either the accumulated configuration or the next configuration is a top-level task-generator function, the next configuration replaces the accumulated configuration entirely. Subsequent glob mappings merge from that replacement; they do not restore earlier tasks. Task functions run when lint-staged supplies the staged file list, not while merging configurations.
157
+
158
+
### App and lib presets
159
+
160
+
A developer infrastructure team can maintain two presets: one for App + Test + Lint + Format, and another for Lib + Test + Lint + Format. Both can extend the `sharedConfig` above.
161
+
162
+
A preset can be a regular function when consumers need options. Call it to produce an object before passing it to `define.extends()`:
After publishing these presets as `@biz/app-preset` and `@biz/lib-preset`, an application can use:
204
+
205
+
```ts title="rstack.config.ts (application)"
206
+
import { appPreset } from'@biz/app-preset';
207
+
import { define } from'rstack';
208
+
209
+
define.extends([appPreset({ title: 'My App' })]);
210
+
```
211
+
212
+
A library can use:
213
+
214
+
```ts title="rstack.config.ts (library)"
215
+
import { libPreset } from'@biz/lib-preset';
216
+
import { define } from'rstack';
217
+
218
+
define.extends([libPreset]);
219
+
```
220
+
221
+
Make the presets' dependencies available: for this example, the App preset needs `@rsbuild/plugin-react`, and application projects need `happy-dom` for their tests.
222
+
223
+
### Loading dependencies and resolving paths
224
+
225
+
Shared configurations follow the same [dependency loading guidance](#loading-dependencies-on-demand) as project configurations. Only the tool configuration functions needed by a command are evaluated. In the App preset above, `rs lint` and `rs fmt` do not load the React plugin; `rs test` may load it when inheriting the App configuration. The outer `appPreset()` function runs when the configuration file is loaded, so keep tool-specific imports inside the relevant configuration function.
226
+
227
+
Relative paths follow each tool's existing rules. They are not automatically resolved relative to the shared configuration module. For a file shipped with a preset, use an absolute path derived from that module:
Include `setup.ts` in the published package at that location, or adjust the path to the built file. Existing local configuration dependency tracking also applies to shared modules: editing an imported local shared configuration reloads App, Lib, and Doc configurations in their development or watch modes.
241
+
77
242
## Configuration APIs
78
243
79
244
Configuration options follow the formats of the underlying tools. When using APIs and helpers that Rstack CLI re-exports, prefer the `rstack/app`, `rstack/lib`, `rstack/test`, and `rstack/lint` entry points.
@@ -158,6 +323,8 @@ When `extends` is omitted, Rstack CLI automatically connects the test configurat
158
323
159
324
If the root test configuration does not define `extends` and contains `projects`, Rstack CLI applies automatic inheritance to each inline project that omits its own `extends`. A function-based application or library configuration is resolved once and shared by those projects. String project entries are passed to Rstest unchanged; they load their external configurations independently and do not inherit the current application or library configuration.
160
325
326
+
When using shared configurations, these rules apply after merging all test configurations and use the merged App or Lib configuration. See [Shared test configurations](./testing#shared-test-configurations).
327
+
161
328
> For more guidance on testing, see [Testing](./testing).
162
329
163
330
### `define.lint()`\{#define-lint}
@@ -201,4 +368,4 @@ define.staged({
201
368
});
202
369
```
203
370
204
-
Unlike the other commands, `rs staged` requires a `define.staged()` configuration and reports an error when it is missing.
371
+
`rs staged` requires a staged configuration, provided by `define.staged()`or a shared configuration, and reports an error when it is missing.
Copy file name to clipboardExpand all lines: website/docs/en/guide/testing.mdx
+38Lines changed: 38 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -107,6 +107,44 @@ define.test({
107
107
108
108
For multiple projects, setting `extends` on the root `define.test()` configuration disables automatic inheritance for every project. Setting it on an inline project disables inheritance only for that project.
109
109
110
+
### Shared test configurations
111
+
112
+
[`define.extends()`](./configuration#shared-configurations) shares configurations across tools. The `extends` field inside a test configuration is Rstest's own inheritance option. These operate at different levels.
113
+
114
+
Rstack first merges all shared and project test configurations using `mergeRstestConfig`. It then checks the resulting `extends` and `projects` fields to decide whether automatic inheritance is needed. If it is, Rstack uses the merged App configuration, or the merged Lib configuration when no App configuration is defined.
115
+
116
+
```ts title="shared.ts"
117
+
importtype { RstackConfig } from'rstack';
118
+
119
+
exportconst sharedConfig:RstackConfig= {
120
+
app: {
121
+
resolve: {
122
+
alias: {
123
+
'@': './src',
124
+
},
125
+
},
126
+
},
127
+
test: {
128
+
retry: 2,
129
+
},
130
+
};
131
+
```
132
+
133
+
```ts title="rstack.config.ts"
134
+
import { define } from'rstack';
135
+
import { sharedConfig } from'./shared.ts';
136
+
137
+
define.extends([sharedConfig]);
138
+
139
+
define.test({
140
+
testEnvironment: 'happy-dom',
141
+
});
142
+
```
143
+
144
+
Tests use `retry: 2`, run in happy-dom, and inherit the `@` alias from the shared App configuration. A local `define.app()` call is not required.
145
+
146
+
The same opt-out rules apply to shared configurations: an explicit `extends` in the merged test configuration, including `extends: undefined`, disables automatic inheritance. Inline projects are checked after merging; external string projects still load independently. If no project needs automatic inheritance, Rstack does not evaluate App or Lib configuration functions for it.
147
+
110
148
## Multiple projects
111
149
112
150
Set Rstest's [`projects`](https://rstest.rs/config/test/projects) option to run multiple test configurations together. Entries can be inline projects or strings that Rstest resolves as external projects.
0 commit comments