123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- // @remove-file-on-eject
- /**
- * Copyright (c) 2015-present, Facebook, Inc.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
- 'use strict';
- const chalk = require('react-dev-utils/chalk');
- const fs = require('fs');
- const semver = require('semver');
- const path = require('path');
- // We assume that having wrong versions of these
- // in the tree will likely break your setup.
- // This is a relatively low-effort way to find common issues.
- function verifyPackageTree() {
- const depsToCheck = [
- // These are packages most likely to break in practice.
- // See https://github.com/facebook/create-react-app/issues/1795 for reasons why.
- // I have not included Babel here because plugins typically don't import Babel (so it's not affected).
- 'babel-eslint',
- 'babel-jest',
- 'babel-loader',
- 'eslint',
- 'jest',
- 'webpack',
- 'webpack-dev-server',
- ];
- // Inlined from semver-regex, MIT license.
- // Don't want to make this a dependency after ejecting.
- const getSemverRegex = () =>
- /\bv?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?\b/gi;
- const ownPackageJson = require('../../package.json');
- const expectedVersionsByDep = {};
- // Gather wanted deps
- depsToCheck.forEach(dep => {
- const expectedVersion = ownPackageJson.dependencies[dep];
- if (!expectedVersion) {
- throw new Error('This dependency list is outdated, fix it.');
- }
- if (!getSemverRegex().test(expectedVersion)) {
- throw new Error(
- `The ${dep} package should be pinned, instead got version ${expectedVersion}.`
- );
- }
- expectedVersionsByDep[dep] = expectedVersion;
- });
- // Verify we don't have other versions up the tree
- let currentDir = __dirname;
- // eslint-disable-next-line no-constant-condition
- while (true) {
- const previousDir = currentDir;
- currentDir = path.resolve(currentDir, '..');
- if (currentDir === previousDir) {
- // We've reached the root.
- break;
- }
- const maybeNodeModules = path.resolve(currentDir, 'node_modules');
- if (!fs.existsSync(maybeNodeModules)) {
- continue;
- }
- depsToCheck.forEach(dep => {
- const maybeDep = path.resolve(maybeNodeModules, dep);
- if (!fs.existsSync(maybeDep)) {
- return;
- }
- const maybeDepPackageJson = path.resolve(maybeDep, 'package.json');
- if (!fs.existsSync(maybeDepPackageJson)) {
- return;
- }
- const depPackageJson = JSON.parse(
- fs.readFileSync(maybeDepPackageJson, 'utf8')
- );
- const expectedVersion = expectedVersionsByDep[dep];
- if (!semver.satisfies(depPackageJson.version, expectedVersion)) {
- console.error(
- chalk.red(
- `\nThere might be a problem with the project dependency tree.\n` +
- `It is likely ${chalk.bold(
- 'not'
- )} a bug in Create React App, but something you need to fix locally.\n\n`
- ) +
- `The ${chalk.bold(
- ownPackageJson.name
- )} package provided by Create React App requires a dependency:\n\n` +
- chalk.green(
- ` "${chalk.bold(dep)}": "${chalk.bold(expectedVersion)}"\n\n`
- ) +
- `Don't try to install it manually: your package manager does it automatically.\n` +
- `However, a different version of ${chalk.bold(
- dep
- )} was detected higher up in the tree:\n\n` +
- ` ${chalk.bold(chalk.red(maybeDep))} (version: ${chalk.bold(
- chalk.red(depPackageJson.version)
- )}) \n\n` +
- `Manually installing incompatible versions is known to cause hard-to-debug issues.\n\n` +
- chalk.red(
- `If you would prefer to ignore this check, add ${chalk.bold(
- 'SKIP_PREFLIGHT_CHECK=true'
- )} to an ${chalk.bold('.env')} file in your project.\n` +
- `That will permanently disable this message but you might encounter other issues.\n\n`
- ) +
- `To ${chalk.green(
- 'fix'
- )} the dependency tree, try following the steps below in the exact order:\n\n` +
- ` ${chalk.cyan('1.')} Delete ${chalk.bold(
- 'package-lock.json'
- )} (${chalk.underline('not')} ${chalk.bold(
- 'package.json'
- )}!) and/or ${chalk.bold('yarn.lock')} in your project folder.\n` +
- ` ${chalk.cyan('2.')} Delete ${chalk.bold(
- 'node_modules'
- )} in your project folder.\n` +
- ` ${chalk.cyan('3.')} Remove "${chalk.bold(
- dep
- )}" from ${chalk.bold('dependencies')} and/or ${chalk.bold(
- 'devDependencies'
- )} in the ${chalk.bold(
- 'package.json'
- )} file in your project folder.\n` +
- ` ${chalk.cyan('4.')} Run ${chalk.bold(
- 'npm install'
- )} or ${chalk.bold(
- 'yarn'
- )}, depending on the package manager you use.\n\n` +
- `In most cases, this should be enough to fix the problem.\n` +
- `If this has not helped, there are a few other things you can try:\n\n` +
- ` ${chalk.cyan('5.')} If you used ${chalk.bold(
- 'npm'
- )}, install ${chalk.bold(
- 'yarn'
- )} (http://yarnpkg.com/) and repeat the above steps with it instead.\n` +
- ` This may help because npm has known issues with package hoisting which may get resolved in future versions.\n\n` +
- ` ${chalk.cyan('6.')} Check if ${chalk.bold(
- maybeDep
- )} is outside your project directory.\n` +
- ` For example, you might have accidentally installed something in your home folder.\n\n` +
- ` ${chalk.cyan('7.')} Try running ${chalk.bold(
- `npm ls ${dep}`
- )} in your project folder.\n` +
- ` This will tell you which ${chalk.underline(
- 'other'
- )} package (apart from the expected ${chalk.bold(
- ownPackageJson.name
- )}) installed ${chalk.bold(dep)}.\n\n` +
- `If nothing else helps, add ${chalk.bold(
- 'SKIP_PREFLIGHT_CHECK=true'
- )} to an ${chalk.bold('.env')} file in your project.\n` +
- `That would permanently disable this preflight check in case you want to proceed anyway.\n\n` +
- chalk.cyan(
- `P.S. We know this message is long but please read the steps above :-) We hope you find them helpful!\n`
- )
- );
- process.exit(1);
- }
- });
- }
- }
- module.exports = verifyPackageTree;
|