# scripts/build Shared build setup for the React Native monorepo. ## Overview These scripts form the modern build setup for JavaScript ([Flow](https://flow.org/)) packages in `react-native`, exposed as `yarn build`. > [!Tip] > Generally, React Native maintainers do not need to run `yarn build`, as all packages will run from source during development. Please continue reading if you are adding/removing a package or modifying its build configuration. #### Key info - **Which packages are included?** - Currently, only Node.js-targeting packages are included, configured in `config.js`. - We don't yet include runtime packages (targeting Metro). These are instead transformed in user space via `@react-native/babel-preset`. - **When does the build run?** - Packages are built in CI workflows — both for integration/E2E tests, and before publishing to npm. ## Usage **💡 Reminder**: 99% of the time, there is no need to use `yarn build`, as all packages will run from source during development. Build commands are exposed as npm scripts at the repo root. ```sh # Build all packages yarn build # Build a specific package yarn build dev-middleware # Clean build directories yarn clean ``` Once built, developing in the monorepo should continue to work — now using the compiled version of each package. ## Configuration Monorepo packages must be opted in for build, configured in `config.js` (where build options are also documented). ```js const buildConfig /*: BuildConfig */ = { 'packages': { 'dev-middleware': { emitTypeScriptDefs: true, target: 'node', }, ... ``` #### Required package structure Opting a package into the `yarn build` setup requires a strict file layout. This is done to simplify config and to force consistency across the monorepo. ```sh packages/ example-pkg/ src/ # All source files index.js # Entry point wrapper file (calls babel-register.js) (compiled away) index.flow.js # Entry point implementation in Flow [other files] package.json # Includes "exports" field, ideally only src/index.js ``` Notes: - We make use of "wrapper files" (`.js` → `.js.flow`) for each package entry point, to enable running from source with zero config. To validate these, package entry points must be explicitly defined via `"exports"`. - To minimize complexity, prefer only a single entry of `{".": "src/index.js"}` in `"exports"` for new packages. ## Build behavior Running `yarn build` will compile each package following the below steps, depending on the configured `target` and other build options. - Create a `dist/` directory, replicating each source file under `src/`: - For every `@flow` file, strip Flow annotations using [flow-api-extractor](https://www.npmjs.com/package/flow-api-translator). - For each entry point in `"exports"`, remove the `.js` wrapper file and compile from the `.flow.js` source. - If configured, emit a Flow (`.js.flow`) or TypeScript (`.d.ts`) type definition file per source file, using [flow-api-extractor](https://www.npmjs.com/package/flow-api-translator). Together, this might look like the following: ```sh packages/ example-pkg/ dist/ index.js # Compiled source file (from index.flow.js) index.js.flow # Flow definition file index.d.ts # TypeScript definition file [other transformed files] package.json # "publishConfig" will override exports to "dist/" on publish ``` **Link**: [Example `dist/` output on npm](https://www.npmjs.com/package/@react-native/dev-middleware/v/0.76.5?activeTab=code).