预先了解
yarn:nodejs包管理工具,用于安装、卸载、更新和管理Javascript包;
npm:同上;
npx:并非包管理工具,而是在指定的包中查找可执行文件(bin目录下脚本文件)的命令,比如常见的npx create-react-app my-app意思就是查找create-react-app内的可执行文件。
目标
-
安装
create-yzbao-app命令行输入npx create-yzbao-app my-app初始化项目
-
要考虑my-app目录已经存在的情况(支持 询问是否要 强制覆盖)
-
支持克隆远程仓库为模版(模版支持recoil、redux、react-cocos、tsdx)
-
默认隐藏配置文件包括
webpack、Babel、Jest等,支持执行eject暴露
实现方式
-
可以自己从0搭建一个脚手架工具(包含命令行工具
create-yzbao-app和模版仓库)本文介绍的就是这种方式
-
另外发现
create-react-app支持指定自定义模版(继续使用create-react-app,但模版自定义)
问题调研
-
create-react-app是如何隐藏
webpack、Babel、Jest等配置文件的?
下面是使用create-react-app命令创建的项目:
可以发现,所有的命令行脚本都被放到react-scripts这个包里了。
在命令行中执行react-scripts,实际执行的是./bin/react-scripts.js:
-
create-react-app是如何解析template中的依赖的(使用脚手架创建出的项目中的package.json中的依赖是如何确定的)?
- template中公共的依赖全都放到react-scripts的package.json里面了
- 针对不同的template有不同的依赖,create-react-app采用的方案是在创建模版时,根目录创建一个template.js的配置文件,配置文件中有该模版依赖的模块:
然后在create-react-app的脚本中读取template.json中的依赖并安装,注意⚠️create-react-app创建的项目,node_modules是安装好的,直接start就能启动项目:
我们如果实现不需要这么麻烦,在创建模版时,模版本身就包含可用的package.json,create-yzbao-app不负责区分模版处理,只负责根据模版中的package.json安装。
正式开始
-
准备模版文件
-
创建create-yzbao-app项目
-
npm init初始化package.json- 在
package.json文件中的 "keywords" 字段用于定义与你的软件包相关的关键字。这些关键字可以帮助其他开发者更容易地找到你的软件包 - 在
package.json文件中的 "license" 字段用于指定软件包的许可证信息 - 在
package.json文件中的 "files" 字段用于指定哪些文件或目录应该被包含在发布的软件包中 - 在
package.json文件中的 "bin" 字段用于指定一些可执行文件(或者说命令行工具)的路径,这样当用户安装你的包时,这些文件就可以被链接到全局的bin目录,从而可以在命令行中直接执行
- 在
-
主要关心"bin"字段,配置为
"bin": {
"create-yzbao-app": "./index.js"
},
当用户通过
npm installcreate-yzbao-app-g全局安装这个包时,index.js就会被链接到系统的bin目录,用户就可以在命令行中直接执行 create-yzbao-app 命令了。 -
-
本地调试
我们本地调试不需要安装,直接在当前目录执行
npx create-yzbao-app,能看到index文件被执行了:用npx **这种方式,会临时下载
create-react-app包,这样做的好处是可以确保使用的是最新版本的create-react-app,而不会受到全局安装的旧版本的影响。-
安装commander,配置命令行信息,拿到命令npx create-yzbao-app 中的appName
-
安装inquirer,创建命令行交互信息,用户可选择模版进行下载
inquirer的type: list 和 type: select 有什么区别?
list是个垂直排列的可选择列表,为标准选项,用户可通过键盘上下按钮进行选择;select是在list基础上的增强版本,用户可通过鼠标点击,使用字母快捷键等更丰富的交互体验。
-
安装download-git-repo下载代码模版
download-git-repo('仓库','目标位置',options, callback)
- options.clone默认为false,true表示什么意思?
true表示使用gitclone替代http下载,会保留克隆仓库的git历史,代码分支等信息。
- path.resolve(a,b)作用:
将传入的路径片段, 解析为绝对路径
- process.cwd()作用:
获取当前命令执行的目录
打开my-app目录可以看到,模版已经下载好了:
优化:考虑将模版文件的package.json中的信息,从命令行中获取~
-
安装cross-spawn, 自动执行yarn add 安装my-app的node_modules
看了官方
create-react-app的源码,它创建好的项目已经预先安装好依赖了,直接yarn start启动项目。所以我们也考虑支持。思路很简单,进入到项目目录,自动执行yarn install 即可:
ok! 至此基础的脚手架就搭建好了~~
-
react官方脚手架源码:github.com/facebook/cr…
Commander 文档:github.com/tj/commande…