UNPKG

11.1 kBMarkdownView Raw
1# react-native-builder-bob
2
3[![Version][version-badge]][package]
4[![Build Status][build-badge]][build]
5[![MIT License][license-badge]][license]
6
7👷‍♂️ Simple CLI to scaffold and build React Native libraries for different targets.
8
9## Features
10
11### Scaffold new projects
12
13If you want to create your own React Native module, scaffolding the project can be a daunting task. Bob can scaffold a new project for you with the following things:
14
15- Simple example modules for Android and iOS which you can build upon
16- [Kotlin](https://kotlinlang.org/) configured for building the module on Android
17- C++ support for native modules on Android and iOS
18- [Expo](https://expo.io/) support for libraries without native code and web support
19- Example React Native app to manually test your modules
20- [ESLint](https://eslint.org/), [Prettier](https://prettier.io/), [TypeScript](https://www.typescriptlang.org/), [Husky](https://github.com/typicode/husky) and [Release It](https://github.com/release-it/release-it) pre-configured
21- Bob pre-configured to compile your files
22- [CircleCI](https://circleci.com/) pre-configured to run tests on the CI
23
24<img src="assets/bob-create.gif" width="500px" height="auto">
25
26### Build your projects
27
28Bob can build code for following targets:
29
30- Generic CommonJS build
31- ES modules build for bundlers such as webpack
32- Flow definitions (copies .js files to .flow files)
33- TypeScript definitions (uses `tsc` to generate declaration files)
34- Android AAR files
35
36## Usage
37
38### Creating a new project
39
40To create new project with Bob, run the following:
41
42```sh
43npx react-native-builder-bob create react-native-awesome-module
44```
45
46This will ask you few questions about your project and generate a new project in a folder named `react-native-awesome-module`.
47
48The difference from [create-react-native-module](https://github.com/brodybits/create-react-native-module) is that the generated project with Bob is very opinionated and configured with additional tools.
49
50### Configuring an existing project
51
52#### Automatic configuration
53
54To automatically configure your project to use Bob, open a Terminal and run:
55
56```js
57npx react-native-builder-bob init
58```
59
60#### Manual configuration
61
62To configure your project manually, follow these steps:
63
641. First, install Bob in your project. Open a Terminal in your project, and run:
65
66 ```sh
67 yarn add --dev react-native-builder-bob
68 ```
69
701. In your `package.json`, specify the targets to build for:
71
72 ```json
73 "react-native-builder-bob": {
74 "source": "src",
75 "output": "lib",
76 "targets": [
77 ["aar", {"reverseJetify": true}],
78 ["commonjs", {"copyFlow": true}],
79 "module",
80 "typescript",
81 ]
82 }
83 ```
84
85 See options below for more details.
86
871. Add `bob` to your `prepare` step:
88
89 ```js
90 "scripts": {
91 "prepare": "bob build"
92 }
93 ```
94
951. Configure the appropriate entry points:
96
97 ```json
98 "main": "lib/commonjs/index.js",
99 "module": "lib/module/index.js",
100 "react-native": "src/index.ts",
101 "types": "lib/typescript/src/index.d.ts",
102 "files": [
103 "lib/",
104 "src/"
105 ]
106 ```
107
108 Make sure to change specify correct files according to the targets you have enabled.
109
110 It's usually good to point to your source code with the `react-native` field to make debugging easier. Metro already supports compiling a lot of new syntaxes including JSX, Flow and TypeScript and it will use this field if present.
111
112 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).
113
1141. Add the output directory to `.gitignore` and `.eslintignore`
115
116 ```gitignore
117 # generated files by bob
118 lib/
119 ```
120
1211. Add the output directory to `jest.modulePathIgnorePatterns` if you use [Jest](https://jestjs.io)
122
123 ```json
124 "modulePathIgnorePatterns": ["<rootDir>/lib/"]
125 ```
126
127And we're done 🎉
128
129## Options
130
131The options can be specified in the `package.json` file under the `react-native-builder-bob` property, or in a `bob.config.js` file in your project directory.
132
133### `source`
134
135The name of the folder with the source code which should be compiled. The folder should include an `index` file.
136
137### `output`
138
139The name of the folder where the compiled files should be output to. It will contain separate folder for each target.
140
141### `targets`
142
143Various targets to build for. The available targets are:
144
145#### `commonjs`
146
147Enable compiling source files with Babel and use commonjs module system.
148
149This is useful for running the code in Node (SSR, tests etc.). The output file should be referenced in the `main` field of `package.json`.
150
151By default, this will compile the code for last 2 versions of modern browsers, as well as JSX. It'll also strip TypeScript and Flow annotations. You can customize the environments to compile for by using a [browserslist config](https://github.com/browserslist/browserslist#config-file). To customize the babel config used, you can pass the [`configFile`](https://babeljs.io/docs/en/options#configfile) or [`babelrc`](https://babeljs.io/docs/en/options#babelrc) options.
152
153If your source code is written in [Flow](http://www.typescriptlang.org/), You can also specify the `copyFlow` option to copy the source files as `.js.flow` to the output folder. If the `main` entry in `package.json` points to the `index` file in the output folder, the flow type checker will pick these files up to use for type definitions.
154
155Example:
156
157```json
158["commonjs", { "babelrc": true, "copyFlow": true }]
159```
160
161#### `module`
162
163Enable compiling source files with Babel and use ES module system. This is essentially same as the `commonjs` target and accepts the same options, but leaves the `import`/`export` statements in your code.
164
165This is useful for bundlers which understand ES modules and can tree-shake. The output file should be referenced in the `module` field of `package.json`.
166
167Example:
168
169```json
170["module", { "babelrc": true, "copyFlow": true }]
171```
172
173#### `typescript`
174
175Enable generating type definitions with `tsc` if your source code is written in [TypeScript](http://www.typescriptlang.org/).
176
177By default, it'll use the `tsconfig.json` file in your project root. If you want to use a different config, you can specify it using the `project` option. Furthermore, the tsc binary will be resolved to ./node_modules/.bin/tsc. Use the `tsc` option to specify a different path.
178
179Example:
180
181```json
182["typescript", { "project": "tsconfig.build.json" }]
183```
184
185#### `aar`
186
187Enable assembling Android AAR files for a library for React Native modules including native code.
188
189It's also possible to convert the AAR with the `reverseJetify` option to use the [Android support Library](https://developer.android.com/topic/libraries/support-library) using the [`jetifier`](https://www.npmjs.com/package/jetifier) package if your package is using [AndroidX](https://developer.android.com/jetpack/androidx). This is useful to publish packages for older projects which haven't migrated to AndroidX.
190
191You can also specify the `androidPath` (defaults to `android`) to specify the `android` directory and `androidBundleName` (defaults to `android.aar`) to customize the name of AAR file.
192Example:
193
194```json
195["aar", { "reverseJetify": true }]
196```
197
198## FAQ
199
200## Why should I compile my project with Bob?
201
202We write our library code in non-standard syntaxes such as JSX, TypeScript etc. as well as proposed syntaxes which aren't part of the standard yet. This means that our code needs to be compiled to be able to run on JavaScript engines.
203
204When using the library in a React Native app, Metro handles compiling the source code. However, it's also possible to use them in other targets such as web, run in Node for tests or SSR etc. So we need to compile the source code for them as well.
205
206Currently, to handle such multiple targets, we need to have multiple babel configs and write a long `babel-cli` command in our `package.json`. We also need to keep the configs in sync between our projects.
207
208Just as an example, this is a command we have in one of the packages: `babel --extensions '.js,.ts,.tsx' --no-babelrc --config-file=./babel.config.publish.js src --ignore '**/__tests__/**' --copy-files --source-maps --delete-dir-on-start --out-dir dist && del-cli 'dist/**/__tests__' && yarn tsc --emitDeclarationOnly`. This isn't all, there's even a separate `babel.config.publish.js` file. And this only works for webpack and Metro, and will fail on Node due to ESM usage.
209
210Bob wraps tools such as `babel` and `typescript` to simplify these common tasks across multiple projects. It's tailored specifically to React Native projects to minimize the configuration required.
211
212### How do I add a react-native library containing native code as a dependency in my library?
213
214If your library depends on another react-native library containing native code, you should do the following:
215
216- Add the native library to `peerDependencies`: This makes sure that there are no conflicts between the version you have specified and the version user has installed (in case they also want to use that library). By deferring the installation to the user, it also makes sure the package manager installs it in correct location and that autolinking can work properly.
217- Add the native library to `devDependencies`: This makes sure that you can use it for tests, and there are no other errors such as type errors due to the missing module.
218- Add the native library to `dependencies` under `example`: This is equivalent to the consumer of the library installing the dependency, and is needed so that this module is also available to the example app.
219
220## Development workflow
221
222To get started with the project, run `yarn` in the root directory to install the required dependencies.
223
224```sh
225yarn
226```
227
228While developing, you can run watch mode to automatically rebuild the changes:
229
230```sh
231yarn watch
232```
233
234To test the CLI locally, you can point to the `bin/bob` executable:
235
236```sh
237../bob/bin/bob create test-project
238```
239
240Before sending a pull rquest, make sure your code passes TypeScript and ESLint. Run the following to verify:
241
242```sh
243yarn typescript
244yarn lint
245```
246
247To fix formatting errors, run the following:
248
249```sh
250yarn lint --fix
251```
252
253## Acknowledgements
254
255Thanks to the authors of these libraries for inspiration:
256
257- [create-react-native-module](https://github.com/brodybits/create-react-native-module)
258- [react-native-webview](https://github.com/react-native-community/react-native-webview)
259
260## LICENSE
261
262MIT
263
264<!-- badges -->
265
266[version-badge]: https://img.shields.io/npm/v/react-native-builder-bob.svg?style=flat-square
267[package]: https://www.npmjs.com/package/react-native-builder-bob
268[build-badge]: https://img.shields.io/circleci/project/github/callstack/react-native-builder-bob/main.svg?style=flat-square
269[build]: https://circleci.com/gh/callstack/react-native-builder-bob
270[license-badge]: https://img.shields.io/npm/l/react-native-builder-bob.svg?style=flat-square
271[license]: https://opensource.org/licenses/MIT