Adam Miskiewicz 9f01f96770 Move react to peerDependencies
Summary:
This PR moves `react` from dependencies to peerDependencies.

In general, this would have only been important for those people using packages that depend on `react` and were using npm@2...npm@3 would automatically de-dupe.

However, when #5812 gets merged, dependencies will be scoped to react-native (on both npm@2 & npm@3), thus breaking projects that are using a package like `react-redux` for example, which depends on `react`. There would be two copies of React installed, and due to the use of haste modules in `react`, this would break the packager and cause naming collisions.

This PR does three things -

1. Moves the dependency from dependencies to peerDependencies
2. Updates the local-cli to run `npm install react --save` when a new project is initialized.
3. Updates `react-native upgrade` to warn if `react` is not listed in the package.json's dependencies.

**Note: This will require a shrinkwrap update.**
Closes https://github.com/facebook/react-native/pull/5813

Reviewed By: svcscm

Differential Revision: D2918380

Pulled By: androidtrunkagent

fb-gh-sync-id: 6e4234a45284be2fdf6fedf29e70b2d2d0262486
shipit-source-id: 6e4234a45284be2fdf6fedf29e70b2d2d0262486
2016-02-09 15:38:37 -08:00

89 lines
3.2 KiB
JavaScript

/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
const fs = require('fs');
const chalk = require('chalk');
const path = require('path');
const Promise = require('promise');
const yeoman = require('yeoman-environment');
const semver = require('semver');
module.exports = function upgrade(args, config) {
args = args || process.argv;
const env = yeoman.createEnv();
const pak = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const version = pak.dependencies['react-native'];
if (version) {
if (version === 'latest' || version === '*') {
console.warn(
chalk.yellow(
'Major releases are most likely to introduce breaking changes.\n' +
'Use a proper version number in your \'package.json\' file to avoid breakage.\n' +
'e.g. - ^0.18.0'
)
);
} else {
const installed = JSON.parse(fs.readFileSync('node_modules/react-native/package.json', 'utf8'));
if (semver.satisfies(installed.version, version)) {
const v = version.replace(/^(~|\^|=)/, '').replace(/x/i, '0');
if (semver.valid(v)) {
console.log(
'Upgrading project to react-native v' + installed.version + '\n' +
'Be sure to read the release notes and breaking changes:\n' +
chalk.blue(
'https://github.com/facebook/react-native/releases/tag/v' + semver.major(v) + '.' + semver.minor(v) + '.0'
)
);
// >= v0.21.0, we require react to be a peer depdendency
if (semver.gte(v, '0.21.0') && !pak.dependencies['react']) {
console.log(
chalk.yellow(
'\nYour \'package.json\' file doesn\'t seem to have \'react\' as a dependency.\n' +
'\'react\' was changed from a dependency to a peer dependency in react-native v0.21.0.\n' +
'Therefore, it\'s necessary to include \'react\' in your project\'s dependencies.\n' +
'Just run \'npm install --save react\', then re-run \'react-native upgrade\'.\n'
)
);
return Promise.resolve();
}
} else {
console.log(
chalk.yellow(
'A valid version number for \'react-native\' is not specified your \'package.json\' file.'
)
);
}
} else {
console.warn(
chalk.yellow(
'react-native version in \'package.json\' doesn\'t match the installed version in \'node_modules\'.\n' +
'Try running \'npm install\' to fix the issue.'
)
);
}
}
} else {
console.warn(
chalk.yellow(
'Your \'package.json\' file doesn\'t seem to have \'react-native\' as a dependency.'
)
);
}
const generatorPath = path.join(__dirname, '..', 'generator');
env.register(generatorPath, 'react:app');
const generatorArgs = ['react:app', pak.name].concat(args);
return new Promise((resolve) => env.run(generatorArgs, {upgrade: true}, resolve));
};