mirror of
https://github.com/zhigang1992/create-react-app.git
synced 2026-06-16 18:39:21 +08:00
Install react, react-dom, and react-scripts at the same time (#1253)
* Install react and react-dom along with react-scripts - Install react, react-dom and react-script in a same time - Move react-scripts to devDependencies. * Check if react, react-dom has been already installed - To backward compatibility with old CRA’s cli - In case old CRA doesn’t install react, react-don along with react-scripts * Use packageName to find script dependency - use packageName to find dependency - fix pathExists.sync * Check dependencies.react in package.json instead of actual files * Process exit when dependencies not found - Show error and exit when dependencies not found. - Log install show custom package name * Remove template string * Install dependencies if template is preseted * Remove dangling comma Resolves #1239
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
|
||||
var chalk = require('chalk');
|
||||
|
||||
var currentNodeVersion = process.versions.node
|
||||
var currentNodeVersion = process.versions.node;
|
||||
if (currentNodeVersion.split('.')[0] < 4) {
|
||||
console.error(
|
||||
chalk.red(
|
||||
@@ -124,7 +124,7 @@ function createApp(name, verbose, version, template) {
|
||||
var packageJson = {
|
||||
name: appName,
|
||||
version: '0.1.0',
|
||||
private: true,
|
||||
private: true
|
||||
};
|
||||
fs.writeFileSync(
|
||||
path.join(root, 'package.json'),
|
||||
@@ -133,10 +133,6 @@ function createApp(name, verbose, version, template) {
|
||||
var originalDirectory = process.cwd();
|
||||
process.chdir(root);
|
||||
|
||||
console.log('Installing packages. This might take a couple minutes.');
|
||||
console.log('Installing ' + chalk.cyan('react-scripts') + '...');
|
||||
console.log();
|
||||
|
||||
run(root, appName, version, verbose, originalDirectory, template);
|
||||
}
|
||||
|
||||
@@ -149,15 +145,15 @@ function shouldUseYarn() {
|
||||
}
|
||||
}
|
||||
|
||||
function install(packageToInstall, verbose, callback) {
|
||||
function install(dependencies, verbose, callback) {
|
||||
var command;
|
||||
var args;
|
||||
if (shouldUseYarn()) {
|
||||
command = 'yarnpkg';
|
||||
args = [ 'add', '--dev', '--exact', packageToInstall];
|
||||
args = [ 'add', '--exact'].concat(dependencies);
|
||||
} else {
|
||||
command = 'npm';
|
||||
args = ['install', '--save-dev', '--save-exact', packageToInstall];
|
||||
args = ['install', '--save', '--save-exact'].concat(dependencies);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
@@ -174,7 +170,13 @@ function run(root, appName, version, verbose, originalDirectory, template) {
|
||||
var packageToInstall = getInstallPackage(version);
|
||||
var packageName = getPackageName(packageToInstall);
|
||||
|
||||
install(packageToInstall, verbose, function(code, command, args) {
|
||||
var allDependencies = ['react', 'react-dom', packageToInstall];
|
||||
|
||||
console.log('Installing packages. This might take a couple minutes.');
|
||||
console.log('Installing ' + chalk.cyan('react, react-dom, ' + packageName) + '...');
|
||||
console.log();
|
||||
|
||||
install(allDependencies, verbose, function(code, command, args) {
|
||||
if (code !== 0) {
|
||||
console.error(chalk.cyan(command + ' ' + args.join(' ')) + ' failed');
|
||||
process.exit(1);
|
||||
@@ -182,6 +184,10 @@ function run(root, appName, version, verbose, originalDirectory, template) {
|
||||
|
||||
checkNodeVersion(packageName);
|
||||
|
||||
// Since react-scripts has been installed with --save
|
||||
// We need to move it into devDependencies and rewrite package.json
|
||||
moveReactScriptsToDev(packageName);
|
||||
|
||||
var scriptsPath = path.resolve(
|
||||
process.cwd(),
|
||||
'node_modules',
|
||||
@@ -273,6 +279,33 @@ function checkAppName(appName) {
|
||||
}
|
||||
}
|
||||
|
||||
function moveReactScriptsToDev(packageName) {
|
||||
var packagePath = path.join(process.cwd(), 'package.json');
|
||||
var packageJson = require(packagePath);
|
||||
|
||||
if (typeof packageJson.dependencies === 'undefined') {
|
||||
console.error(
|
||||
chalk.red('Missing dependencies in package.json')
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var packageVersion = packageJson.dependencies[packageName];
|
||||
|
||||
if (typeof packageVersion === 'undefined') {
|
||||
console.error(
|
||||
chalk.red('Unable to find ' + packageName + ' in package.json')
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
packageJson.devDependencies = packageJson.devDependencies || {};
|
||||
packageJson.devDependencies[packageName] = packageVersion;
|
||||
delete packageJson.dependencies[packageName];
|
||||
|
||||
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2));
|
||||
}
|
||||
|
||||
// If project only contains files generated by GH, it’s safe.
|
||||
// We also special case IJ-based products .idea because it integrates with CRA:
|
||||
// https://github.com/facebookincubator/create-react-app/pull/368#issuecomment-243446094
|
||||
|
||||
98
packages/react-scripts/scripts/init.js
vendored
98
packages/react-scripts/scripts/init.js
vendored
@@ -64,8 +64,6 @@ module.exports = function(appPath, appName, verbose, originalDirectory, template
|
||||
}
|
||||
});
|
||||
|
||||
// Run yarn or npm for react and react-dom
|
||||
// TODO: having to do two npm/yarn installs is bad, can we avoid it?
|
||||
var command;
|
||||
var args;
|
||||
|
||||
@@ -92,53 +90,65 @@ module.exports = function(appPath, appName, verbose, originalDirectory, template
|
||||
fs.unlinkSync(templateDependenciesPath);
|
||||
}
|
||||
|
||||
console.log('Installing react and react-dom using ' + command + '...');
|
||||
console.log();
|
||||
// Install react and react-dom for backward compatibility with old CRA cli
|
||||
// which doesn't install react and react-dom along with react-scripts
|
||||
// or template is presetend (via --internal-testing-template)
|
||||
if (!isReactInstalled(appPackage) || template) {
|
||||
console.log('Installing react and react-dom using ' + command + '...');
|
||||
console.log();
|
||||
|
||||
var proc = spawn(command, args, {stdio: 'inherit'});
|
||||
proc.on('close', function (code) {
|
||||
if (code !== 0) {
|
||||
var proc = spawn.sync(command, args, {stdio: 'inherit'});
|
||||
if (proc.status !== 0) {
|
||||
console.error('`' + command + ' ' + args.join(' ') + '` failed');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the most elegant way to cd.
|
||||
// This needs to handle an undefined originalDirectory for
|
||||
// backward compatibility with old global-cli's.
|
||||
var cdpath;
|
||||
if (originalDirectory &&
|
||||
path.join(originalDirectory, appName) === appPath) {
|
||||
cdpath = appName;
|
||||
} else {
|
||||
cdpath = appPath;
|
||||
}
|
||||
// Display the most elegant way to cd.
|
||||
// This needs to handle an undefined originalDirectory for
|
||||
// backward compatibility with old global-cli's.
|
||||
var cdpath;
|
||||
if (originalDirectory &&
|
||||
path.join(originalDirectory, appName) === appPath) {
|
||||
cdpath = appName;
|
||||
} else {
|
||||
cdpath = appPath;
|
||||
}
|
||||
|
||||
console.log();
|
||||
console.log('Success! Created ' + appName + ' at ' + appPath);
|
||||
console.log('Inside that directory, you can run several commands:');
|
||||
console.log();
|
||||
console.log(chalk.cyan(' ' + command + ' start'));
|
||||
console.log(' Starts the development server.');
|
||||
console.log();
|
||||
console.log(chalk.cyan(' ' + command + ' run build'));
|
||||
console.log(' Bundles the app into static files for production.');
|
||||
console.log();
|
||||
console.log(chalk.cyan(' ' + command + ' test'));
|
||||
console.log(' Starts the test runner.');
|
||||
console.log();
|
||||
console.log(chalk.cyan(' ' + command + ' run eject'));
|
||||
console.log(' Removes this tool and copies build dependencies, configuration files');
|
||||
console.log(' and scripts into the app directory. If you do this, you can’t go back!');
|
||||
console.log();
|
||||
console.log('We suggest that you begin by typing:');
|
||||
console.log();
|
||||
console.log(chalk.cyan(' cd'), cdpath);
|
||||
console.log(' ' + chalk.cyan(command + ' start'));
|
||||
if (readmeExists) {
|
||||
console.log();
|
||||
console.log('Success! Created ' + appName + ' at ' + appPath);
|
||||
console.log('Inside that directory, you can run several commands:');
|
||||
console.log();
|
||||
console.log(chalk.cyan(' ' + command + ' start'));
|
||||
console.log(' Starts the development server.');
|
||||
console.log();
|
||||
console.log(chalk.cyan(' ' + command + ' run build'));
|
||||
console.log(' Bundles the app into static files for production.');
|
||||
console.log();
|
||||
console.log(chalk.cyan(' ' + command + ' test'));
|
||||
console.log(' Starts the test runner.');
|
||||
console.log();
|
||||
console.log(chalk.cyan(' ' + command + ' run eject'));
|
||||
console.log(' Removes this tool and copies build dependencies, configuration files');
|
||||
console.log(' and scripts into the app directory. If you do this, you can’t go back!');
|
||||
console.log();
|
||||
console.log('We suggest that you begin by typing:');
|
||||
console.log();
|
||||
console.log(chalk.cyan(' cd'), cdpath);
|
||||
console.log(' ' + chalk.cyan(command + ' start'));
|
||||
if (readmeExists) {
|
||||
console.log();
|
||||
console.log(chalk.yellow('You had a `README.md` file, we renamed it to `README.old.md`'));
|
||||
}
|
||||
console.log();
|
||||
console.log('Happy hacking!');
|
||||
});
|
||||
console.log(chalk.yellow('You had a `README.md` file, we renamed it to `README.old.md`'));
|
||||
}
|
||||
console.log();
|
||||
console.log('Happy hacking!');
|
||||
};
|
||||
|
||||
function isReactInstalled(appPackage) {
|
||||
var dependencies = appPackage.dependencies || {};
|
||||
|
||||
return (
|
||||
typeof dependencies.react !== 'undefined' &&
|
||||
typeof dependencies['react-dom'] !== 'undefined'
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user