深入浅出React和Redux
上QQ阅读APP看书,第一时间看更新

1.3 分解React应用

前面我们提到过,React应用实际上依赖于一个很大很复杂的技术栈,我们使用create-react-app避免在一开始就费太多精力配置技术栈,不过现在是时候了解一下这个技术栈了。

我们启动React应用的命令是npm start,看一看package.json中对start脚本的定义,如下所示:

"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test --env=jsdom",
  "eject": "react-scripts eject"
}

可以看到,start命令实际上是调用了react-scripts这个命令,react-scripts是create-react-app添加的一个npm包,所有的配置文件都藏在node_modules/react-scripts目录下,我们当然可以钻进这个目录去一探究竟,但是也可以使用eject方法来看清楚背后的原理。

你可以发现package.json文件中和start并列还有其他几个命令,其中build可以创建生产环境优化代码,test用于单元测试,还有一个eject命令很有意思。

这个eject(弹射)命令做的事情,就是把潜藏在react-scripts中的一系列技术栈配置都“弹射”到应用的顶层,然后我们就可以研究这些配置细节了,而且可以更灵活地定制应用的配置。

注意

eject命令是不可逆的,就好像战斗机飞行员选择“弹射”出驾驶舱,等于是放弃了这架战斗机,是不可能再飞回驾驶舱的。所以,当你执行eject之前,最好做一下备份。

我们在命令行下执行下面的命令,完成“弹射”操作:

npm run eject

这个命令会让改变一些文件,也会添加一些文件。

当前目录下会增加两个目录,一个是scripts,另一个是config,同时,package.json文件中的scripts部分也发生了变化:

"scripts": {
  "start": "node scripts/start.js",
  "build": "node scripts/build.js",
  "test": "node scripts/test.js --env=jsdom"
},

从此之后,start脚本将使用scripts目录下的start.js,而不是node_modules目录下的react-scripts,弹射成功,再也回不去了。

在config目录下的webpack.config.dev.js文件,定制的就是npm start所做的构造过程,其中有一段关于babel的定义:

{
  test: /\.(js|jsx)$/,
  include: paths.appSrc,
  loader: 'babel',
  query: {
    // This is a feature of `babel-loader` for webpack (not Babel itself).
    // It enables caching results in ./node_modules/.cache/babel-loader/
    // directory for faster rebuilds.
    cacheDirectory: true
  }
},

代码中paths.appSrc的值就是src,所以这段配置的含义指的是所有以js或者jsx为扩展名的文件,都会由babel所处理。

并不是所有的浏览器都支持所有ES6语法,但是有了babel,我们就可以不用顾忌太多,因为babel会把ES6语法的JavaScript代码转译(transpile)成浏览器普遍支持的JavaScript代码,实际上,在React的社区中,不使用ES6语法写代码才显得奇怪。