读 create-react-app 源码构建自己的脚手架

剧透下我们的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 ,整个脚本的流程如下
执行 createApp 函数传入命令行得到的参数 开始构建(这个函数基本在做环境兼容) 执行 run 函数生成项目基础骨架

细节如下

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值