You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -103,15 +103,11 @@ To configure your project manually, follow these steps:
103
103
104
104
-`source`: The path to the source code. It is used by `react-native-builder-bob` to detect the correct output files and provide better error messages.
105
105
-`main`: The entry point for the CommonJS build. This is used by Node - such as tests, SSR etc.
106
-
-`module`: The entry point for the ES module build. This is used by bundlers such as webpack.
107
-
-`types`: The entry point for the TypeScript definitions. This is used by TypeScript to typecheck the code using your library.
108
106
-`files`: The files to include in the package when publishing with `npm`.
109
-
-`exports`: The entry points for tools that support the `exports` field in `package.json` - such as Node.js 12+ & modern browsers. See [the ESM support guide](./esm.md) for more details.
107
+
-`exports`: The entry points for tools that support the `exports` field in `package.json` - such as Node.js 12+, modern browsers and tools. See [the ESM support guide](./esm.md) for more details.
110
108
111
109
Make sure to change specify correct files according to the targets you have enabled.
112
110
113
-
> If you're building TypeScript definition files, also make sure that the `types` field points to a correct path. Depending on the project configuration, the path can be different for you than the example snippet (e.g. `lib/typescript/index.d.ts` if you have only the `src` directory and `rootDir` is not set).
114
-
115
111
5. Add the output directory to `.gitignore` and `.eslintignore`
116
112
117
113
```gitignore
@@ -173,13 +169,15 @@ Example:
173
169
174
170
Various targets to build for. The available targets are:
175
171
176
-
#### `commonjs`
172
+
#### `module`
173
+
174
+
Enable compiling source files with Babel and use ES module system (`import`/`export`).
177
175
178
-
Enable compiling source files with Babel and use CommonJS module system.
176
+
This is useful for modern bundlers that understand ES modules. Bundlers such as [webpack](https://webpack.js.org) can also tree-shake code using ES modules.
179
177
180
-
This is useful for running the code in Node (SSR, tests etc.). The output file should be referenced in the `main` field and `exports['.'].require` (when `esm: true`) field of `package.json`.
178
+
The output file should be referenced in the `module` field and `exports['.'].import` (when `esm: true`) field of `package.json`.
181
179
182
-
By default, the code is compiled to support the last 2 versions of modern browsers. It also strips TypeScript and Flow annotations as well as compiles JSX. You can customize the environments to compile for by using a [browserslist config](https://github.com/browserslist/browserslist#config-file).
180
+
By default, the code is compiled to support the last 2 versions of modern browsers. It also strips TypeScript and Flow annotations as well as compiles JSX code. You can customize the environments to compile for by using a [browserslist config](https://github.com/browserslist/browserslist#config-file).
183
181
184
182
In addition, the following options are supported:
185
183
@@ -243,19 +241,19 @@ Sourcemaps are generated by default alongside the compiled files. You can disabl
243
241
Example:
244
242
245
243
```json
246
-
["commonjs", { "esm": true, "copyFlow": true }]
244
+
["module", { "esm": true }]
247
245
```
248
246
249
-
#### `module`
247
+
#### `commonjs`
250
248
251
-
Enable compiling source files with Babel and use ES module system. This is essentially the same as the `commonjs` target and accepts the same options, but leaves the `import`/`export` statements in your code.
249
+
Enable compiling source files with Babel and use CommonJS module system. This is essentially the same as the `module` target and accepts the same options, but transforms the `import`/`export` statements in your code to `require`/`module.exports`.
252
250
253
-
This is useful for bundlers that understand ES modules and can tree-shake. The output file should be referenced in the `module` fieldand `exports['.'].import` (when `esm: true`) field of `package.json`.
251
+
This is useful for supporting usage of this module with `require` in Node versions older than 20 (it can still be used with `import` for Node.js 12+ if `module` target with `esm` is enabled), and some tools such a [Jest](https://jestjs.io). The output file should be referenced in the `main` field. If you have a dual module setup with both ESM and CommonJS builds, it needs to be specified in `exports['.'].require` field of `package.json`.
The output file should be referenced in the `types` field or `exports['.'].types` field of `package.json`.
284
282
285
-
##### `esm`
286
-
287
-
Setting this option to `true` will output 2 sets of type definitions: one for the CommonJS build and one for the ES module build.
288
-
289
-
See the [ESM support](./esm.md) guide for more details.
290
-
291
283
#### `codegen`
292
284
293
285
Enable generating the [React Native Codegen](https://reactnative.dev/docs/the-new-architecture/what-is-codegen) scaffold code, which is used with the New React Native Architecture.
Copy file name to clipboardexpand all lines: docs/pages/esm.md
+29-10
Original file line number
Diff line number
Diff line change
@@ -9,14 +9,16 @@ You can verify whether ESM support is enabled by checking the configuration for
9
9
"source": "src",
10
10
"output": "lib",
11
11
"targets": [
12
-
["commonjs", { "esm": true }],
13
12
["module", { "esm": true }],
13
+
["commonjs", { "esm": true }],
14
14
"typescript"
15
15
]
16
16
}
17
17
```
18
18
19
-
The `"esm": true` option enables ESM-compatible output by adding the `.js` extension to the import statements in the generated files. For TypeScript, it also generates 2 sets of type definitions: one for the CommonJS build and one for the ES module build.
19
+
The `"esm": true` option enables ESM-compatible output by adding the `.js` extension to the import statements in the generated files. This is necessary if you want to be able to import the library on Node.js or in a bundler that supports ESM, with some caveats. See the [Guidelines](#guidelines) section for more information.
20
+
21
+
For TypeScript, it also generates 2 sets of type definitions if the [`commonjs`](build.md#commonjs) target is also enabled: one for the CommonJS build and one for the ES module build.
20
22
21
23
It's recommended to specify `"moduleResolution": "bundler"` and `"resolvePackageJsonImports": false` in your `tsconfig.json` file to match [Metro's behavior](https://reactnative.dev/blog/2023/06/21/package-exports-support#enabling-package-exports-beta):
22
24
@@ -36,7 +38,6 @@ To make use of the output files, ensure that your `package.json` file contains t
The `main`, `module` and `types` fields are for legacy setups that don't support the `exports` field. See the [Manual configuration](build.md#manual-configuration) guide for more information about those fields.
56
+
The `main` field is for tools that don't support the `exports` field (e.g. [Metro](https://metrobundler.dev/)). The `module` field is a non-standard field that some tools use to determine the ESM entry point.
55
57
56
-
The `exports` field is used by modern tools and bundlers to determine the correct entry point. Here, we specify 2 conditions:
58
+
The `exports` field is used by Node.js 12+, modern browsers and tools to determine the correct entry point. The entrypoint is specified in the `.` key and will be used when the library is imported or required directly (e.g. `import 'my-library'` or `require('my-library')`).
59
+
60
+
Here, we specify 2 conditions:
57
61
58
62
-`import`: Used when the library is imported with an `import` statement or a dynamic `import()`. It should point to the ESM build.
59
63
-`require`: Used when the library is required with a `require` call. It should point to the CommonJS build.
60
64
61
-
Each condition has a `types` field - necessary for TypeScript to provide the appropriate definitions for the module system. The type definitions have slightly different semantics for CommonJS and ESM, so it's important to specify them separately.
65
+
Each condition has 2 fields:
62
66
63
-
The `default` field is the fallback entry point for both conditions. It's used for the actual JS code when the library is imported or required.
67
+
-`types`: Used for the TypeScript definitions.
68
+
-`default`: Used for the actual JS code when the library is imported or required.
64
69
65
70
You can also specify additional conditions for different scenarios, such as `react-native`, `browser`, `production`, `development` etc. Note that support for these conditions depends on the tooling you're using.
66
71
72
+
The `./package.json` field is used to point to the library's `package.json` file. It's necessary for tools that may need to read the `package.json` file directly (e.g. [React Native Codegen](https://reactnative.dev/docs/the-new-architecture/what-is-codegen)).
73
+
67
74
## Guidelines
68
75
69
76
There are still a few things to keep in mind if you want your library to be ESM-compatible:
@@ -79,9 +86,20 @@ There are still a few things to keep in mind if you want your library to be ESM-
79
86
const { foo } =require('my-library');
80
87
```
81
88
89
+
Alternatively, if you want to be able to use the library in Node.js with `import` syntax, you can use `require` to import code with platform-specific extensions in your library:
90
+
91
+
```js
92
+
// will import `foo.native.js`, `foo.ios.js`, `foo.js` etc.
93
+
const { foo } =require('./foo');
94
+
```
95
+
96
+
Make sure to have a file without any platform-specific extensions that will be loaded by Node.js.
97
+
98
+
Also note that if your module (e.g. `foo.js` in this case) contains ESM syntax, it will only work on Node.js 20 or newer.
99
+
82
100
- Avoid using `.cjs`, `.mjs`, `.cts` or `.mts` extensions. Metro always requires file extensions in import statements when using `.cjs` or `.mjs` which breaks platform-specific extension resolution.
83
101
- Avoid using `"moduleResolution": "node16"` or `"moduleResolution": "nodenext"` in your `tsconfig.json` file. They require file extensions in import statements which breaks platform-specific extension resolution.
84
-
- If you specify a `react-native` condition in `exports`, make sure that it comes before `import` or `require`. The conditions should be ordered from the most specific to the least specific:
102
+
- If you specify a `react-native` condition in `exports`, make sure that it comes before the `default` condition. The conditions should be ordered from the most specific to the least specific:
85
103
86
104
```json
87
105
"exports": {
@@ -96,6 +114,7 @@ There are still a few things to keep in mind if you want your library to be ESM-
0 commit comments