var currentNodeVersion = process.versions.node;
var semver = currentNodeVersion.split('.');
var major = semver[0];
if (major < 8) {
console.error(
'You are running Node ' +
currentNodeVersion +
'.\n' +
'Create React App requires Node 8 or higher. \n' +
'Please update your version of Node.'
);
process.exit(1);
}
require('./createReactApp');
在create-react-app/index.js
中,首先获取了进程中的node
版本号,并通过截取获得主版本号,如果主版本号小于8,则提示用户应该升级node
版本并退出进程,主要的逻辑还是在createReactApp
中。
createReactApp
主要的三个核心函数:
createApp
作环境和命令行参数的处理run
根据参数获取需要安装的依赖文件install
安装依赖
// 为终端输出的文字添加颜色,增加区别
const chalk = require('chalk');
// 轻量的node命令行工具 可以处理用户终端输入的命令行参数
const commander = require('commander');
const dns = require('dns');
// 可以输出当前设备的硬件及软件信息
const envinfo = require('envinfo');
const execSync = require('child_process').execSync;
// 文件的处理的模块
const fs = require('fs-extra');
const hyperquest = require('hyperquest');
// 提供终端进行交互的功能
const inquirer = require('inquirer');
const os = require('os');
const path = require('path');
// 规范化版本工具库
const semver = require('semver');
// 跨平台的spawn解决方案
const spawn = require('cross-spawn');
// 临时文件工具库
const tmp = require('tmp');
const unpack = require('tar-pack').unpack;
const url = require('url');
// 验证包名是否被占用的工具
const validateProjectName = require('validate-npm-package-name');
const packageJson = require('./package.json');
createReactApp.js
中首先引入项目所需要的模块,以下几个模块是脚手架工具非常常用的工具
chalk
commander
semver
spawn
inquirer
validateProjectName
// 获取命令行参数
const program = new commander.Command(packageJson.name)
.version(packageJson.version)
.arguments('<project-directory>') // create-react-app 唯一参数
.usage(`${
chalk.green('<project-directory>')} [options]`) // 用法介绍
.action(name => {
projectName = name; // create-react-app my-react 这里name就是my-react
})
.option('--verbose', 'print additional logs')
.option('--info', 'print environment debug info')
.option(
'--scripts-version <alternative-package>',
'use a non-standard version of react-scripts' // 使用不标准版本的react-scripts
)
.option(
'--template <path-to-template>',
'specify a template for the created project'
)
.option('--use-npm') // 使用npm
.option('--use-pnp') // 使用pnp
// TODO: Remove this in next major release.
.option( // 使用typescript 将在下个主版本移除
'--typescript',
'(this option will be removed in favour of templates in the next major release of create-react-app)'
)
.allowUnknownOption()
.on('--help', () => {
// 提供帮助信息
console.log(` Only ${
chalk.green('<project-directory>')} is required.`);
console.log();
console.log(
` A custom ${
chalk.cyan('--scripts-version')} can be one of:`
);
console.log(` - a specific npm version: ${
chalk.green('0.8.2')}`);
console.log(` - a specific npm tag: ${
chalk.green('@next')}`);
console.log(
` - a custom fork published on npm: ${
chalk.green(
'my-react-scripts'
)}`
);
console.