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: unsupportedNodeVersion
judge Node
whether the current running version is greater than v14
if 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 enterif (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 libraryfs-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 fileconflicts.length
is 0, removelog
the file, and returntrue
The console prints the following:
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
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
, npm
the version that needs to be checked, and the executionnpmInfo
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