Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/autolinking.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
Autolinking is a mechanism built into CLI that allows adding a dependency with native components for React Native to be as simple as:

```sh
yarn add react-native-firebase
yarn add react-native-webview
```

> Autolinking is a replacement for [`react-native link`](./linking.md) that brings new features (such as ability to easily integrate native dependencies on iOS) and fixes some of the long-standing issues.

## How does it work

React Native CLI provides a [`config`](./commands.md#config) command which grabs all of the configuration for React Native packages installed in the project (by scanning dependenecies in `package.json`) and outputs it in JSON format.
React Native CLI provides a [`config`](./commands.md#config) command which grabs all of the configuration for React Native packages installed in the project (by scanning dependencies in `package.json`) and outputs it in JSON format.

This information is then used by the projects advertised as platforms (with `react-native` being a default project supporting both iOS and Android platforms) that implement their autolinking behavior.

Expand Down
3 changes: 3 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Configuration

TBD
3 changes: 3 additions & 0 deletions docs/dependency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Dependency

TBD
3 changes: 3 additions & 0 deletions docs/platforms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Platforms

TBD
150 changes: 149 additions & 1 deletion docs/plugins.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,151 @@
# Plugins

TBD
Plugin is a JavaScript package that extends built-in React Native CLI features. It can provide an array of additional commands to run or platforms to target.

For example, `react-native-windows` package is a plugin that provides `react-native run-windows` command and `windows` platform.

Details of this particular integration as well as how to provide an additional platform for React Native were described in a [`dedicated section`](./platforms.md) about platforms.

## How does it work?

Except for React Native dependencies, where configuration is implicit, each package needs to have a `react-native.config.js` at the root folder in order to be discovered by the CLI as a plugin.

```js
module.exports = {
commands: [
{
name: 'foo-command',
func: () => console.log('It worked')
}
]
};
```

> Above is an example of a plugin that exports a command named `foo-command` that can be executed with `react-native foo-command` and logs "It worked" and exits.


At the startup, React Native CLI reads configuration from all dependencies listed in `package.json` and reduces them into a single configuration.

At the end, an array of commands concatenated from all plugins is passed on to the CLI to be loaded after built-in commands.

## Command interface

```ts
type Command = {
name: string,
description?: string,
func: (argv: Array<string>, config: ConfigT, args: Object) => ?Promise<void>,
options?: Array<{
name: string,
description?: string,
parse?: (val: string) => any,
default?:
| string
| boolean
| number
| ((config: ConfigT) => string | boolean | number),
}>,
examples?: Array<{
desc: string,
cmd: string,
}>,
};
```

> Note: `ConfigT` is described in [`configuration`](./configuration.md) section

#### `name`

A name that will be used in order to run the command.

Note: If you want your command to accept additional arguments, make sure to include them in the name.

For example, `my-command <argument>` will require an argument to be provided and will throw a validation error otherwise. Alternatively, `my-command [argument]` will accept an argument, but will not throw when run without it. In that case, make sure to check for its presence.

#### `func`

Function that will be run when this command is executed. Receives an array of arguments, in order they were provided, a config object (see [`configuration` section](./configuration.md)) and options, that were passed to your command.

You can return a Promise if your command is async.

All errors are handled by the built-in logger. Prefer throwing instead of implementing your own logging mechanism.

#### `options`

An array of options that your command accepts.

##### `options.name`

Name of the option.

For example, a `--reset-cache` option will result in a `resetCache: true` or `resetCache: false` present in the `options` object - passed to a command function as a last argument.

Just like with a [command name](#name), your option can require a value (e.g. `--port <port>`) or accept an optional one (e.g. `--host [host]`). In this case, you may find [`default`](#optionsdefault) value useful.

##### `options.description`

Optional description of your option. When provided, will be used to output a better help information.

##### `options.parse`

Parsing function that can be used to transform a raw (string) option as passed by the user into a format expected by your function.

##### `options.default`

Default value for the option when not provided. Can be either a primitive value or a function, that receives a configuration and returns a primitive.

Useful when you want to use project settings as default value for your option.

#### `examples`

An array of example usage of the command to be printed to the user.

##### `examples.desc`

String that describes this particular usage.

##### `examples.cmd`

A command with arguments and options (if applicable) that can be run in order to achieve the desired goal.

## Migrating from `rnpm` configuration

The changes are mostly cosmetic so the migration should be pretty straight-forward.

### Changing the configuration

A `plugin` property should be renamed to `commands`.

For example, the following `rnpm` configuration inside `package.json`:
```json
{
"rnpm": {
"plugin": "./path-to-commands.js",
}
}
```
should be moved to a `react-native.config.js`:
```js
module.exports = {
commands: require('./path-to-commands.js')
};
```
provided that `./path-to-commands.js` returns an array of commands.

### Renaming command options

If your command accepts options, rename `command` property of each of them to `name`.

```diff
module.exports = {
name: 'foo',
func: () => console.log('My work'),
options: [
{
- command: '--reset-cache, --resetCache',
+ name: '--reset-cache, --resetCache',
description: 'Removes cached files',
}
]
}
```
4 changes: 2 additions & 2 deletions packages/cli/src/cliEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function printHelpInformation(examples, pkg) {
: [];

let output = [
chalk.bold(`react-native ${cmdName} ${this.usage()}`),
chalk.bold(`react-native ${cmdName}`),
this._description ? `\n${this._description}\n` : '',
...sourceInformation,
`${chalk.bold('Options:')}`,
Expand Down Expand Up @@ -122,7 +122,7 @@ const addCommand = (command: CommandT, ctx: ConfigT) => {

options.forEach(opt =>
cmd.option(
opt.command,
opt.name,
opt.description,
opt.parse || defaultOptParser,
typeof opt.default === 'function' ? opt.default(ctx) : opt.default,
Expand Down
30 changes: 15 additions & 15 deletions packages/cli/src/commands/bundle/bundleCommandLineArgs.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,85 +30,85 @@ export type CommandLineArgs = {

export default [
{
command: '--entry-file <path>',
name: '--entry-file <path>',
description:
'Path to the root JS file, either absolute or relative to JS root',
},
{
command: '--platform [string]',
name: '--platform [string]',
description: 'Either "ios" or "android"',
default: 'ios',
},
{
command: '--transformer [string]',
name: '--transformer [string]',
description: 'Specify a custom transformer to be used',
},
{
command: '--dev [boolean]',
name: '--dev [boolean]',
description: 'If false, warnings are disabled and the bundle is minified',
parse: (val: string) => val !== 'false',
default: true,
},
{
command: '--minify [boolean]',
name: '--minify [boolean]',
description:
'Allows overriding whether bundle is minified. This defaults to ' +
'false if dev is true, and true if dev is false. Disabling minification ' +
'can be useful for speeding up production builds for testing purposes.',
parse: (val: string) => val !== 'false',
},
{
command: '--bundle-output <string>',
name: '--bundle-output <string>',
description:
'File name where to store the resulting bundle, ex. /tmp/groups.bundle',
},
{
command: '--bundle-encoding [string]',
name: '--bundle-encoding [string]',
description:
'Encoding the bundle should be written in (https://nodejs.org/api/buffer.html#buffer_buffer).',
default: 'utf8',
},
{
command: '--max-workers [number]',
name: '--max-workers [number]',
description:
'Specifies the maximum number of workers the worker-pool ' +
'will spawn for transforming files. This defaults to the number of the ' +
'cores available on your machine.',
parse: (workers: string) => Number(workers),
},
{
command: '--sourcemap-output [string]',
name: '--sourcemap-output [string]',
description:
'File name where to store the sourcemap file for resulting bundle, ex. /tmp/groups.map',
},
{
command: '--sourcemap-sources-root [string]',
name: '--sourcemap-sources-root [string]',
description:
"Path to make sourcemap's sources entries relative to, ex. /root/dir",
},
{
command: '--sourcemap-use-absolute-path',
name: '--sourcemap-use-absolute-path',
description: 'Report SourceMapURL using its full path',
default: false,
},
{
command: '--assets-dest [string]',
name: '--assets-dest [string]',
description:
'Directory name where to store assets referenced in the bundle',
},
{
command: '--reset-cache',
name: '--reset-cache',
description: 'Removes cached files',
default: false,
},
{
command: '--read-global-cache',
name: '--read-global-cache',
description:
'Try to fetch transformed JS code from the global cache, if configured.',
default: false,
},
{
command: '--config [string]',
name: '--config [string]',
description: 'Path to the CLI configuration file',
parse: (val: string) => path.resolve(val),
},
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/bundle/ramBundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default {
'builds javascript as a "Random Access Module" bundle for offline use',
func: ramBundle,
options: bundleCommandLineArgs.concat({
command: '--indexed-ram-bundle',
name: '--indexed-ram-bundle',
description:
'Force the "Indexed RAM" bundle file format, even when building for android',
default: false,
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/commands/init/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ export default {
description: 'initialize new React Native project',
options: [
{
command: '--version [string]',
name: '--version [string]',
description: 'Version of RN',
},
{
command: '--template [string]',
name: '--template [string]',
description: 'Custom template',
},
{
command: '--npm',
name: '--npm',
description: 'Force use of npm during initialization',
},
],
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/library/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default {
description: 'generates a native library bridge',
options: [
{
command: '--name <string>',
name: '--name <string>',
description: 'name of the library to generate',
default: null,
},
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/link/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export default {
name: 'link [packageName]',
options: [
{
command: '--platforms [list]',
name: '--platforms [list]',
description:
'If you want to link dependencies only for specific platforms',
parse: (val: string) => val.toLowerCase().split(','),
Expand Down
Loading