From 90a449809cd83e2499bdd377538bd77d0fd51167 Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 21 Jul 2025 13:22:05 +0200 Subject: [PATCH 1/2] Add initial guide on monorepos --- data/sidebar_manual_v1200.json | 1 + .../manual/v12.0.0/build-monorepo-setup.mdx | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 pages/docs/manual/v12.0.0/build-monorepo-setup.mdx diff --git a/data/sidebar_manual_v1200.json b/data/sidebar_manual_v1200.json index 5269c67c9..a557f0d45 100644 --- a/data/sidebar_manual_v1200.json +++ b/data/sidebar_manual_v1200.json @@ -63,6 +63,7 @@ "build-configuration-schema", "build-external-stdlib", "build-pinned-dependencies", + "build-monorepo-setup", "interop-with-js-build-systems", "build-performance", "warning-numbers" diff --git a/pages/docs/manual/v12.0.0/build-monorepo-setup.mdx b/pages/docs/manual/v12.0.0/build-monorepo-setup.mdx new file mode 100644 index 000000000..11b8d51a6 --- /dev/null +++ b/pages/docs/manual/v12.0.0/build-monorepo-setup.mdx @@ -0,0 +1,102 @@ +--- +title: "Setting up a monorepo" +metaTitle: "Setting up a monorepo" +description: "Setting up a monorepo" +canonical: "/docs/manual/v12.0.0/build-monorepo-setup" +--- + +# Setting up a monorepo with ReScript + +**Since 12.0** + +> A monorepo is a single repository containing multiple distinct projects, with well-defined relationships. + +ReScript 12.0 introduces native monorepo support via the new "Rewatch" build system. This guide shows you how to set it up. + +**Note:** This feature requires the new build system and is **not compatible** with `rescript legacy`. + +## Project Structure + +A ReScript monorepo requires a `rescript.json` file at the repository root, plus a `rescript.json` file in each sub-project directory. + +A typical structure looks like this: + +``` +my-monorepo/ +├── rescript.json +├── packages/ +│ ├── package-1/ +│ │ ├── rescript.json +│ │ ├── src/ +│ ├── package-2/ +│ │ ├── rescript.json +│ │ ├── src/ +│ ├── ... +``` + +## Root `rescript.json` Configuration + +The root `rescript.json` orchestrates the monorepo by listing its constituent packages. + +```json +{ + "name": "my-monorepo", + "dependencies": [ + "package-1", + "package-2" + ], + "package-specs": { + "module": "esmodule", + "in-source": true + }, + "suffix": ".res.mjs", + "bsc-flags": [] +} +``` + +The "dependencies" array specifies the names of your packages, which must correspond to the "name" fields in their respective sub-rescript.json files. + +Inheritance: By default, all settings defined in the root rescript.json are inherited by the individual packages. + +## Package `rescript.json` Configuration + +Each nested rescript.json configures a specific package. + +`packages/package-1/rescript.json`: + +```json +{ + "name": "package-1", + "sources": ["src"], + "dependencies": [] +} +``` + +`packages/package-2/rescript.json`: + +```json +{ + "name": "package-2", + "sources": ["src"], + "dependencies": ["package-1"], + "warnings": { + "number":"-27" + } +} +``` + +In `package-2`, we demonstrate overriding a root setting by specifically disabling warning 27 (unused variable) for this package only. + +Note the dependencies array here, which allows one package to depend on another within the monorepo. + +## Building the monorepo + +From the root directory, build all packages with: + +```bash +rescript build +``` + +Note on package.json: ReScript's build system manages the compilation of your ReScript code. +It does not directly interact with your `package.json` setup or `node_modules`. +You might need a separate monorepo tool (like Yarn Workspaces, pnpm, or npm Workspaces) to manage your JavaScript/Node.js dependencies across packages if applicable. \ No newline at end of file From a845d08045acbdc6f9262937c70761cbeaa46ea2 Mon Sep 17 00:00:00 2001 From: nojaf Date: Wed, 23 Jul 2025 08:28:12 +0200 Subject: [PATCH 2/2] Remove pinned dependencies --- data/sidebar_manual_v1200.json | 1 - .../manual/v12.0.0/build-configuration.mdx | 6 - .../v12.0.0/build-pinned-dependencies.mdx | 105 ------------------ 3 files changed, 112 deletions(-) delete mode 100644 pages/docs/manual/v12.0.0/build-pinned-dependencies.mdx diff --git a/data/sidebar_manual_v1200.json b/data/sidebar_manual_v1200.json index a557f0d45..dd7af60ba 100644 --- a/data/sidebar_manual_v1200.json +++ b/data/sidebar_manual_v1200.json @@ -62,7 +62,6 @@ "build-configuration", "build-configuration-schema", "build-external-stdlib", - "build-pinned-dependencies", "build-monorepo-setup", "interop-with-js-build-systems", "build-performance", diff --git a/pages/docs/manual/v12.0.0/build-configuration.mdx b/pages/docs/manual/v12.0.0/build-configuration.mdx index d7c7dfaa6..8d4240299 100644 --- a/pages/docs/manual/v12.0.0/build-configuration.mdx +++ b/pages/docs/manual/v12.0.0/build-configuration.mdx @@ -85,12 +85,6 @@ List of ReScript dependencies. Just like `package.json`'s dependencies, they'll Note that only sources marked with `"type":"dev"` will be able to resolve modules from `bs-dev-dependencies`. -## pinned-dependencies - -**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`. - -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. - ## external-stdlib **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. diff --git a/pages/docs/manual/v12.0.0/build-pinned-dependencies.mdx b/pages/docs/manual/v12.0.0/build-pinned-dependencies.mdx deleted file mode 100644 index 405ac7f7c..000000000 --- a/pages/docs/manual/v12.0.0/build-pinned-dependencies.mdx +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: "Pinned Dependencies" -metaTitle: "Pinned Dependencies" -description: "Handling multiple packages within one ReScript project with pinned dependencies" -canonical: "/docs/manual/v12.0.0/build-pinned-dependencies" ---- - -# Pinned Dependencies - -Usually we'd recommend to use ReScript in a single-codebase style by using one `rescript.json` file for your whole codebase. - -There are scenarios where you still want to connect and build multiple independent ReScript packages for one main project though (`npm` workspaces-like "monorepos"). This is where `pinned-dependencies` come into play. - -## Package Types - -Before we go into detail, let's first explain all the different package types recognized by the build system: - -- Toplevel (this is usually the final app you are building, which has dependencies to other packages) -- Pinned dependencies (these are your local packages that should always rebuild when you build your toplevel, those should be listed in `bs-dependencies` and `pinned-dependencies`) -- Normal dependencies (these are packages that are consumed from npm and listed via `bs-dependencies`) - -Whenever a package is being built (`rescript build`), the build system will build the toplevel package with its pinned-dependencies. So any changes made in a pinned dependency will automatically be reflected in the final app. - -## Build System Package Rules - -The build system respects the following rules for each package type: - -**Toplevel** - -- Warnings reported -- Warn-error respected -- Builds dev dependencies -- Builds pinned dependencies -- Runs custom rules -- Package-specs like JavaScript module or CommonJS overrides all its dependencies - -**Pinned dependencies** - -- Warnings reported -- Warn-error respected -- Ignores pinned dependencies -- Builds dev dependencies -- Runs custom rules - -**Normal dependencies** - -- Warnings, warn-error ignored -- Ignores dev directories -- Ignores pinned dependencies -- Ignores custom generator rules - -So with that knowledge in mind, let's dive into some more concrete examples to see our pinned dependencies in action. - -## Examples - -### Yarn workspaces - -Let's assume we have a codebase like this: - -``` -myproject/ - app/ - - src/App.res - - rescript.json - common/ - - src/Header.res - - rescript.json - myplugin/ - - src/MyPlugin.res - - rescript.json - package.json -``` - -Our `package.json` file within our codebase root would look like this: - -```json -{ - "name": "myproject", - "private": true, - "workspaces": { - "packages": ["app", "common", "myplugin"] - } -} -``` - -Our `app` folder would be our toplevel package, consuming our `common` and `myplugin` packages as `pinned-dependencies`. The configuration for `app/rescript.json` looks like this: - -```json -{ - "name": "app", - "version": "1.0.0", - "sources": { - "dir": "src", - "subdirs": true - }, - /* ... */ - "bs-dependencies": ["common", "myplugin"], - "pinned-dependencies": ["common", "myplugin"] - /* ... */ -} -``` - -Now, whenever we are running `rescript build` within our `app` package, the compiler would always rebuild any changes within its pinned dependencies as well. - -**Important:** ReScript will not rebuild any `pinned-dependencies` in watch mode! This is due to the complexity of file watching, so you'd need to set up your own file-watcher process that runs `rescript build` on specific file changes.