原文链接:http://axuebin.com/articles/fe-solution/cli/cra.html,转载请联系
Create React App is an officially supported way to create single-page React applications. It offers a modern build setup with no configuration.
create react app
是 React
官方创建单页应用的方式,为了方便,下文皆简称 CRA
。
它的核心思想我理解主要是:
- 脚手架核心功能中心化:使用
npx
保证每次用户使用的都是最新版本,方便功能的升级 - 模板去中心化:方便地进行模板管理,这样也允许用户自定义模板
- 脚手架逻辑和初始化代码逻辑分离:在
cra
中只执行了脚手架相关逻辑,而初始化代码的逻辑在react-scripts
包里执行
本文主要就是通过源码分析对上述的理解进行阐述。
按照自己的理解,画了个流程图,大家可以带着该流程图去阅读源码(主要包含两个部分 create-react-app
和 react-scripts/init
):
如果图片不清晰可以微信搜索公众号 玩相机的程序员,回复 CRA
获取。
0. 用法
CRA
的用法很简单,两步:
- 安装:
npm install -g create-react-app
- 使用:
create-react-app my-app
这是常见的用法,会在全局环境下安装一个 CRA
,在命令行中可以通过 create react app
直接使用。
现在更推荐的用法是使用 npx
来执行 create react app
:
npx create-react-app my-app
这样确保每次执行 create-reat-app
使用的都是 npm
上最新的版本。
注:npx 是 npm 5.2+
之后引入的功能,如需使用需要 check
一下本地的 npm
版本。
默认情况下,CRA
命令只需要传入 project-directory
即可,不需要额外的参数,更多用法查看:https://create-react-app.dev/docs/getting-started#creating-an-app,就不展开了。
可以看一下官方的 Demo 感受一下:
我们主要还是通过 CRA
的源码来了解一下它的思路。
1. 入口
本文中的
create-react-app
版本为4.0.1
。若阅读本文时存在break change
,可能就需要自己理解一下啦
按照正常逻辑,我们在 package.json
里找到了入口文件:
{
"bin": {
"create-react-app": "./index.js"
}
}
index.js
里的逻辑比较简单,判断了一下 node
环境是否是 10
以上,就调用 init
了,所以核心还是在 init
方法里。
// index.js
const {
init } = require('./createReactApp');
init();
打开 createReactApp.js
文件一看,好家伙,1017 行代码(别慌,跟着我往下看,1000 行代码也分分钟看明白)
吐槽一下,虽然代码逻辑写得很清楚,但是为啥不拆几个模块呢?
找到 init
方法之后发现,其实就执行了一个 Promise
:
// createReactApp.js
function init() {
checkForLatestVersion()
.catch()
.then();
}
注意这里是先 catch
再 then
。
跟着我往下看呗 ~ 一步一步理清楚 CRA
,你也能依葫芦画瓢造一个。
2. 检查版本
checkForLatestVersion
就做了一件事,获取 create-react-app
这个 npm
包的 latest
版本号。
如果你想获取某个 npm
包的版本号,可以通过开放接口 [https://registry.npmjs.org/-/package/{pkgName}/dist-tags](https://registry.npmjs.org/-/package/%7BpkgName%7D/dist-tags "https://registry.npmjs.org/-/package/{pkgName}/dist-tags")
获得,其返回值为:
{
"next": "4.0.0-next.117",
"latest": "4.0.1",
"canary": "3.3.0-next.38"
}
如果你想获取某个 npm
包完整信息,可以通过开放接口 [https://registry.npmjs.org/{pkgName}](https://registry.npmjs.org/%7BpkgName%7D "https://registry.npmjs.org/{pkgName}")
获得,其返回值为:
{
"name": "create-react-app", # 包名
"dist-tags": {
}, # 版本语义化标签
"versions": {
}, # 所有版本信息
"readme": "", # README 内容(markdown 文本)
"maintainers": [],
"time": {
}, # 每个版本的发布时间
"license": "",
"readmeFilename": "README.md",
"description": "",
"homepage": "", # 主页
"keywords": [], # 关键词
"repository": {
}, # 代码仓库
"bugs": {
}, # 提 bug 链接
"users": {