-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: add guidelines for ESM support
- Loading branch information
Showing
3 changed files
with
59 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# ESM support | ||
|
||
Libraries created with [`create-react-native-library`](./create.md) are pre-configured to work with ESM (ECMAScript Modules) out of the box. | ||
|
||
You can verify whether ESM support is enabled by checking the configuration for [`react-native-builder-bob`](./build.md) in the `package.json` file of the library: | ||
|
||
```json | ||
"react-native-builder-bob": { | ||
"source": "src", | ||
"output": "lib", | ||
"targets": [ | ||
["commonjs", { "esm" : true }], | ||
["module", { "esm" : true }], | ||
"typescript", | ||
] | ||
} | ||
``` | ||
|
||
The `"esm": true` option enables ESM-compatible output. Here's what it does: | ||
|
||
- It adds the `.js` extension to the import statements in the generated files. | ||
- It creates a `package.json` file in the output directory with the content: `{ "type": "module" }` | ||
|
||
In addition, it's necessary to specify `"moduleResolution": "Bundler"` in your `tsconfig.json` file: | ||
|
||
```json | ||
{ | ||
"compilerOptions": { | ||
"moduleResolution": "Bundler" | ||
} | ||
} | ||
``` | ||
|
||
This means that you don't need to specify the file extension in the import statements. They'll be automatically added when possible during the build process. | ||
|
||
## Guidelines | ||
|
||
There are still a few things to keep in mind if you want your library to be ESM-compatible: | ||
|
||
- Avoid using default exports in your library. Named exports are recommended. Default exports produce a CommonJS module with a `default` property, which will work differently than the ESM build and can cause issues. | ||
- If the library uses platform-specific extensions (e.g., `.ios.js` or `.android.js`), the ESM output will not be compatible with Node.js. It's necessary to omit file extensions from the imports to make platform-specific extensions work, however, Node.js requires file extensions to be present. Bundlers such as Webpack (with [`resolve.fullySpecified: false`](https://webpack.js.org/configuration/module/#resolvefullyspecified)) or Metro can handle this. It's still possible to `require` the CommonJS build directly in Node.js. | ||
- 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. | ||
- 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. | ||
- 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: | ||
|
||
```json | ||
"exports": { | ||
".": { | ||
"types": "./lib/typescript/src/index.d.ts", | ||
"react-native": "./lib/modules/index.native.js", | ||
"import": "./lib/modules/index.js", | ||
"require": "./lib/commonjs/index.js" | ||
} | ||
} | ||
``` |