1. 从0搭建CLI工具-前端脚手架

206 阅读4分钟

预先了解

yarn:nodejs包管理工具,用于安装、卸载、更新和管理Javascript包;
npm:同上;
npx:并非包管理工具,而是在指定的包中查找可执行文件(bin目录下脚本文件)的命令,比如常见的npx create-react-app my-app意思就是查找create-react-app内的可执行文件。

目标

  1. 安装 create-yzbao-app命令行输入npx create-yzbao-app my-app初始化项目
  1. 要考虑my-app目录已经存在的情况(支持 询问是否要 强制覆盖)
  1. 支持克隆远程仓库为模版(模版支持recoil、redux、react-cocos、tsdx)
  1. 默认隐藏配置文件包括 webpackBabelJest 等,支持执行eject暴露

实现方式

  1. 可以自己从0搭建一个脚手架工具(包含命令行工具create-yzbao-app和模版仓库)本文介绍的就是这种方式
  1. 另外发现create-react-app 支持指定自定义模版(继续使用create-react-app,但模版自定义)

问题调研

  1. create-react-app是如何隐藏 webpackBabelJest 等配置文件的?

下面是使用create-react-app命令创建的项目:

可以发现,所有的命令行脚本都被放到react-scripts这个包里了。

在命令行中执行react-scripts,实际执行的是./bin/react-scripts.js:

  1. create-react-app是如何解析template中的依赖的(使用脚手架创建出的项目中的package.json中的依赖是如何确定的)?
    1. template中公共的依赖全都放到react-scripts的package.json里面了
    2. 针对不同的template有不同的依赖,create-react-app采用的方案是在创建模版时,根目录创建一个template.js的配置文件,配置文件中有该模版依赖的模块:

然后在create-react-app的脚本中读取template.json中的依赖并安装,注意⚠️create-react-app创建的项目,node_modules是安装好的,直接start就能启动项目:

我们如果实现不需要这么麻烦,在创建模版时,模版本身就包含可用的package.json,create-yzbao-app不负责区分模版处理,只负责根据模版中的package.json安装。

正式开始

  1. 准备模版文件

github.com/yzbaoo/cra-…

  1. 创建create-yzbao-app项目
    1. npm init初始化package.json

      1.     在 package.json 文件中的 "keywords" 字段用于定义与你的软件包相关的关键字。这些关键字可以帮助其他开发者更容易地找到你的软件包
      2.     在 package.json 文件中的 "license" 字段用于指定软件包的许可证信息
      3.     在 package.json 文件中的 "files" 字段用于指定哪些文件或目录应该被包含在发布的软件包中
      4.     在 package.json 文件中的 "bin" 字段用于指定一些可执行文件(或者说命令行工具)的路径,这样当用户安装你的包时,这些文件就可以被链接到全局的 bin 目录,从而可以在命令行中直接执行
    2. 主要关心"bin"字段,配置为

      "bin": {

      "create-yzbao-app": "./index.js"

      },

      当用户通过 npm install create-yzbao-app -g 全局安装这个包时,index.js 就会被链接到系统的 bin 目录,用户就可以在命令行中直接执行 create-yzbao-app 命令了。

  1. 本地调试

      我们本地调试不需要安装,直接在当前目录执行npx create-yzbao-app,能看到index文件被执行了:

      用npx **这种方式,会临时下载create-react-app包,这样做的好处是可以确保使用的是最新版本的 create-react-app,而不会受到全局安装的旧版本的影响。

    1.   安装commander,配置命令行信息,拿到命令npx create-yzbao-app 中的appName

    1.   安装inquirer,创建命令行交互信息,用户可选择模版进行下载

    inquirer的type: list 和 type: select 有什么区别?

    list是个垂直排列的可选择列表,为标准选项,用户可通过键盘上下按钮进行选择;select是在list基础上的增强版本,用户可通过鼠标点击,使用字母快捷键等更丰富的交互体验。

    1.   安装download-git-repo下载代码模版

    download-git-repo('仓库','目标位置',options, callback)

    1. options.clone默认为false,true表示什么意思?

    true表示使用gitclone替代http下载,会保留克隆仓库的git历史,代码分支等信息。

    1. path.resolve(a,b)作用:

    将传入的路径片段, 解析为绝对路径

    1. process.cwd()作用:

    获取当前命令执行的目录

      打开my-app目录可以看到,模版已经下载好了:

      优化:考虑将模版文件的package.json中的信息,从命令行中获取~

    1.   安装cross-spawn, 自动执行yarn add 安装my-app的node_modules

      看了官方create-react-app的源码,它创建好的项目已经预先安装好依赖了,直接yarn start启动项目。所以我们也考虑支持。

      思路很简单,进入到项目目录,自动执行yarn install 即可:

      ok! 至此基础的脚手架就搭建好了~~


个人博客:juejin.cn/post/696611…

react官方脚手架源码:github.com/facebook/cr…

Commander 文档:github.com/tj/commande…