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
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`.
250
243
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`.
244
+
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 as[Jest](https://jestjs.io). The output file should be referenced in the `main` field. If you have a [dual module setup](esm.md#dual-module-setup) with both ESM and CommonJS builds, it needs to be specified in `exports['.'].require` field of `package.json`.
@@ -58,11 +51,6 @@ The `exports` field is used by Node.js 12+, modern browsers and tools to determi
58
51
59
52
Here, we specify 2 conditions:
60
53
61
-
-`import`: Used when the library is imported with an `import` statement or a dynamic `import()`. It should point to the ESM build.
62
-
-`require`: Used when the library is required with a `require` call. It should point to the CommonJS build.
63
-
64
-
Each condition has 2 fields:
65
-
66
54
-`types`: Used for the TypeScript definitions.
67
55
-`default`: Used for the actual JS code when the library is imported or required.
68
56
@@ -72,6 +60,72 @@ The `./package.json` field is used to point to the library's `package.json` file
72
60
73
61
> Note: Metro enables support for `package.json` exports by default from version [0.82.0](https://github.com/facebook/metro/releases/tag/v0.82.0). In previous versions, experimental support can be enabled by setting the `unstable_enablePackageExports` option to `true` in the [Metro configuration](https://metrobundler.dev/docs/configuration/). If this is not enabled, Metro will use the entrypoint specified in the `main` field.
74
62
63
+
## Dual module setup
64
+
65
+
The previously mentioned setup only works with tools that support ES modules. If you want to support tools that don't support ESM and use the CommonJS module system, you can set up a dual module setup.
66
+
67
+
A dual module setup means that you have 2 builds of your library: one for ESM and one for CommonJS. The ESM build is used by tools that support ES modules, while the CommonJS build is used by tools that don't support ES modules.
68
+
69
+
To set up a dual module setup, you can follow these steps:
70
+
71
+
1. Add the `commonjs` target to the `react-native-builder-bob` field in your `package.json` or `bob.config.js`:
72
+
73
+
```diff
74
+
"react-native-builder-bob": {
75
+
"source": "src",
76
+
"output": "lib",
77
+
"targets": [
78
+
["module", { "esm": true }],
79
+
+ ["commonjs", { "esm": true }]
80
+
"typescript",
81
+
]
82
+
}
83
+
```
84
+
85
+
2. Change the `main` field in your `package.json` to point to the CommonJS build:
86
+
87
+
```diff
88
+
- "main": "./lib/module/index.js",
89
+
+ "main": "./lib/commonjs/index.js",
90
+
```
91
+
92
+
3. Optionally add a `module` field in your `package.json` to point to the ESM build:
93
+
94
+
```diff
95
+
"main": "./lib/commonjs/index.js",
96
+
+ "module": "./lib/module/index.js",
97
+
```
98
+
99
+
The `module` field is a non-standard field that some tools use to determine the ESM entry point.
100
+
101
+
4. Change the `exports` field in your `package.json` to include 2 conditions:
-`import`: Used when the library is imported with an `import` statement or a dynamic `import()`. It will point to the ESM build.
123
+
-`require`: Used when the library is required with a `require` call. It will point to the CommonJS build.
124
+
125
+
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.
126
+
127
+
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.
128
+
75
129
## Guidelines
76
130
77
131
There are still a few things to keep in mind if you want your library to be ESM-compatible:
@@ -100,7 +154,19 @@ There are still a few things to keep in mind if you want your library to be ESM-
100
154
101
155
- 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.
102
156
- 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.
103
-
- 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:
157
+
- If you specify a `react-native` condition in `exports`, make sure that it comes before other conditions. The conditions should be ordered from the most specific to the least specific:
0 commit comments