From 25e366d19089ee47c47c0053f5be5d1bec94193f Mon Sep 17 00:00:00 2001 From: Conrad2134 Date: Thu, 23 Feb 2017 19:38:31 -0600 Subject: [PATCH 1/2] comments so I can open a PR --- tasks/e2e-simple.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tasks/e2e-simple.sh b/tasks/e2e-simple.sh index a79b2f489e..760b2d5b09 100755 --- a/tasks/e2e-simple.sh +++ b/tasks/e2e-simple.sh @@ -221,6 +221,14 @@ npm start -- --smoke-test # Test environment handling verify_env_url +# CONNOR : #1551 : Trying to figure out where everything goes. This is after testing is done (before testing eject). +# That's what we want, but this is tested with a packed, local-pathed version of react-scripts, correct? +# So how, in our yarn.lock, would we ever get it to install its own released version before we release it? +# We could create + copy the yarn.lock as part of the release process, but if the version to release is 0.9.2, +# then you can still only install 0.9.1, and that's what the lockfile would have. And you can't do it *after* +# releasing because then you've already released it. +# See: https://github.com/facebookincubator/create-react-app/issues/1551 + # ****************************************************************************** # Finally, let's check that everything still works after ejecting. # ****************************************************************************** From 84107137ffe324f20bc03e077ab15606d40cc9a8 Mon Sep 17 00:00:00 2001 From: Conrad2134 Date: Sat, 25 Feb 2017 09:46:05 -0600 Subject: [PATCH 2/2] Initial work for yarn.lock - still messy, still work TODO. --- packages/create-react-app/index.js | 114 +++++++++++++++++++------ packages/create-react-app/package.json | 1 + tasks/e2e-simple.sh | 8 -- 3 files changed, 91 insertions(+), 32 deletions(-) diff --git a/packages/create-react-app/index.js b/packages/create-react-app/index.js index d8d28496cb..35ef8e3787 100755 --- a/packages/create-react-app/index.js +++ b/packages/create-react-app/index.js @@ -58,6 +58,8 @@ var path = require('path'); var execSync = require('child_process').execSync; var spawn = require('cross-spawn'); var semver = require('semver'); +var https = require('https'); +var request = require('request'); var projectName; @@ -145,12 +147,14 @@ function shouldUseYarn() { } } -function install(dependencies, verbose, callback) { +function install(dependencies, verbose, useYarnLock, callback) { var command; var args; if (shouldUseYarn()) { command = 'yarnpkg'; - args = [ 'add', '--exact'].concat(dependencies); + + // If the yarn.lock exists, just run `yarnpkg`. + args = useYarnLock ? [] : ['add', '--exact'].concat(dependencies); } else { command = 'npm'; args = ['install', '--save', '--save-exact'].concat(dependencies); @@ -172,32 +176,74 @@ function run(root, appName, version, verbose, originalDirectory, template) { var allDependencies = ['react', 'react-dom', packageToInstall]; + var installDependencies = function(yarnLockExists) { + install(allDependencies, verbose, yarnLockExists, function(code, command, args) { + if (code !== 0) { + console.error(chalk.cyan(command + ' ' + args.join(' ')) + ' failed'); + process.exit(1); + } + + checkNodeVersion(packageName); + + // Since react-scripts has been installed with --save + // We need to move it into devDependencies and rewrite package.json + if (!yarnLockExists) { + moveReactScriptsToDev(packageName); + } + + var scriptsPath = path.resolve( + process.cwd(), + 'node_modules', + packageName, + 'scripts', + 'init.js' + ); + var init = require(scriptsPath); + init(root, appName, verbose, originalDirectory, template); + }); + } + 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); - } - - 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', - packageName, - 'scripts', - 'init.js' - ); - var init = require(scriptsPath); - init(root, appName, verbose, originalDirectory, template); - }); + // Try to download the yarn.lock file. + if (shouldUseYarn()) { + var releaseRequest = request({ + uri: 'https://api.github.com/repos/facebookincubator/create-react-app/releases/latest', + method: 'GET', + headers: { + 'User-Agent': 'create-react-app' + } + }, function(err, response, releasesBody) { + var yarnLockUrl = JSON.parse(releasesBody).assets.reduce(function(acc, asset) { + return asset.name === 'yarn.lock' ? asset.browser_download_url : acc; + }, ""); + + // TODO: We'll want to copy the package.json && yarn.lock, + // `yarn install` will change the lockfile if the deps don't + // satisfy versions in the package.json. + + if (!yarnLockUrl) { + installDependencies(false); + + return; + } + + var yarnLockRequest = request(yarnLockUrl, function(err, response, body) { + fs.writeFileSync('yarn.lock', body); // TODO: Async + + // Success. Write the package.json dependencies manually. + writePackageJsonFromYarnLock(packageName, packageToInstall); + installDependencies(true); + }).on('error', function(err) { + fs.unlink(dest); + installDependencies(false); + }); + }); + } else { + installDependencies(false); + } } function getInstallPackage(version) { @@ -306,6 +352,26 @@ function moveReactScriptsToDev(packageName) { fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2)); } +// TODO: Get rid of most this - we'll copy a package.json +// Will need to write the name, though. +function writePackageJsonFromYarnLock(packageName, packageVersion) { + var packagePath = path.join(process.cwd(), 'package.json'); + var packageJson = require(packagePath); + + packageJson.devDependencies = packageJson.devDependencies || {}; + packageJson.devDependencies[packageName] = packageVersion; + + var reactVersion = 'latest'; + var reactDomVersion = 'latest'; + + packageJson.dependencies = { + 'react': reactVersion, + 'react-dom': reactDomVersion + }; + + 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 diff --git a/packages/create-react-app/package.json b/packages/create-react-app/package.json index 93df8da55b..5325e4db48 100644 --- a/packages/create-react-app/package.json +++ b/packages/create-react-app/package.json @@ -24,6 +24,7 @@ "commander": "^2.9.0", "cross-spawn": "^4.0.0", "fs-extra": "^1.0.0", + "request": "^2.79.0", "semver": "^5.0.3" } } diff --git a/tasks/e2e-simple.sh b/tasks/e2e-simple.sh index 760b2d5b09..a79b2f489e 100755 --- a/tasks/e2e-simple.sh +++ b/tasks/e2e-simple.sh @@ -221,14 +221,6 @@ npm start -- --smoke-test # Test environment handling verify_env_url -# CONNOR : #1551 : Trying to figure out where everything goes. This is after testing is done (before testing eject). -# That's what we want, but this is tested with a packed, local-pathed version of react-scripts, correct? -# So how, in our yarn.lock, would we ever get it to install its own released version before we release it? -# We could create + copy the yarn.lock as part of the release process, but if the version to release is 0.9.2, -# then you can still only install 0.9.1, and that's what the lockfile would have. And you can't do it *after* -# releasing because then you've already released it. -# See: https://github.com/facebookincubator/create-react-app/issues/1551 - # ****************************************************************************** # Finally, let's check that everything still works after ejecting. # ******************************************************************************