diff --git a/packages/create-react-app/createReactApp.js b/packages/create-react-app/createReactApp.js index 1bf3bb0649..f0111aebd6 100755 --- a/packages/create-react-app/createReactApp.js +++ b/packages/create-react-app/createReactApp.js @@ -49,6 +49,7 @@ const url = require('url'); const hyperquest = require('hyperquest'); const envinfo = require('envinfo'); const os = require('os'); +const resolveFrom = require('resolve-from'); const findMonorepo = require('react-dev-utils/workspaceUtils').findMonorepo; const packageJson = require('./package.json'); @@ -323,15 +324,12 @@ function run( ); }) .then(packageName => { - checkNodeVersion(packageName); + checkNodeVersion(root, packageName); setCaretRangeForRuntimeDeps(packageName); - const scriptsPath = path.resolve( - process.cwd(), - 'node_modules', - packageName, - 'scripts', - 'init.js' + const scriptsPath = resolveFrom( + root, + path.join(packageName, 'scripts', 'init.js') ); const init = require(scriptsPath); init(root, appName, verbose, originalDirectory, template); @@ -511,12 +509,10 @@ function checkNpmVersion() { }; } -function checkNodeVersion(packageName) { - const packageJsonPath = path.resolve( - process.cwd(), - 'node_modules', - packageName, - 'package.json' +function checkNodeVersion(root, packageName) { + const packageJsonPath = resolveFrom( + root, + path.join(packageName, 'package.json') ); const packageJson = require(packageJsonPath); if (!packageJson.engines || !packageJson.engines.node) { diff --git a/packages/create-react-app/package.json b/packages/create-react-app/package.json index 86bd258f73..cbeb5a2ea2 100644 --- a/packages/create-react-app/package.json +++ b/packages/create-react-app/package.json @@ -28,6 +28,7 @@ "fs-extra": "^5.0.0", "hyperquest": "^2.1.2", "react-dev-utils": "^5.0.0", + "resolve-from": "^4.0.0", "semver": "^5.0.3", "tar-pack": "^3.4.0", "tmp": "0.0.33", diff --git a/packages/react-scripts/fixtures/monorepos/cra-app/.template.dependencies.json b/packages/react-scripts/fixtures/monorepos/cra-app/.template.dependencies.json new file mode 100644 index 0000000000..93d99993f2 --- /dev/null +++ b/packages/react-scripts/fixtures/monorepos/cra-app/.template.dependencies.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "comp2": "^1.0.0" + } +} diff --git a/packages/react-scripts/fixtures/monorepos/cra-app/gitignore b/packages/react-scripts/fixtures/monorepos/cra-app/gitignore new file mode 100644 index 0000000000..57078cd136 --- /dev/null +++ b/packages/react-scripts/fixtures/monorepos/cra-app/gitignore @@ -0,0 +1,24 @@ +# See https://help.github.com/ignore-files/ for more about ignoring files. + +# generated test output +testoutput.json + +# dependencies +/node_modules + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/packages/react-scripts/fixtures/monorepos/packages/cra-app1/public/favicon.ico b/packages/react-scripts/fixtures/monorepos/cra-app/public/favicon.ico similarity index 100% rename from packages/react-scripts/fixtures/monorepos/packages/cra-app1/public/favicon.ico rename to packages/react-scripts/fixtures/monorepos/cra-app/public/favicon.ico diff --git a/packages/react-scripts/fixtures/monorepos/packages/cra-app1/public/index.html b/packages/react-scripts/fixtures/monorepos/cra-app/public/index.html similarity index 100% rename from packages/react-scripts/fixtures/monorepos/packages/cra-app1/public/index.html rename to packages/react-scripts/fixtures/monorepos/cra-app/public/index.html diff --git a/packages/react-scripts/fixtures/monorepos/packages/cra-app1/public/manifest.json b/packages/react-scripts/fixtures/monorepos/cra-app/public/manifest.json similarity index 100% rename from packages/react-scripts/fixtures/monorepos/packages/cra-app1/public/manifest.json rename to packages/react-scripts/fixtures/monorepos/cra-app/public/manifest.json diff --git a/packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/App.css b/packages/react-scripts/fixtures/monorepos/cra-app/src/App.css similarity index 100% rename from packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/App.css rename to packages/react-scripts/fixtures/monorepos/cra-app/src/App.css diff --git a/packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/App.js b/packages/react-scripts/fixtures/monorepos/cra-app/src/App.js similarity index 100% rename from packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/App.js rename to packages/react-scripts/fixtures/monorepos/cra-app/src/App.js diff --git a/packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/App.test.js b/packages/react-scripts/fixtures/monorepos/cra-app/src/App.test.js similarity index 100% rename from packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/App.test.js rename to packages/react-scripts/fixtures/monorepos/cra-app/src/App.test.js diff --git a/packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/index.css b/packages/react-scripts/fixtures/monorepos/cra-app/src/index.css similarity index 100% rename from packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/index.css rename to packages/react-scripts/fixtures/monorepos/cra-app/src/index.css diff --git a/packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/index.js b/packages/react-scripts/fixtures/monorepos/cra-app/src/index.js similarity index 100% rename from packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/index.js rename to packages/react-scripts/fixtures/monorepos/cra-app/src/index.js diff --git a/packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/logo.svg b/packages/react-scripts/fixtures/monorepos/cra-app/src/logo.svg similarity index 100% rename from packages/react-scripts/fixtures/monorepos/packages/cra-app1/src/logo.svg rename to packages/react-scripts/fixtures/monorepos/cra-app/src/logo.svg diff --git a/packages/react-scripts/scripts/init.js b/packages/react-scripts/scripts/init.js index ac695d167d..5328ae2880 100644 --- a/packages/react-scripts/scripts/init.js +++ b/packages/react-scripts/scripts/init.js @@ -21,6 +21,9 @@ const execSync = require('child_process').execSync; const spawn = require('react-dev-utils/crossSpawn'); const { defaultBrowsers } = require('react-dev-utils/browsersHelper'); const os = require('os'); +const resolveFrom = require('resolve-from'); +const paths = require('../config/paths'); +const { findMonorepo } = require('react-dev-utils/workspaceUtils'); function isInGitRepository() { try { @@ -83,9 +86,12 @@ module.exports = function( ) { const ownPackageName = require(path.join(__dirname, '..', 'package.json')) .name; - const ownPath = path.join(appPath, 'node_modules', ownPackageName); + const ownPath = path.join( + resolveFrom(appPath, path.join(ownPackageName, 'package.json')), + '..' + ); const appPackage = require(path.join(appPath, 'package.json')); - const useYarn = fs.existsSync(path.join(appPath, 'yarn.lock')); + const useYarn = paths.useYarn; // Copy over some of the devDependencies appPackage.dependencies = appPackage.dependencies || {}; @@ -172,10 +178,19 @@ module.exports = function( fs.unlinkSync(templateDependenciesPath); } + // yarn ws not creating app/node_modules/.bin link to hoisted react-scripts + // -- workaround: install react-scripts again to create link + // -- bug in yarn 1.3.2, fix verified in nightly 1.4.1-20180211.2236 and 1.5.1 + // TODO: remove this workaround when CRA enforces min yarn version + const rerunYarn = useYarn && findMonorepo(appPath).isAppIncluded; + if (rerunYarn) { + console.log('Detected app in yarn workspace, running install again'); + } + // 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) { + if (!isReactInstalled(appPackage) || template || rerunYarn) { console.log(`Installing react and react-dom using ${command}...`); console.log(); diff --git a/tasks/e2e-monorepos.sh b/tasks/e2e-monorepos.sh index 635badcf21..480bb016df 100755 --- a/tasks/e2e-monorepos.sh +++ b/tasks/e2e-monorepos.sh @@ -110,25 +110,46 @@ pushd "$temp_app_path" cp -r "$root_path/packages/react-scripts/fixtures/monorepos/yarn-ws" . cd "yarn-ws" cp -r "$root_path/packages/react-scripts/fixtures/monorepos/packages" . -yarn # Test cra-app1 -cd packages/cra-app1 +pushd packages/cra-app1 +cp -r "$root_path/packages/react-scripts/fixtures/monorepos/cra-app/"* . +yarn +verifyBuild +yarn start --smoke-test +verifyTest +popd + +# ****************************************************************************** +# Test clean create-react-app inside workspace +# ****************************************************************************** +pushd packages +npx create-react-app newapp +cd newapp +yarn build +yarn start --smoke-test +CI=true yarn test --watch=no +popd + +# ****************************************************************************** +# Test create-react-app w/ shared comps inside workspace +# ****************************************************************************** +pushd packages +npx create-react-app --internal-testing-template="$root_path"/packages/react-scripts/fixtures/monorepos/cra-app cra-app2 +cd cra-app2 verifyBuild yarn start --smoke-test verifyTest # Test eject +# TODO: veriy tests can be run from other apps after eject +# -- will currently fail due to picking up ejected scripts/test.js echo yes | npm run eject verifyBuild yarn start --smoke-test verifyTest +popd -# ****************************************************************************** -# Test create-react-app inside workspace -# ****************************************************************************** -# npx create-react-app --internal-testing-template="$root_path"/packages/react-scripts/fixtures/yarn-ws/ws/cra-app1 cra-app2 -# -- above needs https://github.com/facebookincubator/create-react-app/pull/3435 to user create-react-app popd # Cleanup