问题
从零开始创建和配置React项目非常有挑战性,不仅要做出许多设计选择——要包含哪些库、要使用哪些工具、要启用哪些语言功能——而且手动创建的那些应用在特性上都各不相同。项目的这些特性也会增加团队中新成员的学习成本。
解决方案
create-react-app是一个用于构建React单页面应用的工具。生成的项目具有标准的文件结构和默认配置,使用React Scripts库来构建、测试和运行代码,并且具有标准的Webpack配置和标准的语言特性。
任何一个使用过create-react-app创建的应用的开发人员在看到同样由create-react-app创建的应用时,都会感觉十分熟悉。他们了解这种项目的结构,知道可以使用哪些语言特性。create-react-app易于使用,而且功能完善,其创建的应用包含典型应用所需的所有特性:从Babel配置和file loader(文件加载器)到测试库和开发服务器。
如果你是React新手,或者需要轻松创建通用单页面应用,那么可以考虑使用create-react-app。
你可以在机器上全局安装create-react-app命令,但我们不鼓励这样做。我们推荐使用npx调用create-react-app来创建应用。借助npx可以确保你一直使用最新版本的create-react-app来构建应用:
这个命令会创建一个名为 my-app 的项目文件夹。应用默认使用JavaScript。如果你希望使用TypeScript作为开发语言,create-react-app也提供了选项:
如果你已经安装了yarn包管理器,并发现项目默认使用yarn作为包管理器,对此你不必惊讶,因为create-react-app也是Facebook公司开发的。如果你希望使用npm作为包管理器,那么可以使用--use-npm命令,或者进入项目文件夹删除 yarn.lock 文件,然后使用npm install命令重新安装包:
你可以使用start命令来启动应用:
如图1-1所示,这个命令在端口3000启动服务器,并且在浏览器打开应用的主页。
图1-1:默认生成的应用主页
这个服务器将应用打包为一个单一的、大的JavaScript文件(bundle)。这个文件将所有组件挂载到 public/index.html 中的<div>标签上:
生成组件的代码的入口是 src/index.js 文件(如果你使用的是TypeScript,则为 src/index.tsx ):
这个文件渲染了<App>组件,该组件自同目录的 App.js (或 App.tsx )文件导入:
如果你在应用运行后编辑这个文件,那么浏览器中的页面会自动更新。
当你准备将代码交付到生产环境时,你需要生成一组可以部署到标准Web服务器上的静态文件。为此,可以运行build命令:
build命令创建一个 build 目录,并生成一组静态文件,如图1-2所示。
图1-2: build 目录中生成的文件
可以看到,build命令从 public/ 目录中直接复制了一些文件。应用的代码被编译成浏览器兼容的JavaScript,并存储在 static/js 目录内的一个或多个文件中。CSS被拼接在一起并存储在 static/css 目录中。有几个文件添加了散列ID,以使得在部署应用时浏览器下载的是最新的代码,而不是一些旧的缓存版本。
讨论
create-react-app不仅可以创建新的React应用,而且可以让你的React应用的工具与库版本保持最新。你可以像升级其他库那样升级react-scripts:通过直接更改版本号并重新运行npm install。有了react-scripts,你不再需要管理一系列Babel插件、postcss库,或者维护一个复杂的 webpack.config.js 文件。
当然,所有的配置仍然存在,只不过被隐藏在了 react-scripts 目录中。如果进入这个目录,你会找到包括所有Babel配置以及各种file loader的 webpack.config.js 文件。正因为react-scripts是一个库,所以你可以像更新其他依赖项一样更新它的版本。
如果你想自己管理这些配置,也是可以做到的。eject命令可以将配置暴露在项目中:
然而,这是一个单向操作,如果你输入了这个命令,那么就无法还原了。所以在输入之前,请务必考虑清楚。你可能发现在应用eject之前的配置已经够用了。例如,开发人员经常会通过这个命令来将项目切换到TypeScript,但其实在创建应用时增加--template typescript选项就可以了。
开发人员使用eject命令的另一个常见原因是代理Web服务。React应用通常需要访问一些单独的后端API,此时开发人员一般会配置Webpack来将本地开发服务代理到这个远程目标服务。现在,你可以通过在 package.json 文件中设置proxy字段来达到这个目的:
如果你的代码需要访问非本地的API(例如 /api/thing ),那么配置该字段后react-scripts会自动将这个请求代理到 http://myapiserver/api/thing 。
如果可以,尽量避免运行eject命令。请查阅create-react-app文档( https://oreil.ly/99Ied )来确认是否可以通过其他方式达到你的目的。
你可以从GitHub网站下载JavaScript( https://oreil.ly/UK0dZ )和TypeScript( https://oreil.ly/oOSo9 )源码。