diff --git a/docs/configuration.md b/docs/configuration.md index 79de38b76..acff3c023 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,3 +1,15 @@ # Configuration -TBD +React Native CLI has a configuration mechanism that allows changing its behavior and providing additional features. + +> Note: Configuring CLI used to be possible via `rn-cli.config.js` (that has been renamed to `metro.config.js`) and never documented `rnpm` entry on the `package.json`. We have provided migration guides where possible. + +React Native CLI can be configured by creating a `react-native.config.js` at the root of the project. Depending on a type of a package, this file can have a different set properties. + +Check the documentation for: +- [projects](./projects.md) +- [dependencies](./dependencies.md) +- [platforms](./platforms.md) +- [plugins](./plugins.md) + +to learn more about different types of configuration and features available. diff --git a/docs/dependencies.md b/docs/dependencies.md new file mode 100644 index 000000000..bfd20cbdb --- /dev/null +++ b/docs/dependencies.md @@ -0,0 +1,154 @@ +# Dependency + +A dependency is a JavaScript package that is listed under dependencies present in the project's `package.json`. It can also contain native, platform-specific files that should be linked. + +For example, `lodash` is a dependency that doesn't have any native code to link. On the other hand, `react-native-vector-icons` is a dependency that contains not only native code, but also font assets that the CLI should link. + +By default, CLI analyses the folder structure inside the dependency and looks for assets and native files to link. This simple heuristic works in most of the cases. + +At the same time, a dependency can explicitly set its configuration in case CLI cannot infer it properly. A dependency can also define additional settings, such as a script to run after linking, in order to support some advanced use-cases. + +## How does it work? + +A dependency can define the following `react-native.config.js` at the root: + +```js +module.exports = { + dependency: { + platforms: { + ios: { + project: './Custom.xcodeproj' + } + } + assets: ['./assets'] + } +}; +``` + +> The above configuration informs CLI of the additional assets to link and about a custom project location. + +## Dependency interface + +The following type describes the configuration of a dependency that can be set under `dependency` key inside `react-native.config.js`. + +```ts +type DependencyConfigT = { + platforms: { + [key: string]: any, + }, + assets: string[], + hooks: { + [key: string]: string, + } +}; +``` + +> Note: This interface is subject to breaking changes. We may consider renaming some keys to simplify the configuration further. If you are going to use it, be prepared to update before we ship a stable 0.60.0 release. + +### platforms + +A map of specific settings that can be set per platform. The exact shape is always defined by the package that provides given platform. + +In most cases, as a library author, you should not need to define any of these. + +The following settings are available on iOS and Android: + +```ts +type DependencyParamsIOST = { + project?: string, + sharedLibraries?: string[], +}; + +type DependencyParamsAndroidT = { + sourceDir?: string, + manifestPath?: string, + packageImportPath?: string, + packageInstance?: string +}; +``` + +#### platforms.ios.project + +Custom path to `.xcodeproj` + +#### platforms.ios.sharedLibraries + +An array of shared iOS libraries to link with the dependency. E.g. `libc++`. This is mostly a requirement of the native code that a dependency ships with. + +#### platforms.android.sourceDir + +Path to a folder with source files. + +#### platforms.android.manifestPath + +Path to a custom `AndroidManifest.xml` + +#### platforms.android.packageImportPath + +Custom package import. For example: `import com.acme.AwesomePackage;`. + +#### platforms.android.packageInstance + +Custom syntax to instantiate a package. By default, it's a `new AwesomePackage()`. It can be useful when your package requires additional arguments while initializing. + +For settings applicable on other platforms, please consult their respective documentation. + +### assets + +An array of assets folders to glob for files to link. + +### hooks + +A map where key is the name of a hook and value is the path to a file to execute. + +For example, `link` command supports `prelink` and `postlink` hooks to run before and after linking is done. + +These are the only ones supported by CLI at the moment. Depending on the packages used in your project, you may find other hooks supported to. + +> Note: This has nothing to do with React Hooks. + +## Migrating from `rnpm` configuration + +The changes are mostly cosmetic so the migration should be pretty straight-forward. + +> Note: We read `rnpm` configuration to remain backwards-compatible. Dependency maintainers should update their configuration in the nearest future. + +### Changing the configuration + +Properties were renamed. Look at the following example for the differences. + +```json +{ + "rnpm": { + "ios": {}, + "android": {}, + "assets": ["./path-to-assets"], + "hooks": { + "prelink": "./path-to-a-postlink-hook" + } + } +} +``` + +to a `react-native.config.js` + +```js +module.exports = { + dependency: { + platforms: { + ios: {}, + android: {}, + }, + assets: ['./path-to-assets'], + hooks: { + prelink: './path-to-a-postlink-hook' + } + } +}; +``` + +### Asking for params while linking has been removed + +If your library needs it, do not upgrade over to the new config format. + +If you want to ask users for additional settings, consider setting a custom `postlink` hook, just like [`react-native-code-push`](https://github.com/Microsoft/react-native-code-push/blob/master/package.json#L53). diff --git a/docs/dependency.md b/docs/dependency.md deleted file mode 100644 index 4c02d82b9..000000000 --- a/docs/dependency.md +++ /dev/null @@ -1,3 +0,0 @@ -# Dependency - -TBD diff --git a/docs/platforms.md b/docs/platforms.md index 6d01cf086..23f6c2d0b 100644 --- a/docs/platforms.md +++ b/docs/platforms.md @@ -57,7 +57,7 @@ type PlatformConfig = { ### projectConfig -Returns a project configuration for a given platform. This is later used inside `linkConfig` to perform linking and unlinking. +Returns a project configuration for a given platform or `null`, when no project found. This is later used inside `linkConfig` to perform linking and unlinking. First argument is a root folder where the project is located. @@ -72,6 +72,36 @@ module.exports = { > Note: You may find this useful in order to alter the default behavior of your function. For example, on iOS, we find an `.xcodeproj` by globbing the project files and taking the first match. There's a possibility we pick the wrong one in case the project has multiple `.xcodeproj` files. In order to support this use-case, we have allowed users to define an exact path to an iOS project in order to overwrite our `glob` mechanism. +On Android and iOS, this function returns: + +```ts +type ProjectConfigIOST = { + sourceDir: string, + folder: string, + pbxprojPath: string, + podfile: null, + podspec: null, + projectPath: string, + projectName: string, + libraryFolder: string, + sharedLibraries: Array, + plist: Array, +}; + +type ProjectConfigAndroidT = { + sourceDir: string, + isFlat: boolean, + folder: string, + stringsPath: string, + manifestPath: string, + buildGradlePath: string, + settingsGradlePath: string, + assetsPath: string, + mainFilePath: string, + packageName: string, +}; +``` + We suggest performing all side-effects inside this function (such as resolving paths to native files) and making `linkConfig` functions pure, operating on provided data. ### dependencyConfig @@ -89,6 +119,20 @@ module.exports = { } ``` +On Android and iOS, this function returns: + +```ts +type DependencyConfigIOST = ProjectConfigIOST; + +type DependencyConfigAndroidT = { + sourceDir: string, + folder: string, + manifest: Manifest, + packageImportPath: string, + packageInstance: string, +}; +``` + ### linkConfig Returns an object with utilities that are run by the CLI while linking. @@ -153,7 +197,7 @@ module.exports = { > The above configuration is taken from `react-native-windows` and adds support for `windows` platform. -### Changing platform configuration for a dependency +### Changing platform configuration for a [`dependency`](./dependencies.md) Platform keys are now under `dependency.platforms`. @@ -185,7 +229,7 @@ module.exports = { > The above is a configuration of a dependency that explicitly sets a path to `.xcodeproj`. -### Changing platform configuration for a project +### Changing platform configuration for a [`project`](./projects.md) Platform keys are now under `project.platforms`. diff --git a/docs/projects.md b/docs/projects.md new file mode 100644 index 000000000..1a2a681ff --- /dev/null +++ b/docs/projects.md @@ -0,0 +1,155 @@ +# Project + +A project is an app that contains React code and has a dependency on `react-native`. + +Projects can provide additional properties to alter the CLI behavior, such as custom location of React Native files (this is useful when running RNTester from source) or a non-standard location of a project (useful when working in a brownfield app). + +## How does it work? + +A project can define a `react-native.config.js` at the root with custom configuration to be picked up by the CLI. + +For example, below configuration informs CLI of the additional assets to link and about a custom project location. + +```js +module.exports = { + project: { + ios: { + project: './CustomProject.xcodeproj' + } + }, + assets: ['./assets'] +}; +``` + +You can check all available options below. + +## Project interface + +```ts +type ProjectConfigT = { + reactNativePath: ?string, + project: { + android?: ProjectParamsAndroidT, + ios?: ProjectParamsIOST, + [key: string]: any, + }, + assets: string[], + platforms: PlatformT, + dependencies: { + [key: string]: { + name: string, + root: string, + platforms: { + [key: string]: PlatformSettingsT + }, + assets: string[], + hooks: { + [key: string]: string + } + }, + }, + commands: CommandT[] +}; +``` + +### reactNativePath + +A custom path to React Native, in case `require('react-native')` would throw. Useful when running +React Native from a (custom) source. + +### project + +A map of specific settings that can be set per platform. The exact shape is always defined by the package that provides given platform. + +In most cases, as a React Native developer, you should not need to define any of these. + +The following settings are available on iOS and Android: + +```ts +type ProjectParamsAndroidT = { + sourceDir?: string, + manifestPath?: string, + packageName?: string, + packageFolder?: string, + mainFilePath?: string, + stringsPath?: string, + settingsGradlePath?: string, + assetsPath?: string, + buildGradlePath?: string, + packageName?: string, +}; + +type ProjectParamsIOST = { + project?: string, + sharedLibraries?: string[], + libraryFolder?: string, + plist: any[], +}; +``` + +### assets + +An array of folders to check for project assets + +### platforms + +A object with platforms defined inside a project. You can check the format and options available [`here`](platforms.md#platform-interface) + +### commands + +An array of commands defined inside a project. You can check the format and options available [`here`](plugins.md#command-interface) + +### dependencies + +Dependencies is a map where key is the name of the dependency and value is an object that can override any of the resolved settings for a particular package. + +For example, you could set: +```js +module.exports = { + dependencies: { + ['react-native-webview']: { + platforms: { + ios: null + } + } + } +} +``` +in order to disable linking of React Native WebView on iOS. + +The object provided here is deep merged with the dependency config. Check [`projectConfig`](platforms.md#projectconfig) and [`dependencyConfig`](platforms.md#dependencyConfig) return values for a full list of properties that you can override. + +> Note: This is an advanced feature and you should not need to use it mos of the time. + +## Migrating from `rnpm` configuration + +The changes are mostly cosmetic so the migration should be pretty straight-forward. + +### Changing the configuration + +Properties `ios` and `android` were moved under `project`. Take a look at the following example for the differences. + +```json +{ + "rnpm": { + "ios": {}, + "android": {}, + "assets": ["./path-to-assets"] + } +} +``` + +to a `react-native.config.js` + +```js +module.exports = { + project: { + ios: {}, + android: {}, + }, + assets: ['./path-to-assets'], +}; +``` + + +