Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ order: 3
---

<Docson tag="master" />

For feature-gated source directories, dependency feature selection, and current build-system defaults, see [Configuration](./build-configuration.mdx). The schema above does not yet describe all native build-system options.
101 changes: 88 additions & 13 deletions apps/docs/markdown-pages/docs/manual/build-configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ order: 2

# Configuration

`rescript.json` is the single, mandatory build meta file needed for `rescript`.
Put each package's build configuration in `rescript.json`.

**The complete configuration schema is [here](./build-configuration-schema.mdx)**. We'll _non-exhaustively_ highlight the important parts in prose below.
Browse the [configuration schema](./build-configuration-schema.mdx) for a reference. The sections below explain common settings and native build-system options.

## name, namespace

Expand Down Expand Up @@ -58,7 +58,7 @@ Your source files need to be specified explicitly (we don't want to accidentally
}
```

You can mark your directories as dev-only (for e.g. tests). These won't be built and exposed to third-parties, or even to other "dev" directories in the same project:
You can mark directories containing tests or development helpers as dev-only. Their modules can use `dev-dependencies`; they aren't compiled when the package is a third-party dependency or when you use [`--prod`](./build-overview.mdx#production-builds):

```json
{
Expand Down Expand Up @@ -87,7 +87,55 @@ 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 `dev-dependencies`.

> The legacy keys `bs-dependencies` and `bs-dev-dependencies` are still accepted but deprecated.
Use package names as strings to build all of a dependency's features. To select only some of its features, use the object form described below.

## features

Features let a package include optional source directories, such as browser-specific modules. Tag a source directory with `feature`, and use the top-level `features` map when one feature should enable others:

```json
{
"name": "optional-ui",
"sources": [
{ "dir": "src" },
{ "dir": "src-dom", "feature": "dom" },
{ "dir": "src-browser", "feature": "browser" }
],
"features": {
"core": [],
"browser": ["dom"]
}
}
```

Without a feature selection, all source directories are built. Use `--features` with `build` or `watch` to select features for the package you're building:

```sh
rescript build --features core
rescript build --features browser
```

The first command builds only the untagged `src` directory. The second also builds `src-browser` and `src-dom`, because `browser` enables `dom`. Feature implications are transitive, and cycles are rejected. Untagged directories are included with every selection; tagged directories require their feature to be active. Nested source directories inherit their parent's feature unless they declare their own.

`--features` takes a comma-separated list, such as `--features core,browser`. An empty selection is rejected. The flag only selects the current package's features; it does not select features for its dependencies.

### Selecting a Dependency's Features

In the consuming package's `rescript.json`, list the features you need from a dependency:

```json
{
"dependencies": [{ "name": "optional-ui", "features": ["browser"] }]
}
```

The dependency's own feature map expands this selection, so `optional-ui` also builds its `dom` feature. The same object form works in `dev-dependencies`.

- A string entry, or an object without `features`, enables all of that dependency's features.
- An explicit `"features": []` builds only its untagged source directories.
- If several packages consume the same dependency, their feature requests are combined. If any consumer requests all features, all are enabled.

Feature selection and `--prod` both apply: a dev-only directory is excluded from a production build even if its feature is enabled.

## js-post-build

Expand Down Expand Up @@ -122,28 +170,41 @@ Controls how the compiler emits JSX and which runtime (if any) it delegates to.
}
```

- `version`: JSX transform version. `4` enables the React 17+ transform and is the current and only supported option in v12.
- `version`: JSX transform version. `4` enables the React 17+ transform and is the current supported version.
- `module`: Override the target module that receives JSX calls. Useful for [generic JSX transforms](./jsx.mdx#generic-jsx-transform-jsx-beyond-react-experimental); omit it when using the built-in React runtime.
- `preserve`: When `true`, the compiler re-emits JSX syntax in the generated JavaScript so bundlers or other tooling can take over the transform later. The regenerated JSX might differ slightly from the original source but stays semantically equivalent. See [Preserve mode](./jsx.mdx#preserve-mode) for details.

All fields are optional; unspecified fields fall back to the defaults mentioned above. Combine them as needed for your project's JSX runtime.

## package-specs

Output to either CommonJS (the default) or JavaScript module. Example:
Choose JavaScript modules (`esmodule`, the default) or CommonJS (`commonjs`). By default, JavaScript is generated alongside the source files. For example:

```json
{
"package-specs": {
"module": "commonjs",
"module": "esmodule",
"in-source": true
}
}
```

- `"module": "commonjs"` generates output as CommonJS format.
- `"module": "esmodule"` generates output as JavaScript module format. Will be default value in next major.
- `"in-source": true` generates output alongside source files. If you omit it, it'll generate the artifacts into `lib/js`. The output directory is not configurable otherwise.
- `"module": "esmodule"` generates JavaScript modules and is the default when `package-specs` is omitted.
- `"module": "commonjs"` generates CommonJS output.
- `"in-source": true` is the default and generates output alongside source files. Set it to `false` to use `lib/es6` for JavaScript modules or `lib/js` for CommonJS.

To emit both formats, use distinct suffixes so the outputs don't overwrite each other:

```json
{
"package-specs": [
{ "module": "esmodule", "suffix": ".mjs" },
{ "module": "commonjs", "suffix": ".cjs" }
]
}
```

A suffix set on an individual package spec overrides the top-level `suffix` setting.

This configuration only applies to you, when you develop the project. When the project is used as a third-party library, the consumer's own `rescript.json` `package-specs` overrides the configuration here, logically.

Expand All @@ -153,7 +214,7 @@ This configuration only applies to you, when you develop the project. When the p

one of the following:

- `".js`
- `".js"`
- `".mjs"`
- `".cjs"`
- `".res.js"`
Expand Down Expand Up @@ -191,8 +252,6 @@ Extra flags to pass to the compiler. For advanced usages.

- `-open ABC` opens the module `ABC` for each file in the project. `ABC` can either be a dependency, namespaced project or local module of the current project.

> The legacy key `bsc-flags` is still accepted but deprecated.

## gentypeconfig

To enable genType, set `"gentypeconfig"` at top level in the project's `rescript.json`.
Expand Down Expand Up @@ -223,6 +282,22 @@ To enable genType, set `"gentypeconfig"` at top level in the project's `rescript

`debug`: Enable debug logs.

## Migrating Older Configurations

Use `rescript.json` for new projects. For compatibility, the build system also reads `bsconfig.json` when `rescript.json` is absent, with a deprecation warning.

Prefer these current configuration keys:

| Legacy key | Current key |
| --------------------- | ------------------ |
| `bs-dependencies` | `dependencies` |
| `bs-dev-dependencies` | `dev-dependencies` |
| `bsc-flags` | `compiler-flags` |

The legacy keys are still accepted with deprecation warnings. Remove `external-stdlib`; it is no longer supported.

Use `esmodule` instead of `es6` or `es6-global`, and `commonjs` instead of `cjs`. The `es6` and `cjs` aliases are still accepted with deprecation warnings; `es6-global` is unsupported.

Comment on lines +285 to +300

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should move this to "Migrate to v13" page?

## Environment Variables

We heavily disrecommend the usage of environment variables, but for certain cases, they're justified.
Expand Down
20 changes: 12 additions & 8 deletions apps/docs/markdown-pages/docs/manual/build-monorepo-setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ order: 5

ReScript 12.0 introduces improved support for native monorepos through the new ["Rewatch"](../../blog/reforging-build-system.mdx) build system. This guide walks you through the setup process.

**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.
Expand Down Expand Up @@ -68,17 +66,19 @@ Therefore, it is recommended to place these settings in the root `rescript.json`

**Settings from different config files:** When Rewatch builds a package within a monorepo setup, it uses these settings from the root rescript.json:

- `"jsx"` (jsx_args, jsx_module_args, jsx_mode_args, jsx_preserve_args)
- `"experimental"` (experimental_features_args)
- `"package-specs"` (used for implementation_args)
- `"suffix"` (used for package output)
- `"jsx"`
- `"experimental-features"`
- `"package-specs"`
- `"suffix"`

These settings come from the package's own rescript.json:

- `"sources"` (determines which files to compile)
- `"dependencies"` (package dependencies)
- `"warnings"` (warning_args)
- `"compiler-flags"` (bsc_flags)
- `"dev-dependencies"`
- `"features"`
- `"warnings"`
- `"compiler-flags"`

When the root package is built, Rewatch will look for the dependencies inside the `my-monorepo/node_modules` folder.
It is expected that `package-1` and `package-2` are available there via a symlink system provided by your node_modules package manager.
Expand Down Expand Up @@ -137,6 +137,10 @@ rescript clean
rescript format
```

Use `rescript build --prod` to exclude dev dependencies and dev-only source directories across the monorepo. The same flag is available on `watch` and `clean`.

To select features of a workspace package when building the root, use a dependency entry such as `{"name": "package-1", "features": ["browser"]}` in the root configuration. `--features` selects the package being built, rather than every package in the monorepo. See [Features](./build-configuration.mdx#features) for the selection rules.

### Building individual packages

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.
Expand Down
25 changes: 24 additions & 1 deletion apps/docs/markdown-pages/docs/manual/build-overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ order: 1

ReScript comes with a fast, native build system through the [`rescript`](https://www.npmjs.com/package/rescript) package.

Every ReScript project needs a build description file, `rescript.json`.
Configure each ReScript package in a `rescript.json` file. See [Build Configuration](./build-configuration.mdx) for the available settings and compatibility with older configuration files.

The current build system was introduced in ReScript 12. It tracks dependencies across packages and schedules only the work affected by a change. See [Reforging the Build System](../../blog/reforging-build-system.mdx) for a deeper look at its architecture.

Expand Down Expand Up @@ -54,10 +54,31 @@ rescript watch

Any new file change will be picked up and the build will re-run.

Watch output distinguishes rebuilds, successful compilations, warnings, and failures. To clear the terminal before each rebuild, use:

```sh
rescript watch --clear-screen
```

Screen clearing only applies to interactive terminal output. You can also run a separate `rescript build` while a watcher is active.

Third-party libraries in `node_modules` aren't watched.

For monorepo setup in ReScript 12+, see [Setting up a monorepo](./build-monorepo-setup.mdx).

### Production Builds

Use `--prod` to exclude `dev-dependencies` and source directories marked with `"type": "dev"`:

```sh
rescript build --prod
rescript watch --prod
```

This filtering applies across the packages being built, including local monorepo packages. Without `--prod`, local packages also compile their dev sources and dev dependencies.

To select optional parts of a package's source tree, see [Features](./build-configuration.mdx#features).

### Incremental Builds

The build system recompiles only files affected by a change. Interface files (`.resi`) can reduce this work further: if an implementation change doesn't alter the corresponding interface, dependent modules don't need to be recompiled. See [Module signatures](./module.mdx#signatures) and [Build Performance](./build-performance.mdx).
Expand All @@ -70,6 +91,8 @@ If you ever get into a stale build for edge-case reasons, use:
rescript clean
```

`rescript clean --prod` applies the same dev-source and dev-dependency exclusions as production builds. Cleaning covers all feature-gated source directories; `clean` does not accept `--features`.

## Format Source Files

Format the project's ReScript files with:
Expand Down