剧透下我们的cli create-emptyd-app 喜欢的话可以点个star ^_^
create-react-app 目录结构
├── createReactApp.js
├── index.js
├── LICENSE
├── package.json
├── README.md
├── CHANGELOG.zh-CN.md
├── yarn.lock.cached
这个部分的核心是 createReactApp.js ,整个脚本的流程如下
细节如下
1. 通过 commander 读取 命令行参数
2. 执行 createApp 函数传入命令行得到的参数 开始构建(这个函数基本在做环境兼容)
->写入初始的 package.json 文件
->如果不使用yarn的方式 并且命令行中cwd 和当前进程中的cwd 不一致的话 结束当前进程
->node 低于6.0的话使用react-scripts@0.9.x
->如果不用yarn npm的版本要大于3.0 否则 使用react-scripts@0.9.x
->如果使用 yarn 就把lock 文件添加到 应用目录中
3. 执行 run 函数生成项目基础骨架
-> 获取 react-scripts 的版本
-> 配置所有初始依赖
-> 判断是否使用 typescript
-> 从压缩文件或者路径中解析 提取PackageName
-> 检测yarn 的源是否存在问题
-> 下载基本的依赖
-> 检测 node 的版本是否符合react-scripts 的要求
-> 拉取项目模版文件
代码注释
'use strict';
// 验证包名
const validateProjectName = require('validate-npm-package-name');
const chalk = require('chalk');
const commander = require('commander');
const fs = require('fs-extra');
const path = require('path');
const execSync = require('child_process').execSync;
// 跨平台开启子进程
const spawn = require('cross-spawn');
const semver = require('semver');
const dns = require('dns');
// 临时文件系统
const tmp = require('tmp');
// 压缩解压
const unpack = require('tar-pack').unpack;
const url = require('url');
// 发送http请求
const hyperquest = require('hyperquest');
// 输出环境变量
const envinfo = require('envinfo');
const os = require('os');
const packageJson = require('./package.json');
// These files should be allowed to remain on a failed install,
// but then silently removed during the next create.
const errorLogFilePatterns = [
'npm-debug.log',
'yarn-error.log',
'yarn-debug.log',
];
let projectName;
const program = new commander.Command(packageJson.name)
.version(packageJson.version) // 设置版本号
.arguments('<project-directory>') //获取输入参数
.usage(`${
chalk.green('<project-directory>')} [options]`) // --help 时候输出的用例提示
.action(name => {
//此处的name 就对应.arguments('<project-directory>') 中的参数
projectName = name;
})
.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('--use-npm') //使用npm
.option('--use-pnp')
.option('--typescript')
.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.log(
`- a local path relative to the current working directory: ${
chalk.green(
'file:../my-react-scripts'
)}`
);
console.log(
`- a .tgz archive: ${
chalk.green(
'https://mysite.com/my-react-scripts-0.8.2.tgz'
)}`
);
console.log(
` - a .tar.gz archive: ${
chalk.green(
'https://mysite.com/my-react-scripts-0.8.2.tar.gz'
)}`
);
console.log(
` It is not needed unless you specifically want to use a fork.`
);
console.log();
console.log(
` If you have any problems, do not hesitate to file an issue:`
);
console.log(
` ${
chalk.cyan(
'https://github.com/facebook/create-react-app/issues/new'
)}`
);
console.log();
})
.parse(process.argv);
// create-emptyd-app --info 输出 操作系统等环境信息
if(program.info){
console.log(chalk.bold('\nEnvironment Info:'));
return envinfo
.run(
{
System: ['OS', 'CPU'],
Binaries: ['Node', 'npm', 'Yarn'],
Browsers: ['Chrome', 'Edge', 'Internet Explorer', 'Firefox', 'Safari'],
npmPackages: ['react', 'react-dom', 'react-scripts'],
npmGlobalPackages: ['create-react-app'],
},
{
clipboard