diff --git a/docs/commands.md b/docs/commands.md index 4516390c9..f211239e3 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -461,14 +461,6 @@ Specify any additional asset extensions to be used by the packager Specify any additional source extensions to be used by the packager -#### `--platforms [list]` - -Specify any additional platforms to be used by the packager - -#### `--providesModuleNodeModules [list]` - -Specify any npm packages that import dependencies with providesModule - #### `--max-workers [number]` 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 diff --git a/docs/configuration.md b/docs/configuration.md index 24aeb533e..8b66e9529 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -17,7 +17,7 @@ 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. +`"rnpm"` is deprecated and support for it is removed since v4.x of the CLI. > **Important**: Proceed further only if your project uses `"rnpm"` in `package.json`. diff --git a/packages/cli-types/src/index.ts b/packages/cli-types/src/index.ts index e2dc9d394..0d8ea11a9 100644 --- a/packages/cli-types/src/index.ts +++ b/packages/cli-types/src/index.ts @@ -126,7 +126,6 @@ export type ProjectConfig = { * @property dependencies - Map of the dependencies that are present in the project * @property platforms - Map of available platforms (build-ins and dynamically loaded) * @property commands - An array of commands that are present in 3rd party packages - * @property haste - Haste configuration resolved based on available plugins */ export type Config = { root: string; @@ -150,18 +149,14 @@ export type Config = { [name: string]: PlatformConfig; }; commands: Command[]; - haste: { - platforms: Array; - providesModuleNodeModules: Array; - }; }; /** - * Shares some structure with Config, except that haste and root - * are calculated and can't be defined + * Shares some structure with Config, except that root is calculated and can't + * be defined */ -export type UserConfig = Omit & { +export type UserConfig = Omit & { reactNativePath: string | void; // Additional project settings project: { @@ -178,11 +173,6 @@ export type UserDependencyConfig = { commands: Command[]; // An array of extra platforms to load platforms: Config['platforms']; - // Haste config defined by legacy `rnpm` - haste?: { - platforms: string[]; - providesModuleNodeModules: string[]; - }; }; export { diff --git a/packages/cli/src/commands/server/server.ts b/packages/cli/src/commands/server/server.ts index 42923c763..3100bec3f 100644 --- a/packages/cli/src/commands/server/server.ts +++ b/packages/cli/src/commands/server/server.ts @@ -52,18 +52,6 @@ export default { 'Specify any additional source extensions to be used by the packager', parse: (val: string) => val.split(','), }, - { - name: '--platforms [list]', - description: - 'Specify any additional platforms to be used by the packager', - parse: (val: string) => val.split(','), - }, - { - name: '--providesModuleNodeModules [list]', - description: - 'Specify any npm packages that import dependencies with providesModule', - parse: (val: string) => val.split(','), - }, { name: '--max-workers [number]', description: diff --git a/packages/cli/src/tools/config/__mocks__/index.ts b/packages/cli/src/tools/config/__mocks__/index.ts index 08a213a9a..b106d977a 100644 --- a/packages/cli/src/tools/config/__mocks__/index.ts +++ b/packages/cli/src/tools/config/__mocks__/index.ts @@ -13,9 +13,5 @@ export default function mockedLoadConfig() { }, dependencies: {}, assets: [], - haste: { - providesModuleNodeModules: [], - platforms: [], - }, }; } diff --git a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap index 770c6d807..0c5415a93 100644 --- a/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap +++ b/packages/cli/src/tools/config/__tests__/__snapshots__/index-test.ts.snap @@ -1,32 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should handle deprecated "rnpm" in project root: returns valid config 1`] = ` -Object { - "assets": Array [ - "<>/fonts/SampleFont.ttf", - ], - "commands": Array [], - "dependencies": Object {}, - "haste": Object { - "platforms": Array [], - "providesModuleNodeModules": Array [], - }, - "platforms": Object {}, - "project": Object {}, - "reactNativePath": "<>/node_modules/react-native", - "root": "<>", -} -`; - exports[`should have a valid structure by default 1`] = ` Object { "assets": Array [], "commands": Array [], "dependencies": Object {}, - "haste": Object { - "platforms": Array [], - "providesModuleNodeModules": Array [], - }, "platforms": Object {}, "project": Object {}, "reactNativePath": "<>", @@ -34,22 +12,6 @@ Object { } `; -exports[`should load an out-of-tree "windows" platform that ships with a dependency 1`] = ` -Object { - "haste": Object { - "platforms": Array [ - "windows", - ], - "providesModuleNodeModules": Array [ - "react-native-windows", - ], - }, - "platforms": Object { - "windows": Object {}, - }, -} -`; - exports[`should load commands from "react-native-foo" and "react-native-bar" packages 1`] = ` Array [ Object { @@ -91,46 +53,6 @@ Object { } `; -exports[`should read \`rnpm\` config from a dependency and transform it to a new format: foo config 1`] = ` -Object { - "assets": Array [], - "hooks": Object {}, - "name": "react-native-foo", - "params": Array [], - "platforms": Object { - "android": null, - "ios": Object { - "folder": "<>/node_modules/react-native-foo", - "libraryFolder": "Libraries", - "pbxprojPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj/project.pbxproj", - "plist": Array [], - "podfile": null, - "podspecPath": null, - "projectName": "customProject.xcodeproj", - "projectPath": "<>/node_modules/react-native-foo/customLocation/customProject.xcodeproj", - "scriptPhases": Array [], - "sharedLibraries": Array [], - "sourceDir": "<>/node_modules/react-native-foo/customLocation", - }, - }, - "root": "<>/node_modules/react-native-foo", -} -`; - -exports[`should read \`rnpm\` config from a dependency and transform it to a new format: haste config 1`] = ` -Object { - "platforms": Array [ - "ios", - "android", - "dummy", - ], - "providesModuleNodeModules": Array [ - "react-native", - "react-native-dummy", - ], -} -`; - exports[`should read a config of a dependency and use it to load other settings 1`] = ` Object { "assets": Array [], diff --git a/packages/cli/src/tools/config/__tests__/index-test.ts b/packages/cli/src/tools/config/__tests__/index-test.ts index fbf7a02dc..2fb0cec8c 100644 --- a/packages/cli/src/tools/config/__tests__/index-test.ts +++ b/packages/cli/src/tools/config/__tests__/index-test.ts @@ -69,23 +69,6 @@ test('should have a valid structure by default', () => { expect(removeString(config, DIR)).toMatchSnapshot(); }); -test('should handle deprecated "rnpm" in project root', () => { - writeFiles(DIR, { - 'package.json': `{ - "rnpm": { - "assets": ["./fonts"] - } - }`, - 'fonts/SampleFont.ttf': '', - }); - const config = loadConfig(DIR); - - expect(removeString(config, DIR)).toMatchSnapshot('returns valid config'); - expect(logger.warn).toBeCalledWith( - expect.stringMatching(/Your project is using deprecated/), - ); -}); - test('should return dependencies from package.json', () => { writeFiles(DIR, { ...REACT_NATIVE_MOCK, @@ -167,35 +150,6 @@ test('should merge project configuration with default values', () => { ); }); -test('should read `rnpm` config from a dependency and transform it to a new format', () => { - writeFiles(DIR, { - ...REACT_NATIVE_MOCK, - 'node_modules/react-native-foo/package.json': `{ - "name": "react-native-foo", - "rnpm": { - "ios": { - "project": "./customLocation/customProject.xcodeproj" - }, - "haste": { - "platforms": ["dummy"], - "providesModuleNodeModules": ["react-native-dummy"] - } - } - }`, - 'package.json': `{ - "dependencies": { - "react-native": "0.0.1", - "react-native-foo": "0.0.1" - } - }`, - }); - const {dependencies, haste} = loadConfig(DIR); - expect(removeString(dependencies['react-native-foo'], DIR)).toMatchSnapshot( - 'foo config', - ); - expect(haste).toMatchSnapshot('haste config'); -}); - test('should load commands from "react-native-foo" and "react-native-bar" packages', () => { writeFiles(DIR, { 'node_modules/react-native-foo/package.json': '{}', @@ -227,39 +181,6 @@ test('should load commands from "react-native-foo" and "react-native-bar" packag expect(commands).toMatchSnapshot(); }); -test('should load an out-of-tree "windows" platform that ships with a dependency', () => { - writeFiles(DIR, { - 'node_modules/react-native-windows/platform.js': ` - module.exports = {"windows": {}}; - `, - 'node_modules/react-native-windows/plugin.js': ` - module.exports = []; - `, - 'node_modules/react-native-windows/package.json': `{ - "name": "react-native-windows", - "rnpm": { - "haste": { - "platforms": [ - "windows" - ], - "providesModuleNodeModules": [ - "react-native-windows" - ] - }, - "plugin": "./plugin.js", - "platform": "./platform.js" - } - }`, - 'package.json': `{ - "dependencies": { - "react-native-windows": "0.0.1" - } - }`, - }); - const {haste, platforms} = loadConfig(DIR); - expect(removeString({haste, platforms}, DIR)).toMatchSnapshot(); -}); - // @todo: figure out why this test is so flaky // eslint-disable-next-line jest/no-disabled-tests test.skip('should skip packages that have invalid configuration', () => { diff --git a/packages/cli/src/tools/config/index.ts b/packages/cli/src/tools/config/index.ts index 90f4c35a9..3e55d99bf 100644 --- a/packages/cli/src/tools/config/index.ts +++ b/packages/cli/src/tools/config/index.ts @@ -75,10 +75,6 @@ function loadConfig(projectRoot: string = findProjectRoot()): Config { return findAssets(projectRoot, userConfig.assets); }, platforms: userConfig.platforms, - haste: { - providesModuleNodeModules: [], - platforms: Object.keys(userConfig.platforms), - }, get project() { if (lazyProject) { return lazyProject; @@ -99,8 +95,6 @@ function loadConfig(projectRoot: string = findProjectRoot()): Config { }, }; - let depsWithWarnings: Array<[string, string]> = []; - const finalConfig = Array.from( new Set([ ...Object.keys(userConfig.dependencies), @@ -116,15 +110,7 @@ function loadConfig(projectRoot: string = findProjectRoot()): Config { root = localDependencyRoot || resolveNodeModuleDir(projectRoot, dependencyName); - const output = readDependencyConfigFromDisk(root); - config = output.config; - - if (output.legacy && !localDependencyRoot) { - const pkg = require(path.join(root, 'package.json')); - const link = - pkg.homepage || `https://npmjs.com/package/${dependencyName}`; - depsWithWarnings.push([dependencyName, link]); - } + config = readDependencyConfigFromDisk(root); } catch (error) { logger.warn( inlineString(` @@ -139,17 +125,6 @@ function loadConfig(projectRoot: string = findProjectRoot()): Config { const isPlatform = Object.keys(config.platforms).length > 0; - /** - * Legacy `rnpm` config required `haste` to be defined. With new config, - * we do it automatically. - * - * @todo: Remove this once `rnpm` config is deprecated and all major RN libs are converted. - */ - const haste = config.haste || { - providesModuleNodeModules: isPlatform ? [dependencyName] : [], - platforms: Object.keys(config.platforms), - }; - return assign({}, acc, { dependencies: assign({}, acc.dependencies, { get [dependencyName](): Dependency { @@ -168,31 +143,9 @@ function loadConfig(projectRoot: string = findProjectRoot()): Config { ...acc.platforms, ...config.platforms, }, - haste: { - providesModuleNodeModules: [ - ...acc.haste.providesModuleNodeModules, - ...haste.providesModuleNodeModules, - ], - platforms: [...acc.haste.platforms, ...haste.platforms], - }, }) as Config; }, 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://github.com/react-native-community/cli/blob/master/docs/configuration.md#migration-guide', - )}.`, - ); - } - return finalConfig; } diff --git a/packages/cli/src/tools/config/readConfigFromDisk.ts b/packages/cli/src/tools/config/readConfigFromDisk.ts index 4fe850785..a68e94ec9 100644 --- a/packages/cli/src/tools/config/readConfigFromDisk.ts +++ b/packages/cli/src/tools/config/readConfigFromDisk.ts @@ -1,92 +1,17 @@ import Joi from '@hapi/joi'; import cosmiconfig from 'cosmiconfig'; -import path from 'path'; -import chalk from 'chalk'; import {JoiError} from './errors'; import * as schema from './schema'; -import {logger} from '@react-native-community/cli-tools'; -import resolveReactNativePath from './resolveReactNativePath'; import { UserConfig, - AndroidProjectConfig, - AndroidDependencyConfig, - IOSProjectConfig, - IOSDependencyConfig, - Command, - InquirerPrompt, UserDependencyConfig, } from '@react-native-community/cli-types'; -const MIGRATION_GUIDE = `Migration guide: ${chalk.dim.underline( - 'https://github.com/react-native-community/cli/blob/master/docs/configuration.md', -)}`; - -type LegacyConfig = { - ios: IOSProjectConfig; - android: AndroidProjectConfig; - assets: string[]; - reactNativePath: string; - hooks?: { - [key: string]: string; - }; -}; - -type LegacyDependencyConfig = { - platform: any; - ios: IOSDependencyConfig; - android: AndroidDependencyConfig; - assets: string[]; - plugin: Array; - params: InquirerPrompt[]; - haste: any; -}; /** - * Places to look for the new configuration + * Places to look for the configuration file. */ const searchPlaces = ['react-native.config.js']; -function readLegacyConfigFromDisk(rootFolder: string): UserConfig | void { - let config: LegacyConfig; - - try { - config = require(path.join(rootFolder, 'package.json')).rnpm; - } catch (error) { - // when `init` is running, there's no package.json yet - return undefined; - } - - if (!config) { - return undefined; - } - - const transformedConfig: UserConfig = { - project: { - ios: config.ios, - android: config.android, - }, - assets: config.assets, - commands: [], - dependencies: {}, - // @ts-ignore - TODO: platforms can be empty, adjust types - platforms: {}, - get reactNativePath() { - return config.reactNativePath - ? path.resolve(rootFolder, config.reactNativePath) - : resolveReactNativePath(rootFolder); - }, - }; - - logger.warn( - `Your project is using deprecated "${chalk.bold( - 'rnpm', - )}" config that will stop working from next release. Please use a "${chalk.bold( - 'react-native.config.js', - )}" file to configure the React Native CLI. ${MIGRATION_GUIDE}`, - ); - - return transformedConfig; -} - /** * Reads a project configuration as defined by the user in the current * workspace. @@ -97,9 +22,8 @@ export function readConfigFromDisk(rootFolder: string): UserConfig { stopDir: rootFolder, }); - const {config} = explorer.searchSync(rootFolder) || { - config: readLegacyConfigFromDisk(rootFolder), - }; + const searchResult = explorer.searchSync(rootFolder); + const config = searchResult ? searchResult.config : undefined; const result = Joi.validate(config, schema.projectConfig); @@ -116,17 +40,14 @@ export function readConfigFromDisk(rootFolder: string): UserConfig { */ export function readDependencyConfigFromDisk( rootFolder: string, -): {config: UserDependencyConfig; legacy?: boolean} { +): UserDependencyConfig { const explorer = cosmiconfig('react-native', { stopDir: rootFolder, searchPlaces, }); const searchResult = explorer.searchSync(rootFolder); - const legacy = !searchResult; - let config = searchResult - ? (searchResult.config as UserDependencyConfig) - : (readLegacyDependencyConfigFromDisk(rootFolder) as UserDependencyConfig); + const config = searchResult ? searchResult.config : emptyDependencyConfig; const result = Joi.validate(config, schema.dependencyConfig); @@ -134,75 +55,16 @@ export function readDependencyConfigFromDisk( throw new JoiError(result.error); } - return {config: result.value, legacy: legacy && config !== undefined}; + return result.value as UserDependencyConfig; } -/** - * Returns an array of commands that are defined in the project. - * - * `config.project` can be either an array of paths or a single string. - * Each of the files can export a commands (object) or an array of commands - */ -const loadProjectCommands = ( - root: string, - commands: Array | string | undefined, -): Array => { - return ([] as string[]) - .concat(commands || []) - .reduce((acc: Array, cmdPath: string) => { - const cmds: Array | Command = require(path.join(root, cmdPath)); - return acc.concat(cmds); - }, []); +const emptyDependencyConfig = { + dependency: { + platforms: {}, + assets: [], + hooks: {}, + params: [], + }, + commands: [], + platforms: {}, }; - -/** - * Reads a legacy configuration from a `package.json` "rnpm" key. - */ -function readLegacyDependencyConfigFromDisk( - rootFolder: string, -): UserDependencyConfig | undefined { - let config = {} as LegacyDependencyConfig; - - try { - config = require(path.join(rootFolder, 'package.json')).rnpm; - } catch (error) { - // package.json is usually missing in local libraries that are not in - // project "dependencies", so we just return a bare config - // @ts-ignore - TODO: platforms can be empty, adjust types - return { - dependency: { - platforms: {}, - assets: [], - hooks: {}, - params: [], - }, - commands: [], - // @ts-ignore - platforms: {}, - }; - } - - if (!config) { - return undefined; - } - - const transformedConfig: UserDependencyConfig = { - dependency: { - platforms: { - ios: config.ios, - android: config.android, - }, - assets: config.assets, - // @ts-ignore – likely a bug, but we don't care because legacy config is soon to be removed - hooks: config.commands, - params: config.params, - }, - haste: config.haste, - commands: loadProjectCommands(rootFolder, config.plugin), - platforms: config.platform - ? require(path.join(rootFolder, config.platform)) - : {}, - }; - - return transformedConfig; -} diff --git a/packages/cli/src/tools/loadMetroConfig.ts b/packages/cli/src/tools/loadMetroConfig.ts index 7bc29d7a5..d7f086d1c 100644 --- a/packages/cli/src/tools/loadMetroConfig.ts +++ b/packages/cli/src/tools/loadMetroConfig.ts @@ -36,7 +36,6 @@ export interface MetroConfig { resolver: { resolverMainFields: string[]; platforms: string[]; - providesModuleNodeModules: string[]; }; serializer: { getModulesRunBeforeMainModule: () => string[]; @@ -60,16 +59,12 @@ export interface MetroConfig { /** * Default configuration - * - * @todo(grabbou): As a separate PR, haste.platforms should be added before "native". - * Otherwise, a.native.js will not load on Windows or other platforms */ export const getDefaultConfig = (ctx: Config): MetroConfig => { return { resolver: { resolverMainFields: ['react-native', 'browser', 'main'], - platforms: [...ctx.haste.platforms, 'native'], - providesModuleNodeModules: ctx.haste.providesModuleNodeModules, + platforms: [...Object.keys(ctx.platforms), 'native'], }, serializer: { getModulesRunBeforeMainModule: () => [