diff --git a/README.md b/README.md index ac5c93222..c4f4d548b 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,11 @@ This CLI is intended to be used with a certain version of React Native. You'll f ## Documentation +- [configuration](./docs/configuration.md) - [commands](./docs/commands.md) +- [plugins](./docs/plugins.md) - [init](./docs/init.md) - [autolinking](./docs/autolinking.md) -- [plugins](./docs/plugins.md) ## About diff --git a/docs/configuration.md b/docs/configuration.md index bca5ad350..24aeb533e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -14,3 +14,107 @@ Check the documentation for - [plugins](./plugins.md) to learn more about different types of configuration and features available. + +## Migration guide + +`"rnpm"` is deprecated and support for it will be removed in next major version of the CLI. + +> **Important**: Proceed further only if your project uses `"rnpm"` in `package.json`. + +There are different kinds of React Native projects, including apps, libraries and platforms. For each we prepared a brief "before & after" of the configuration shape with legacy `"rnpm"` and current `react-native.config.js`. Please mind that all configuration entries are optional. + +### Apps + +`package.json` entry: + +```json +{ + "rnpm": { + "ios": {}, + "android": {}, + "assets": ["./path-to-assets"], + "plugin": "./path-to-commands.js" + } +} +``` + +becomes `react-native.config.js` + +```js +module.exports = { + project: { + ios: {}, + android: {}, // grouped into "project" + }, + assets: ['./path-to-assets'], // stays the same + commands: require('./path-to-commands.js'), // formerly "plugin", returns an array of commands +}; +``` + +### Libraries + +`package.json` entry: + +```json +{ + "rnpm": { + "ios": {}, + "android": {}, + "assets": ["./path-to-assets"], + "hooks": { + "prelink": "./path-to-a-prelink-hook" + } + } +} +``` + +becomes `react-native.config.js`: + +```js +module.exports = { + // config for a library is scoped under "dependency" key + dependency: { + platforms: { + ios: {}, + android: {}, // projects are grouped into "platforms" + }, + assets: ['./path-to-assets'], // stays the same + // hooks are considered anti-pattern, please avoid them + hooks: { + prelink: './path-to-a-prelink-hook', + }, + }, +}; +``` + +You'll find more details in [dependencies](./dependencies.md) docs. + +### Out-of-tree platforms + +`package.json` entry: + +```json +{ + "rnpm": { + "haste": { + "platforms": ["windows"], + "providesModuleNodeModules": ["react-native-windows"] + }, + "platform": "./local-cli/platform.js" + } +} +``` + +becomes `react-native.config.js` + +```js +module.exports = { + platforms: { + // grouped under "platforms" entry + windows: require('./local-cli/platform.js').windows, + }, + // "haste" is no longer needed +}; +``` + +You'll find more details in [platforms](./platforms.md) docs. diff --git a/packages/cli/src/tools/config/index.js b/packages/cli/src/tools/config/index.js index b92c73224..c6e5a088f 100644 --- a/packages/cli/src/tools/config/index.js +++ b/packages/cli/src/tools/config/index.js @@ -95,13 +95,23 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { }, }; + let depsWithWarnings = []; + const finalConfig = findDependencies(projectRoot).reduce( (acc: ConfigT, dependencyName) => { let root; let config; try { root = resolveNodeModuleDir(projectRoot, dependencyName); - config = readDependencyConfigFromDisk(root); + const output = readDependencyConfigFromDisk(root); + config = output.config; + + if (output.legacy) { + const pkg = require(path.join(root, 'package.json')); + const link = + pkg.homepage || `https://npmjs.com/package/${dependencyName}`; + depsWithWarnings.push([dependencyName, link]); + } } catch (error) { logger.warn( inlineString(` @@ -172,6 +182,21 @@ function loadConfig(projectRoot: string = process.cwd()): ConfigT { initialConfig, ); + if (depsWithWarnings.length) { + logger.warn( + `The following packages use deprecated "rnpm" config that will stop working from next release:\n${depsWithWarnings + .map( + ([name, link]) => + ` - ${chalk.bold(name)}: ${chalk.dim(chalk.underline(link))}`, + ) + .join( + '\n', + )}\nPlease notify their maintainers about it. You can find more details at ${chalk.dim.underline( + 'https://react-native-community/cli/docs/configuration.md#migration-guide', + )}.`, + ); + } + return finalConfig; } diff --git a/packages/cli/src/tools/config/readConfigFromDisk.js b/packages/cli/src/tools/config/readConfigFromDisk.js index 7225f44d4..76a9c7e38 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.js +++ b/packages/cli/src/tools/config/readConfigFromDisk.js @@ -93,14 +93,15 @@ export function readConfigFromDisk(rootFolder: string): UserConfigT { */ export function readDependencyConfigFromDisk( rootFolder: string, -): UserDependencyConfigT { +): {config: UserDependencyConfigT, legacy?: boolean} { const explorer = cosmiconfig('react-native', { stopDir: rootFolder, searchPlaces, }); - const {config} = explorer.searchSync(rootFolder) || { + const {config, legacy} = explorer.searchSync(rootFolder) || { config: readLegacyDependencyConfigFromDisk(rootFolder), + legacy: true, }; const result = Joi.validate(config, schema.dependencyConfig); @@ -109,7 +110,7 @@ export function readDependencyConfigFromDisk( throw new JoiError(result.error); } - return result.value; + return {config: result.value, legacy: legacy && config !== undefined}; } /** @@ -139,7 +140,7 @@ const loadProjectCommands = ( function readLegacyDependencyConfigFromDisk( rootFolder: string, ): ?UserDependencyConfigT { - const {rnpm: config, name} = require(path.join(rootFolder, 'package.json')); + const {rnpm: config} = require(path.join(rootFolder, 'package.json')); if (!config) { return undefined; @@ -162,11 +163,5 @@ function readLegacyDependencyConfigFromDisk( : {}, }; - logger.warn( - `Package "${chalk.bold( - path.basename(name), - )}" is using deprecated "rnpm" config that will stop working from next release. Please notify its maintainers about it.`, - ); - return transformedConfig; }