mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
f940be1caa
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49461 Flow now supports Package Exports 🎉. This means we can delete the compatiblity pattern in each of our build-enabled Node.js packages. This simplifies the internal package structure needed to support Flow while developing from source in the monorepo — no prod impact. Changelog: [Internal] Reviewed By: cipolleschi Differential Revision: D69741143 fbshipit-source-id: 070715cb6beb00eb393186dbf95856ceb87fabef
106 lines
4.1 KiB
Markdown
106 lines
4.1 KiB
Markdown
# 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.
|
|
|
|
#### Limitations/quirks
|
|
|
|
> [!Note]
|
|
> **🚧 Work in progress!** This is not the final state for our monorepo build tooling. Unfortunately, our solution options are narrow due to integration requirements with Meta's codebase.
|
|
|
|
- Running `yarn build` will mutate `package.json` files in place, resulting in a dirty Git working copy.
|
|
- 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"`.
|
|
|
|
## 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.
|
|
|
|
> [!Warning]
|
|
> **Build changes should not be committed**. Currently, `yarn build` will make changes to each `package.json` file, which should not be committed. This is validated in CI.
|
|
|
|
## 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:
|
|
|
|
- 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 every entry point in `"exports"`, remove the `.js` wrapper file and compile from the `.flow.js` source.
|
|
- Rewrite each package `"exports"` target to map to the `dist/` directory location.
|
|
- 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 # "src/index.js" export rewritten to "dist/index.js"
|
|
```
|
|
|
|
**Link**: [Example `dist/` output on npm](https://www.npmjs.com/package/@react-native/dev-middleware/v/0.76.5?activeTab=code).
|