Interpretation of /packages/create-react-app core source code of create-react-app scaffolding (4)

Interpretation of createReactApp function

The directory of the create-react-app scaffolding is/packages/create-react-app/createReactApp.js

Function definition: create react app

The source code is as follows:

function createApp(name, verbose, version, template, useYarn, usePnp) {
    
    
  const unsupportedNodeVersion = !semver.satisfies(
    // Coerce strings with metadata (i.e. `15.0.0-nightly`).
    semver.coerce(process.version),
    '>=14'
  );

  if (unsupportedNodeVersion) {
    
    
    console.log(
      chalk.yellow(
        `You are using Node ${
      
      process.version} so the project will be bootstrapped with an old unsupported version of tools.\n\n` +
          `Please update to Node 14 or higher for a better, fully supported experience.\n`
      )
    );
    // Fall back to latest supported react-scripts on Node 4
    version = '[email protected]';
  }

  const root = path.resolve(name);
  const appName = path.basename(root);

  checkAppName(appName);
  fs.ensureDirSync(name);
  if (!isSafeToCreateProjectIn(root, name)) {
    
    
    process.exit(1);
  }
  console.log();

  console.log(`Creating a new React app in ${
      
      chalk.green(root)}.`);
  console.log();

  const packageJson = {
    
    
    name: appName,
    version: '0.1.0',
    private: true,
  };
  fs.writeFileSync(
    path.join(root, 'package.json'),
    JSON.stringify(packageJson, null, 2) + os.EOL
  );

  const originalDirectory = process.cwd();
  process.chdir(root);
  if (!useYarn && !checkThatNpmCanReadCwd()) {
    
    
    process.exit(1);
  }

  if (!useYarn) {
    
    
    const npmInfo = checkNpmVersion();
    if (!npmInfo.hasMinNpm) {
    
    
      if (npmInfo.npmVersion) {
    
    
        console.log(
          chalk.yellow(
            `You are using npm ${
      
      npmInfo.npmVersion} so the project will be bootstrapped with an old unsupported version of tools.\n\n` +
              `Please update to npm 6 or higher for a better, fully supported experience.\n`
          )
        );
      }
      // Fall back to latest supported react-scripts for npm 3
      version = '[email protected]';
    }
  } else if (usePnp) {
    
    
    const yarnInfo = checkYarnVersion();
    if (yarnInfo.yarnVersion) {
    
    
      if (!yarnInfo.hasMinYarnPnp) {
    
    
        console.log(
          chalk.yellow(
            `You are using Yarn ${
      
      yarnInfo.yarnVersion} together with the --use-pnp flag, but Plug'n'Play is only supported starting from the 1.12 release.\n\n` +
              `Please update to Yarn 1.12 or higher for a better, fully supported experience.\n`
          )
        );
        // 1.11 had an issue with webpack-dev-middleware, so better not use PnP with it (never reached stable, but still)
        usePnp = false;
      }
      if (!yarnInfo.hasMaxYarnPnp) {
    
    
        console.log(
          chalk.yellow(
            'The --use-pnp flag is no longer necessary with yarn 2 and will be deprecated and removed in a future release.\n'
          )
        );
        // 2 supports PnP by default and breaks when trying to use the flag
        usePnp = false;
      }
    }
  }

  run(
    root,
    appName,
    version,
    verbose,
    originalDirectory,
    template,
    useYarn,
    usePnp
  );
}

function analysis

Debug code display: unsupportedNodeVersionjudge Nodewhether the current running version is greater than v14if less than, then print a prompt message

1. checkAppName(appName)

function checkAppName(appName) {
    
    
  const validationResult = validateProjectName(appName);
  if (!validationResult.validForNewPackages) {
    
          // true取反,为false,不进入
    console.error(
      chalk.red(
        `Cannot create a project named ${
      
      chalk.green(
          `"${ 
        appName}"`
        )} because of npm naming restrictions:\n`
      )
    );
    [
      ...(validationResult.errors || []),
      ...(validationResult.warnings || []),
    ].forEach(error => {
    
    
      console.error(chalk.red(`  * ${
      
      error}`));
    });
    console.error(chalk.red('\nPlease choose a different project name.'));
    process.exit(1);
  }

  // TODO: there should be a single place that holds the dependencies
  const dependencies = ['react', 'react-dom', 'react-scripts'].sort();
  if (dependencies.includes(appName)) {
    
    
    console.error(
      chalk.red(
        `Cannot create a project named ${
      
      chalk.green(
          `"${ 
        appName}"`
        )} because a dependency with the same name exists.\n` +
          `Due to the way npm works, the following names are not allowed:\n\n`
      ) +
        chalk.cyan(dependencies.map(depName => `  ${
      
      depName}`).join('\n')) +
        chalk.red('\n\nPlease choose a different project name.')
    );
    process.exit(1);
  }
}
  • if (!validationResult.validForNewPackages) // true negation, false, do not enter
  • if (dependencies.includes(appName)) { // false
  • Check the app name after execution;

2. Create the project root directory

  • Continue to execute fs.ensureDirSync(fs is a three-party library fs-extra) means to create a directory asynchronously. At this point, you can see the directory under the current root directorymy-app
  • Judging that isSafeToCreateProjectIn(root,name)the conflicting file conflicts.lengthis 0, remove logthe file, and returntrue
    [External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-X1wZlxaq-1658397798504)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp /b65c93ecc10248b98db7b1bbc5c7da2a~tplv-k3u1fbpfcp-watermark.image?)]

The console prints the following:
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-qZxCiOOW-1658397798505)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp /91c8566f9dcd4e47a05a4584ee9c742a~tplv-k3u1fbpfcp-watermark.image?)]

3. Write package.json

Write package.json configuration for initialization project

  const packageJson = {
    
    
    name: appName,
    version: '0.1.0',
    private: true,
  };
  fs.writeFileSync(
    path.join(root, 'package.json'),
    JSON.stringify(packageJson, null, 2) + os.EOL
  );

Go to the newly created project directory to view, you can see

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-AbCd0wQg-1658397798506)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp /50977e37aa4d43508b5178b7ed40c26c~tplv-k3u1fbpfcp-watermark.image?)]

4. Execute checkThatNpmCanReadCwd

// 不使用用yarn 而且npm执行有问题,报错,异常退出
 if (!useYarn && !checkThatNpmCanReadCwd()) {
    
    
    process.exit(1);
  }

The process.chdir() method is the process module's built-in API for changing the current working directory.
Continue to execute, execute the function checkThatNpmCanReadCwd, and see the specific meaning [interpretation of the core source code of create-react-app scaffolding (2)]

returntrue

5. useYarn

 if (!useYarn) {
    
    
    const npmInfo = checkNpmVersion();
    if (!npmInfo.hasMinNpm) {
    
    
      if (npmInfo.npmVersion) {
    
    
        console.log(
          chalk.yellow(
            `You are using npm ${
      
      npmInfo.npmVersion} so the project will be bootstrapped with an old unsupported version of tools.\n\n` +
              `Please update to npm 6 or higher for a better, fully supported experience.\n`
          )
        );
      }
      // Fall back to latest supported react-scripts for npm 3
      version = '[email protected]';
    }
  } else if (usePnp) {
    
    
    const yarnInfo = checkYarnVersion();
    if (yarnInfo.yarnVersion) {
    
    
      if (!yarnInfo.hasMinYarnPnp) {
    
    
        console.log(
          chalk.yellow(
            `You are using Yarn ${
      
      yarnInfo.yarnVersion} together with the --use-pnp flag, but Plug'n'Play is only supported starting from the 1.12 release.\n\n` +
              `Please update to Yarn 1.12 or higher for a better, fully supported experience.\n`
          )
        );
        // 1.11 had an issue with webpack-dev-middleware, so better not use PnP with it (never reached stable, but still)
        usePnp = false;
      }
      if (!yarnInfo.hasMaxYarnPnp) {
    
    
        console.log(
          chalk.yellow(
            'The --use-pnp flag is no longer necessary with yarn 2 and will be deprecated and removed in a future release.\n'
          )
        );
        // 2 supports PnP by default and breaks when trying to use the flag
        usePnp = false;
      }
    }
  }

If it is not used yarn, it is used npm, npmthe version that needs to be checked, and the executionnpmInfo

[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-oAu2zVsb-1658397798506)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp /ce8d0a6afe1f48f2912cbd3ac9fd1b49~tplv-k3u1fbpfcp-watermark.image?)]

6. execute run


  run(
    root,
    appName,
    version,
    verbose,
    originalDirectory,
    template,
    useYarn,
    usePnp
  );

So far, the main source code of creating app function has been interpreted

Guess you like

Origin blog.csdn.net/gkf6104/article/details/125918055