Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/oblador/react-native-esbuild
Fast bundler and dev server for react-native using esbuild
https://github.com/oblador/react-native-esbuild
esbuild react-native
Last synced: about 21 hours ago
JSON representation
Fast bundler and dev server for react-native using esbuild
- Host: GitHub
- URL: https://github.com/oblador/react-native-esbuild
- Owner: oblador
- License: mit
- Created: 2022-05-26T09:11:06.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2023-07-11T07:14:03.000Z (over 1 year ago)
- Last Synced: 2024-11-10T05:42:27.420Z (3 days ago)
- Topics: esbuild, react-native
- Language: JavaScript
- Homepage:
- Size: 710 KB
- Stars: 595
- Watchers: 7
- Forks: 11
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
react-native-esbuild
The fastest bundler for React Native.
## Features
- **Fast** – ~10-50x faster depending on project
- **Tree shaking** – Smaller bundles means faster apps (**21% smaller** for `init` project)
- **Compatible** – Drop-in replacement for metro
- **Configurable** – Support for custom transformers and env variables## Sponsoring
If this library helped you, please consider [sponsoring](https://github.com/sponsors/oblador).
## Installation
```shell
yarn add react-native-esbuild esbuild
```## Configuration
### `react-native` CLI plugin
Make sure `react-native.config.js` exists in the root of your project, and create one if not. Add this library to the `commands` section like this:
```js
// react-native.config.js
const { commands } = require('react-native-esbuild');module.exports = {
commands,
};
```### Optional: Esbuild settings
If you want to customize the [esbuild configuration](https://esbuild.github.io/api/#simple-options), for example by adding your own plugins you may do so with the `createEsbuildCommands` function:
```js
// react-native.config.js
const { createEsbuildCommands, babelPlugin } = require('react-native-esbuild');// See https://esbuild.github.io/api/#simple-options
const commands = createEsbuildCommands((config) => ({
...config,
plugins: config.plugins.concat(
babelPlugin({
filter: /src\/my-babel-components\/.+\.[tj]sx?$/,
})
),
}));module.exports = {
commands,
};
```### Optional: Use esbuild for development
1. Open `package.json` in your editor and locate `scripts` section.
2. Edit `start` script to be `react-native esbuild-start`.
3. Prevent metro from starting automatically by appending `--no-packager` to the `ios`/`android` scripts.```json
{
"scripts": {
"android": "react-native run-android --no-packager",
"ios": "react-native run-ios --no-packager",
"start": "react-native esbuild-start"
}
}
```### Optional: Build production app with esbuild
#### Android
Set `project.ext.react.bundleCommand` to `esbuild-bundle` in `android/app/build.gradle`:
```gradle
// android/app/build.gradle
project.ext.react = [
enableHermes: false,
bundleCommand: "esbuild-bundle",
]
```#### iOS
1. Open your iOS project in Xcode manually or with `xed ios`
2. Select the `Build Phases` tab in your project settings.
3. Expand the `Bundle React Native code and images` section and add `export BUNDLE_COMMAND=esbuild-bundle` so it looks like this:```shell
set -eexport BUNDLE_COMMAND=esbuild-bundle
export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh
```## Usage
This library aims to be a plug-in replacement for the metro equivalent commands with the `esbuild-` prefix.
### `react-native esbuild-start`
| **Argument** | **Description** | **Default** |
| ------------------ | -------------------------------- | ----------- |
| `--port` | Port to listen for http requests | `8081` |
| `--host` | Host to listen for http requests | `127.0.0.1` |
| `--projectRoot` | Path to a custom project root. | _None_ |
| `--reset-cache` | Removes cached files. | _N/A_ |
| `--no-interactive` | Disables interactive mode. | `false` |### `react-native esbuild-bundle`
| **Argument** | **Description** | **Default** |
| -------------------- | --------------------------------------------------------------------------------- | ----------------- |
| `--entry-file` | Path to the root JS file, either absolute or relative to JS root | `index.js` |
| `--platform` | Either `ios` or `android` | `ios` |
| `--dev` | If `false`, warnings are disabled and the bundle is minified | `true` |
| `--minify` | Allows overriding whether bundle is minified otherwise determined by `dev` value. | Opposite of `dev` |
| `--bundle-output` | File name where to store the resulting bundle. | _None_ |
| `--sourcemap-output` | File name where to store the sourcemap file for resulting bundle. | _None_ |
| `--assets-dest` | Directory name where to store assets referenced in the bundle. | _None_ |
| `--reset-cache` | Removes cached files. | _N/A_ |## Troubleshooting
### Flow syntax errors such as `Expected "from" but found "{"`
Esbuild doesn't natively support flow so such syntax needs to be stripped with a plugin. By default any file with `@flow` or `@noflow` pragmas will be stripped from flow, but you may also opt-in to flow stripping for more files by passing a custom flow syntax checker:
```js
// react-native.config.js
const {
createEsbuildCommands,
defaultHasFlowSyntax,
syntaxAwareLoaderPlugin,
} = require('react-native-esbuild');const FLOW_MODULES_WITHOUT_PRAGMA = ['react-native-video', 'rn-fetch-blob'];
const commands = createEsbuildCommands((config, args) => ({
...config,
plugins: config.plugins
.filter((plugin) => plugin.name !== 'syntax-aware-loader')
.concat(
syntaxAwareLoaderPlugin({
filter: /\.([mc]js|[tj]sx?)$/,
cache: args.dev,
hasFlowSyntax: (contents, filePath) =>
defaultHasFlowSyntax(contents, filePath) ||
FLOW_MODULES_WITHOUT_PRAGMA.find((m) =>
filePath.includes(`node_modules/${m}/`)
),
})
),
}));module.exports = {
commands,
};
```## Limitations
### Hermes engine
Hermes doesn't support crucial ES6 features like block level scoping (`let`/`const`) and the team doesn't seem to want to merge this feature mentioning it [being a too big of a change](https://github.com/facebook/hermes/issues/575#issuecomment-902169154) without [having good enough reasons to add it](https://github.com/facebook/hermes/issues/715#issuecomment-1083236894).
### HMR/Fast Refresh
Esbuild [doesn't support Fast Refresh or Hot Module Replacement](https://github.com/evanw/esbuild/issues/151#issuecomment-634441809), but this library supports live reload instead.
## License
MIT © Joel Arvidsson 2022-