Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use offline cached version with yarn when it's possible #1423

Merged
123 changes: 83 additions & 40 deletions packages/create-react-app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ var path = require('path');
var execSync = require('child_process').execSync;
var spawn = require('cross-spawn');
var semver = require('semver');
var dns = require('dns');

var projectName;

Expand Down Expand Up @@ -154,25 +155,44 @@ function shouldUseYarn() {
}
}

function install(dependencies, verbose, callback) {
var command;
var args;
if (shouldUseYarn()) {
command = 'yarnpkg';
args = [ 'add', '--exact'].concat(dependencies);
} else {
checkNpmVersion();
command = 'npm';
args = ['install', '--save', '--save-exact'].concat(dependencies);
}
function install(useYarn, dependencies, verbose, isOnline) {
return new Promise(function(resolve, reject) {
var command;
var args;
if (useYarn) {
command = 'yarnpkg';
args = [
'add',
'--exact',
isOnline === false && '--offline'
].concat(dependencies);

if (!isOnline) {
console.log(chalk.yellow('You appear to be offline.'));
console.log(chalk.yellow('Falling back to the local Yarn cache.'));
console.log();
}

if (verbose) {
args.push('--verbose');
}
} else {
checkNpmVersion();
command = 'npm';
args = ['install', '--save', '--save-exact'].concat(dependencies);
}

var child = spawn(command, args, {stdio: 'inherit'});
child.on('close', function(code) {
callback(code, command, args);
if (verbose) {
args.push('--verbose');
}

var child = spawn(command, args, {stdio: 'inherit'});
child.on('close', function(code) {
if (code !== 0) {
reject({
command: command + ' ' + args.join(' ')
});
return;
}
resolve();
});
});
}

Expand All @@ -188,11 +208,38 @@ function run(root, appName, version, verbose, originalDirectory, template) {
', and ' + chalk.cyan(packageName) + '...'
);
console.log();

install(allDependencies, verbose, function(code, command, args) {
if (code !== 0) {

var useYarn = shouldUseYarn();
checkIfOnline(useYarn)
.then(function(isOnline) {
return install(useYarn, allDependencies, verbose, isOnline);
})
.then(function() {
checkNodeVersion(packageName);

// Since react-scripts has been installed with --save
// we need to move it into devDependencies and rewrite package.json
// also ensure react dependencies have caret version range
fixDependencies(packageName);

var scriptsPath = path.resolve(
process.cwd(),
'node_modules',
packageName,
'scripts',
'init.js'
);
var init = require(scriptsPath);
init(root, appName, verbose, originalDirectory, template);
})
.catch(function(reason) {
console.log();
console.error('Aborting installation.', chalk.cyan(command + ' ' + args.join(' ')), 'has failed.');
console.log('Aborting installation.');
if (reason.command) {
console.log(' ' + chalk.cyan(reason.command), 'has failed.')
}
console.log();

// On 'exit' we will delete these files from target directory.
var knownGeneratedFiles = [
'package.json', 'npm-debug.log', 'yarn-error.log', 'yarn-debug.log', 'node_modules'
Expand All @@ -217,25 +264,7 @@ function run(root, appName, version, verbose, originalDirectory, template) {
}
console.log('Done.');
process.exit(1);
}

checkNodeVersion(packageName);

// Since react-scripts has been installed with --save
// we need to move it into devDependencies and rewrite package.json
// also ensure react dependencies have caret version range
fixDependencies(packageName);

var scriptsPath = path.resolve(
process.cwd(),
'node_modules',
packageName,
'scripts',
'init.js'
);
var init = require(scriptsPath);
init(root, appName, verbose, originalDirectory, template);
});
});
}

function getInstallPackage(version) {
Expand Down Expand Up @@ -407,3 +436,17 @@ function isSafeToCreateProjectIn(root) {
return validFiles.indexOf(file) >= 0;
});
}

function checkIfOnline(useYarn) {
if (!useYarn) {
// Don't ping the Yarn registry.
// We'll just assume the best case.
return Promise.resolve(true);
}

return new Promise(function(resolve) {
dns.resolve('registry.yarnpkg.com', function(err) {
resolve(err === null);
});
});
}