Skip to content

Commit 59cf27c

Browse files
authored
Add initial guide on monorepos (#1074)
* Add initial guide on monorepos * Remove pinned dependencies * Correct rewatch guide
1 parent c94d29a commit 59cf27c

File tree

4 files changed

+215
-114
lines changed

4 files changed

+215
-114
lines changed

data/sidebar_manual_v1200.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"build-configuration",
5454
"build-configuration-schema",
5555
"build-external-stdlib",
56-
"build-pinned-dependencies",
56+
"build-monorepo-setup",
5757
"interop-with-js-build-systems",
5858
"build-performance",
5959
"warning-numbers"

pages/docs/manual/v12.0.0/build-configuration.mdx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,6 @@ List of ReScript dependencies. Just like `package.json`'s dependencies, they'll
8787

8888
Note that only sources marked with `"type":"dev"` will be able to resolve modules from `bs-dev-dependencies`.
8989

90-
## pinned-dependencies
91-
92-
**Since 8.4**: List of pinned dependencies. A pinned dependency will always be rebuilt whenever you build a toplevel package (e.g. your main app) with `rescript`.
93-
94-
This is useful for working on multiple independent ReScript packages simultaneously. More usage details can be found in our dedicated [pinned dependencies](./build-pinned-dependencies) page.
95-
9690
## external-stdlib
9791

9892
**Since 9.0**: This setting allows depending on an externally built stdlib package (instead of a locally built stdlib runtime). Useful for shipping packages that are only consumed in JS or TS without any dependencies to the ReScript development toolchain.
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
---
2+
title: "Setting up a monorepo"
3+
metaTitle: "Setting up a monorepo"
4+
description: "Setting up a monorepo"
5+
canonical: "/docs/manual/v12.0.0/build-monorepo-setup"
6+
---
7+
8+
# Setting up a monorepo with ReScript
9+
10+
**Since 12.0**
11+
12+
> A monorepo is a single repository containing multiple separate projects, with clear relationships between them.
13+
14+
ReScript 12.0 introduces improved support for native monorepos through the new "Rewatch" build system. This guide walks you through the setup process.
15+
16+
**Note:** This feature requires the new build system and is **not compatible** with `rescript-legacy`.
17+
18+
## Project Structure
19+
20+
A ReScript monorepo requires a `rescript.json` file at the repository root, plus a `rescript.json` file in each sub-project directory.
21+
Basically, the monorepo contains a root package that manages all local dependencies. Building the root package will build all its dependencies.
22+
23+
**Important:** You also need a node_modules monorepo setup with symlinks. In practice, if you want a ReScript monorepo, you will also need an npm/yarn/pnpm/bun monorepo.
24+
25+
A typical structure looks like this:
26+
27+
```
28+
my-monorepo/
29+
├── rescript.json
30+
├── package.json
31+
├── node_modules/
32+
│ ├── package-1/ # symlinked
33+
│ ├── package-2/ # symlinked
34+
├── packages/
35+
│ ├── package-1/
36+
│ │ ├── rescript.json
37+
│ │ ├── package.json
38+
│ │ ├── src/
39+
│ ├── package-2/
40+
│ │ ├── rescript.json
41+
│ │ ├── package.json
42+
│ │ ├── src/
43+
│ ├── ...
44+
```
45+
46+
## Root `rescript.json` Configuration
47+
48+
The root `rescript.json` manages the monorepo by listing its packages.
49+
50+
```json
51+
{
52+
"name": "my-monorepo",
53+
"dependencies": ["package-1", "package-2"],
54+
"package-specs": {
55+
"module": "esmodule",
56+
"in-source": true
57+
},
58+
"suffix": ".res.mjs",
59+
"bsc-flags": []
60+
}
61+
```
62+
63+
The `"dependencies"` array lists the names of your packages, which must match the `"name"` fields in their respective sub-rescript.json files.
64+
When you build a package in ReScript, it will use the `"package-specs"` and `"suffix"` settings from the root package.
65+
Therefore, it is recommended to place these settings in the root `rescript.json` file and avoid specifying them in local package `rescript.json` files.
66+
67+
**Settings from different config files:** When Rewatch builds a package within a monorepo setup, it uses these settings from the root rescript.json:
68+
69+
- `"jsx"` (jsx_args, jsx_module_args, jsx_mode_args, jsx_preserve_args)
70+
- `"experimental"` (experimental_features_args)
71+
- `"package-specs"` (used for implementation_args)
72+
- `"suffix"` (used for package output)
73+
74+
These settings come from the package's own rescript.json:
75+
76+
- `"sources"` (determines which files to compile)
77+
- `"dependencies"` (package dependencies)
78+
- `"warnings"` (warning_args)
79+
- `"compiler-flags"` (bsc_flags)
80+
81+
When the root package is built, Rewatch will look for the dependencies inside the `my-monorepo/node_modules` folder.
82+
It is expected that `package-1` and `package-2` are available there via a symlink system provided by your node_modules package manager.
83+
84+
Note that your root rescript.json is allowed to have a `"sources"` setting.
85+
These files will be compiled as expected.
86+
87+
## Package `rescript.json` Configuration
88+
89+
Each nested rescript.json sets up a specific package.
90+
91+
`packages/package-1/rescript.json`:
92+
93+
```json
94+
{
95+
"name": "package-1",
96+
"sources": ["src"],
97+
"dependencies": [],
98+
"compiler-flags": ["-open Foobar"]
99+
}
100+
```
101+
102+
`packages/package-2/rescript.json`:
103+
104+
```json
105+
{
106+
"name": "package-2",
107+
"sources": ["src"],
108+
"dependencies": ["package-1"],
109+
"warnings": {
110+
"number": "-27"
111+
}
112+
}
113+
```
114+
115+
In `package-1`, we show how to use special compiler flags.
116+
In `package-2`, we show how to disable warning 27 (unused variable).
117+
In both cases, the settings only apply to the package where they are specified.
118+
Defining these in the root rescript.json will not affect the packages.
119+
There is no inheritance system.
120+
121+
Also note the dependencies array in `package-2`, which allows that package to depend on `package-1` within the monorepo.
122+
123+
## Building the monorepo
124+
125+
From the root directory, you can run all ReScript commands:
126+
127+
```bash
128+
# Build all packages
129+
rescript build
130+
131+
# Clean all packages
132+
rescript clean
133+
134+
# Format all packages
135+
rescript format
136+
```
137+
138+
### Building individual packages
139+
140+
You can also run ReScript commands on individual packages instead of the entire monorepo. This is useful when you only want to work on one package.
141+
142+
```bash
143+
# Build from the package directory
144+
cd packages/package-3
145+
rescript build
146+
rescript clean
147+
rescript format
148+
149+
# Or run from the root directory
150+
rescript build packages/package-3
151+
rescript clean packages/package-3
152+
rescript format packages/package-3
153+
```
154+
155+
When building a single package, ReScript will use the settings from the root rescript.json as explained in the [Root rescript.json Configuration](#root-rescriptjson-configuration) section above.
156+
157+
### Building without a root rescript.json
158+
159+
If your node_modules monorepo is set up with symlinks, you can build packages even without a root rescript.json:
160+
161+
```
162+
my-monorepo/
163+
├──node_modules/
164+
│ ├── package-1/ # symlinked
165+
│ ├── package-2/ # symlinked
166+
├── package.json
167+
├── packages/
168+
│ ├── package-1/
169+
│ │ ├── rescript.json
170+
│ │ ├── package.json
171+
│ │ ├── src/
172+
│ ├── package-2/
173+
│ │ ├── rescript.json
174+
│ │ ├── package.json
175+
│ │ ├── src/
176+
│ ├── ...
177+
```
178+
179+
Building `package-2` (which depends on `package-1`) will search up the folder structure to find `package-1`.
180+
181+
Example:
182+
183+
```bash
184+
rescript build ./packages/package-2
185+
```
186+
187+
Internally, Rewatch will look for:
188+
189+
- 🔴 `my-monorepo/packages/package-2/node_modules/package-1`
190+
- 🔴 `my-monorepo/packages/node_modules/package-1`
191+
-`my-monorepo/node_modules/package-1`
192+
193+
This only happens as a last resort if `package-1` is not listed as a (dev-)dependency in a parent `rescript.json`.
194+
195+
## Troubleshooting
196+
197+
If you're having issues with your monorepo setup, you can use the `-v` flag during build to see what Rewatch detected as the project context:
198+
199+
```bash
200+
rescript build -v
201+
```
202+
203+
This will show you detailed information about how Rewatch is interpreting your project structure and which configuration files it's using.
204+
205+
## Recommendation
206+
207+
**The ReScript team strongly recommends using a root `rescript.json` file when setting up monorepos.** While it's technically possible to build packages without one (as shown in the section above), having a root configuration file provides several benefits:
208+
209+
- **Consistent settings** across all packages (jsx, experimental features, package-specs, suffix)
210+
- **Simplified dependency management** through the root dependencies array
211+
- **Better developer experience** with unified build commands from the root
212+
- **Easier maintenance** and configuration updates across the entire monorepo
213+
214+
The root `rescript.json` approach is the intended and supported way to work with ReScript monorepos.

pages/docs/manual/v12.0.0/build-pinned-dependencies.mdx

Lines changed: 0 additions & 107 deletions
This file was deleted.

0 commit comments

Comments
 (0)