该项目是通过 Create React App 启动的。
您将在下面找到有关如何执行常见任务的一些信息。
您可以在此处找到本指南的最新版本。
<title>
public
文件夹public
文件夹.env
中添加开发环境变量<meta>
标签npm start
未检测到更改npm test
在 macOS Sierra 上挂起npm run build
退出太早npm run build
在 Heroku 上失败npm run build
无法缩小Create React App分为两个包:
create-react-app
是一个全局命令行实用程序,用于创建新项目。react-scripts
是生成的项目(包括这个项目)中的开发依赖项。您几乎不需要更新create-react-app
本身:它将所有设置委托给react-scripts
。
当您运行create-react-app
时,它始终使用最新版本的react-scripts
创建项目,因此您将自动获得新创建的应用程序中的所有新功能和改进。
要将现有项目更新到新版本的react-scripts
,请打开更改日志,找到您当前使用的版本(如果不确定,请检查此文件夹中的package.json
),然后应用较新版本的迁移说明版本。
在大多数情况下,在package.json
中更改react-scripts
版本并在此文件夹中运行npm install
就足够了,但最好查阅变更日志以了解潜在的重大更改。
我们致力于将重大更改保持在最低限度,以便您可以轻松升级react-scripts
。
我们随时欢迎您的反馈。
创建后,您的项目应如下所示:
my-app/
README.md
node_modules/
package.json
public/
index.html
favicon.ico
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
对于要构建的项目,这些文件必须具有准确的文件名:
public/index.html
是页面模板;src/index.js
是 JavaScript 入口点。您可以删除或重命名其他文件。
您可以在src
内创建子目录。为了更快地重建,Webpack 仅处理src
内的文件。
您需要将所有 JS 和 CSS 文件放入src
中,否则 Webpack 将看不到它们。
public/index.html
中只能使用public
内的文件。
请阅读下面的说明,了解如何使用 JavaScript 和 HTML 中的资源。
但是,您可以创建更多顶级目录。
它们不会包含在生产版本中,因此您可以将它们用于文档等内容。
在项目目录中,您可以运行:
npm start
在开发模式下运行应用程序。
在浏览器中打开http://localhost:3000即可查看。
如果您进行编辑,页面将重新加载。
您还将在控制台中看到任何 lint 错误。
npm test
在交互式监视模式下启动测试运行程序。
有关详细信息,请参阅有关运行测试的部分。
npm run build
将用于生产的应用程序构建到build
文件夹。
它在生产模式下正确捆绑 React 并优化构建以获得最佳性能。
构建被缩小,文件名包含哈希值。
您的应用程序已准备好部署!
有关详细信息,请参阅有关部署的部分。
npm run eject
注意:这是一种单向操作。一旦eject
就无法再返回!
如果您对构建工具和配置选择不满意,可以随时eject
。此命令将从您的项目中删除单个构建依赖项。
相反,它会将所有配置文件和传递依赖项(Webpack、Babel、ESLint 等)复制到您的项目中,以便您可以完全控制它们。除eject
之外的所有命令仍然有效,但它们将指向复制的脚本,以便您可以调整它们。此时你只能靠自己了。
您不必使用eject
。精选的功能集适合中小型部署,您不应该觉得有义务使用此功能。但是我们知道,如果您在准备好使用时无法对其进行自定义,则该工具将没有用处。
默认情况下,生成的项目使用最新版本的React。
您可以参阅 React 文档以获取有关支持的浏览器的更多信息。
该项目支持最新 JavaScript 标准的超集。
除了ES6语法特性外,还支持:
了解有关不同提案阶段的更多信息。
虽然我们建议谨慎使用实验性提案,但 Facebook 在产品代码中大量使用了这些功能,因此如果这些提案将来发生任何变化,我们打算提供代码修改。
请注意,该项目仅包含一些 ES6 polyfill :
Object.assign()
通过object-assign
。promise
来Promise
。whatwg-fetch
fetch()
。如果您使用任何其他需要运行时支持的 ES6+ 功能(例如Array.from()
或Symbol
),请确保您手动包含适当的 polyfill,或者您的目标浏览器已经支持它们。
另请注意,使用一些较新的语法功能(例如for...of
或[...nonArrayValue]
会导致 Babel 发出依赖于 ES6 运行时功能的代码,并且如果没有 polyfill,可能无法工作。如有疑问,请使用 Babel REPL 来查看特定语法编译后的结果。
要在您喜欢的文本编辑器中配置语法突出显示,请前往相关的 Babel 文档页面并按照说明进行操作。涵盖了一些最受欢迎的编辑器。
注意:此功能适用于
[email protected]
及更高版本。
它也仅适用于 npm 3 或更高版本。
一些编辑器(包括 Sublime Text、Atom 和 Visual Studio Code)提供了 ESLint 插件。
它们不需要进行 linting。您应该可以在终端和浏览器控制台中看到 linter 输出。但是,如果您希望 lint 结果直接显示在编辑器中,则可以执行一些额外的步骤。
您需要首先为您的编辑器安装 ESLint 插件。然后,将一个名为.eslintrc
的文件添加到项目根目录:
{
"extends" : "react-app"
}
现在您的编辑器应该报告 linting 警告。
请注意,即使您进一步编辑.eslintrc
文件,这些更改也只会影响编辑器集成。它们不会影响终端和浏览器内的 lint 输出。这是因为 Create React App 有意提供了一组最小的规则来发现常见错误。
如果您想为项目强制实施编码风格,请考虑使用 Prettier 而不是 ESLint 风格规则。
目前仅 Visual Studio Code 和 WebStorm 支持此功能。
Visual Studio Code 和 WebStorm 支持使用 Create React App 进行开箱即用的调试。这使您作为开发人员能够在不离开编辑器的情况下编写和调试 React 代码,最重要的是,它使您能够拥有连续的开发工作流程,其中上下文切换最少,因为您不必在工具之间切换。
您需要安装最新版本的 VS Code 和 VS Code Chrome 调试器扩展。
然后将下面的块添加到您的launch.json
文件中,并将其放入应用程序根目录的.vscode
文件夹中。
{
"version" : " 0.2.0 " ,
"configurations" : [{
"name" : " Chrome " ,
"type" : " chrome " ,
"request" : " launch " ,
"url" : " http://localhost:3000 " ,
"webRoot" : " ${workspaceRoot}/src " ,
"sourceMapPathOverrides" : {
"webpack:///src/*" : " ${webRoot}/* "
}
}]
}
注意:如果您通过 HOST 或 PORT 环境变量进行调整,则 URL 可能会有所不同。
通过运行npm start
启动应用程序,然后按F5
或单击绿色调试图标在 VS Code 中开始调试。您现在可以编写代码、设置断点、更改代码以及调试新修改的代码——所有这些都可以通过编辑器进行。
VS Code 调试有问题吗?请参阅他们的故障排除指南。
您需要安装 WebStorm 和 JetBrains IDE 支持 Chrome 扩展程序。
在 WebStorm 菜单Run
中选择Edit Configurations...
。然后单击+
并选择JavaScript Debug
。将http://localhost:3000
粘贴到 URL 字段并保存配置。
注意:如果您通过 HOST 或 PORT 环境变量进行调整,则 URL 可能会有所不同。
通过运行npm start
启动您的应用程序,然后在 macOS 上按^D
或在 Windows 和 Linux 上按F9
,或者单击绿色调试图标开始在 WebStorm 中进行调试。
您可以使用相同的方式在 IntelliJ IDEA Ultimate、PhpStorm、PyCharm Pro 和 RubyMine 中调试应用程序。
Prettier 是一个固执己见的代码格式化程序,支持 JavaScript、CSS 和 JSON。使用 Prettier,您可以格式化自动编写的代码,以确保项目中的代码风格。有关更多信息,请参阅 Prettier 的 GitHub 页面,并查看此页面以了解其实际情况。
为了在 git 中提交时格式化我们的代码,我们需要安装以下依赖项:
npm install --save husky lint-staged prettier
或者你可以使用yarn
:
yarn add husky lint-staged prettier
husky
使使用 githooks 变得很容易,就好像它们是 npm 脚本一样。lint-staged
允许我们在 git 中的暂存文件上运行脚本。请参阅这篇关于 lint-staged 的博客文章以了解更多信息。prettier
是我们将在提交之前运行的 JavaScript 格式化程序。现在,我们可以通过向项目根目录中的package.json
添加几行来确保每个文件的格式正确。
将以下行添加到scripts
部分:
"scripts": {
+ "precommit": "lint-staged",
"start": "react-scripts start",
"build": "react-scripts build",
接下来,我们向package.json
添加一个 'lint-staged' 字段,例如:
"dependencies": {
// ...
},
+ "lint-staged": {
+ "src/**/*.{js,jsx,json,css}": [
+ "prettier --single-quote --write",
+ "git add"
+ ]
+ },
"scripts": {
现在,每当您进行提交时,Prettier 都会自动格式化更改的文件。您还可以运行./node_modules/.bin/prettier --single-quote --write "src/**/*.{js,jsx,json,css}"
来首次格式化整个项目。
接下来,您可能想将 Prettier 集成到您最喜欢的编辑器中。阅读 Prettier GitHub 页面上有关编辑器集成的部分。
<title>
您可以在生成的项目的public
文件夹中找到源 HTML 文件。您可以编辑其中的<title>
标签,将标题从“React App”更改为其他任何内容。
请注意,通常您不会经常编辑public
中的文件。例如,添加样式表无需触及 HTML。
如果您需要根据内容动态更新页面标题,可以使用浏览器document.title
API。对于更复杂的场景,当您想要更改 React 组件的标题时,可以使用第三方库 React Helmet。
如果您在生产中为应用程序使用自定义服务器,并且想要在将标题发送到浏览器之前修改标题,则可以按照本节中的建议进行操作。或者,您可以将每个页面预先构建为静态 HTML 文件,然后加载 JavaScript 包,这将在此处介绍。
生成的项目包含 React 和 ReactDOM 作为依赖项。它还包括 Create React App 用作开发依赖项的一组脚本。您可以使用npm
安装其他依赖项(例如 React Router):
npm install --save react-router
或者你可以使用yarn
:
yarn add react-router
这适用于任何库,而不仅仅是react-router
。
由于 Babel,该项目设置支持 ES6 模块。
虽然您仍然可以使用require()
和module.exports
,但我们鼓励您改用import
和export
。
例如:
Button.js
import React , { Component } from 'react' ;
class Button extends Component {
render ( ) {
// ...
}
}
export default Button ; // Don’t forget to use export default!
DangerButton.js
import React , { Component } from 'react' ;
import Button from './Button' ; // Import a component from another file
class DangerButton extends Component {
render ( ) {
return < Button color = "red" /> ;
}
}
export default DangerButton ;
请注意默认导出和命名导出之间的区别。这是错误的常见来源。
当模块仅导出单个内容(例如组件)时,我们建议您坚持使用默认导入和导出。这就是当您使用export default Button
和import Button from './Button'
时得到的结果。
命名导出对于导出多个函数的实用程序模块很有用。一个模块最多可以有一个默认导出和任意多个命名导出。
了解有关 ES6 模块的更多信息:
代码分割允许您将代码分割成小块,然后您可以按需加载,而不是在用户可以使用它之前下载整个应用程序。
该项目设置支持通过动态import()
进行代码分割。它的提案处于第 3 阶段。类似于import()
函数的形式将模块名称作为参数并返回一个始终解析为模块的名称空间对象的Promise
。
这是一个例子:
moduleA.js
const moduleA = 'Hello' ;
export { moduleA } ;
App.js
import React , { Component } from 'react' ;
class App extends Component {
handleClick = ( ) => {
import ( './moduleA' )
. then ( ( { moduleA } ) => {
// Use moduleA
} )
. catch ( err => {
// Handle failure
} ) ;
} ;
render ( ) {
return (
< div >
< button onClick = { this . handleClick } > Load </ button >
</ div >
) ;
}
}
export default App ;
这将使moduleA.js
及其所有独特的依赖项成为一个单独的块,仅在用户单击“加载”按钮后加载。
如果您愿意,您还可以将其与async
/ await
语法一起使用。
如果您正在使用 React Router,请查看本教程,了解如何使用代码拆分。您可以在此处找到配套的 GitHub 存储库。
另请查看 React 文档中的代码拆分部分。
该项目设置使用 Webpack 来处理所有资产。 Webpack 提供了一种import
概念“扩展”到 JavaScript 之外的自定义方式。为了表达 JavaScript 文件依赖于 CSS 文件,您需要从 JavaScript 文件导入 CSS :
Button.css
. Button {
padding : 20 px ;
}
Button.js
import React , { Component } from 'react' ;
import './Button.css' ; // Tell Webpack that Button.js uses these styles
class Button extends Component {
render ( ) {
// You can use them as regular CSS styles
return < div className = "Button" /> ;
}
}
这对于 React 来说不是必需的,但很多人发现这个功能很方便。您可以在此处了解此方法的优点。然而,您应该意识到,这使得您的代码比 Webpack 更难移植到其他构建工具和环境。
在开发中,以这种方式表达依赖关系允许您在编辑样式时即时重新加载样式。在生产中,所有 CSS 文件将在构建输出中连接成一个缩小的.css
文件。
如果您担心使用 Webpack 特定的语义,您可以将所有 CSS 直接放入src/index.css
中。它仍然会从src/index.js
导入,但如果您稍后迁移到不同的构建工具,您可以随时删除该导入。
此项目设置会缩小您的 CSS 并通过 Autoprefixer 自动添加供应商前缀,因此您无需担心它。
例如,这个:
. App {
display : flex;
flex-direction : row;
align-items : center;
}
变成这样:
. App {
display : -webkit-box;
display : -ms-flexbox;
display : flex;
-webkit-box-orient : horizontal;
-webkit-box-direction : normal;
-ms-flex-direction : row;
flex-direction : row;
-webkit-box-align : center;
-ms-flex-align : center;
align-items : center;
}
如果您出于某种原因需要禁用自动前缀,请按照本节操作。
一般来说,我们建议您不要在不同的组件中重复使用相同的 CSS 类。例如,我们建议不要在<AcceptButton>
和<RejectButton>
组件中使用.Button
CSS 类,而是创建一个具有自己的.Button
样式的<Button>
组件, <AcceptButton>
和<RejectButton>
都可以渲染(但不能渲染)继承)。
遵循这条规则通常会降低 CSS 预处理器的用处,因为 mixin 和嵌套等功能会被组件组合所取代。但是,如果您发现 CSS 预处理器有价值,则可以集成它。在本演练中,我们将使用 Sass,但您也可以使用 Less 或其他替代方案。
首先,让我们安装 Sass 的命令行界面:
npm install --save node-sass-chokidar
或者你可以使用yarn
:
yarn add node-sass-chokidar
然后在package.json
中,将以下行添加到scripts
中:
"scripts": {
+ "build-css": "node-sass-chokidar src/ -o src/",
+ "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
注意:要使用不同的预处理器,请根据预处理器的文档替换
build-css
和watch-css
命令。
现在您可以将src/App.css
重命名为src/App.scss
并运行npm run watch-css
。观察者将在src
子目录中找到每个 Sass 文件,并在其旁边创建相应的 CSS 文件,在我们的例子中覆盖src/App.css
。由于src/App.js
仍然导入src/App.css
,因此样式成为应用程序的一部分。您现在可以编辑src/App.scss
,并且src/App.css
将重新生成。
要在 Sass 文件之间共享变量,可以使用 Sass 导入。例如, src/App.scss
和其他组件样式文件可以包含@import "./shared.scss";
与变量定义。
要在不使用相对路径的情况下导入文件,可以将--include-path
选项添加到package.json
中的命令中。
"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive",
这将允许您进行导入,例如
@import ' styles/_colors.scss ' ; // assuming a styles directory under src/
@import ' nprogress/nprogress ' ; // importing a css file from the nprogress node module
此时,您可能希望从源代码管理中删除所有 CSS 文件,并将src/**/*.css
添加到.gitignore
文件中。将构建产品置于源代码控制之外通常是一个很好的做法。
作为最后一步,您可能会发现使用npm start
自动运行watch-css
很方便,并将build-css
作为npm run build
的一部分运行。您可以使用&&
运算符顺序执行两个脚本。但是,没有跨平台的方法来并行运行两个脚本,因此我们将为此安装一个包:
npm install --save npm-run-all
或者你可以使用yarn
:
yarn add npm-run-all
然后我们可以更改start
和build
脚本以包含 CSS 预处理器命令:
"scripts": {
"build-css": "node-sass-chokidar src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
- "start": "react-scripts start",
- "build": "react-scripts build",
+ "start-js": "react-scripts start",
+ "start": "npm-run-all -p watch-css start-js",
+ "build-js": "react-scripts build",
+ "build": "npm-run-all build-css build-js",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
现在运行npm start
和npm run build
也会构建 Sass 文件。
为什么选择node-sass-chokidar
?
据报告, node-sass
存在以下问题:
据报告,在虚拟机中或与 docker 一起使用时, node-sass --watch
在某些情况下会出现性能问题。
无限样式编译#1939
据报告, node-sass
在检测目录中的新文件时存在问题 #1891
这里使用node-sass-chokidar
来解决这些问题。
使用 Webpack,使用图像和字体等静态资源的工作方式与 CSS 类似。
您可以直接在 JavaScript 模块中import
文件。这告诉 Webpack 将该文件包含在包中。与 CSS 导入不同,导入文件会为您提供一个字符串值。该值是您可以在代码中引用的最终路径,例如作为图像的src
属性或 PDF 链接的href
。
为了减少对服务器的请求数量,导入小于 10,000 字节的图像会返回数据 URI 而不是路径。这适用于以下文件扩展名:bmp、gif、jpg、jpeg 和 png。由于 #1153,SVG 文件被排除。
这是一个例子:
import React from 'react' ;
import logo from './logo.png' ; // Tell Webpack this JS file uses this image
console . log ( logo ) ; // /logo.84287d09.png
function Header ( ) {
// Import result is the URL of your image
return < img src = { logo } alt = "Logo" /> ;
}
export default Header ;
这确保了项目构建时,Webpack 能够正确地将图像移动到构建文件夹中,并为我们提供正确的路径。
这也适用于 CSS:
. Logo {
background-image : url (. / logo.png);
}
Webpack 查找 CSS 中的所有相关模块引用(以./
开头),并将它们替换为编译包中的最终路径。如果您输入错误或意外删除重要文件,您将看到编译错误,就像导入不存在的 JavaScript 模块时一样。编译后的包中的最终文件名由 Webpack 根据内容哈希生成。如果文件内容将来发生变化,Webpack 将在生产中为其指定不同的名称,因此您无需担心资产的长期缓存。
请注意,这也是 Webpack 的自定义功能。
React 不需要它,但很多人喜欢它(React Native 对图像使用类似的机制)。
下一节将介绍处理静态资产的另一种方法。
public
文件夹注意:此功能适用于
[email protected]
及更高版本。
public
包含 HTML 文件,因此您可以对其进行调整,例如设置页面标题。带有已编译代码的<script>
标记将在构建过程中自动添加到其中。
您还可以将其他资产添加到public
。
请注意,我们通常鼓励您改为import
JavaScript 文件中的资源。例如,请参阅有关添加样式表以及添加图像和字体的部分。该机制提供了许多好处:
但是,您可以使用逃生舱口在模块系统之外添加资产。
如果将文件放入public
文件夹中,Webpack不会处理该文件。相反,它将原封不动地复制到构建文件夹中。要引用public
文件夹中的资源,您需要使用一个名为PUBLIC_URL
的特殊变量。
在index.html
中,你可以像这样使用它:
< link rel =" shortcut icon " href =" %PUBLIC_URL%/favicon.ico " >
只有public
内的文件才能通过%PUBLIC_URL%
前缀访问。如果您需要使用src
或node_modules
中的文件,则必须将其复制到那里以明确指定使该文件成为构建的一部分的意图。
当您运行npm run build
时,Create React App 会将%PUBLIC_URL%
替换为正确的绝对路径,这样即使您使用客户端路由或将其托管在非根 URL 上,您的项目也能正常运行。
在 JavaScript 代码中,您可以使用process.env.PUBLIC_URL
实现类似目的:
render ( ) {
// Note: this is an escape hatch and should be used sparingly!
// Normally we recommend using `import` for getting asset URLs
// as described in “Adding Images and Fonts” above this section.
return < img src = { process . env . PUBLIC_URL + '/img/logo.png' } /> ;
}
请记住这种方法的缺点:
public
中的任何文件都不会被后处理或缩小。public
文件夹通常我们建议从 JavaScript 导入样式表、图像和字体。 public
可作为解决许多不太常见情况的方法:
manifest.webmanifest
。pace.js
<script>
标记。请注意,如果您添加声明全局变量的<script>
,您还需要阅读下一节有关使用它们的内容。
当您在 HTML 文件中包含定义全局变量的脚本并尝试在代码中使用这些变量之一时,linter 会抱怨,因为它无法看到变量的定义。
您可以通过从window
对象显式读取全局变量来避免这种情况,例如:
const $ = window . $ ;
这表明您是故意使用全局变量,而不是因为拼写错误。
或者,您可以通过在后面添加// eslint-disable-line
来强制 linter 忽略任何行。
您不必将 React Bootstrap 与 React 一起使用,但它是一个用于将 Bootstrap 与 React 应用程序集成的流行库。如果您需要,可以按照以下步骤将其与 Create React App 集成:
从 npm 安装 React Bootstrap 和 Bootstrap。 React Bootstrap 不包含 Bootstrap CSS,因此也需要安装:
npm install --save react-bootstrap bootstrap@3
或者你可以使用yarn
:
yarn add react-bootstrap bootstrap@3
在src/index.js
文件的开头导入 Bootstrap CSS 和可选的 Bootstrap 主题 CSS:
import 'bootstrap/dist/css/bootstrap.css' ;
import 'bootstrap/dist/css/bootstrap-theme.css' ;
// Put any other imports below so that CSS from your
// components takes precedence over default styles.
在src/App.js
文件或自定义组件文件中导入所需的 React Bootstrap 组件:
import { Navbar , Jumbotron , Button } from 'react-bootstrap' ;
现在您可以在 render 方法中定义的组件层次结构中使用导入的 React Bootstrap 组件了。以下是使用 React Bootstrap 重做的App.js
示例。
有时您可能需要调整 Bootstrap(或等效包)的视觉样式。
我们建议采用以下方法:
以下是添加遵循以下步骤的自定义 Bootstrap 的示例。
Flow 是一个静态类型检查器,可帮助您编写错误更少的代码。如果您不熟悉这个概念,请查看有关在 JavaScript 中使用静态类型的介绍。
Flow 的最新版本可以开箱即用地使用 Create React App 项目。
要将 Flow 添加到 Create React App 项目,请按照以下步骤操作:
npm install --save flow-bin
(或yarn add flow-bin
)。"flow": "flow"
添加到package.json
的scripts
部分。npm run flow init
(或yarn flow init
)以在根目录中创建.flowconfig
文件。// @flow
添加到您想要类型检查的任何文件(例如,添加到src/App.js
)。现在您可以运行npm run flow
(或yarn flow
)来检查文件是否存在类型错误。您可以选择使用 Nuclide 等 IDE 以获得更好的集成体验。未来我们计划将其更紧密地集成到 Create React App 中。
要了解有关 Flow 的更多信息,请查看其文档。
Create React App 没有规定具体的路由解决方案,但 React Router 是最流行的一种。
要添加它,请运行:
npm install --save react-router-dom
或者你可以使用yarn
:
yarn add react-router-dom
要尝试它,请删除src/App.js
中的所有代码并将其替换为其网站上的任何示例。基本示例是一个很好的起点。
请注意,在部署应用程序之前,您可能需要配置生产服务器以支持客户端路由。
注意:此功能适用于
[email protected]
及更高版本。
您的项目可以使用在您的环境中声明的变量,就像它们是在您的 JS 文件中本地声明的一样。默认情况下,您将为您定义NODE_ENV
以及以REACT_APP_
开头的任何其他环境变量。
环境变量是在构建时嵌入的。由于 Create React App 生成静态 HTML/CSS/JS 包,因此它不可能在运行时读取它们。要在运行时读取它们,您需要将 HTML 加载到服务器上的内存中并在运行时替换占位符,就像此处所述。或者,您可以在更改应用程序时随时在服务器上重建应用程序。
注意:您必须创建以
REACT_APP_
开头的自定义环境变量。除NODE_ENV
之外的任何其他变量都将被忽略,以避免意外暴露机器上可能具有相同名称的私钥。更改任何环境变量都将要求您重新启动正在运行的开发服务器。
这些环境变量将在process.env
上为您定义。例如,名为REACT_APP_SECRET_CODE
的环境变量将在 JS 中公开为process.env.REACT_APP_SECRET_CODE
。
还有一个特殊的内置环境变量,称为NODE_ENV
。您可以从process.env.NODE_ENV
读取它。当您运行npm start
时,它始终等于'development'
,当您运行npm test
时,它始终等于'test'
,当您运行npm run build
来制作生产包时,它始终等于'production'
。您无法手动覆盖NODE_ENV
。这可以防止开发人员意外地将缓慢的开发版本部署到生产中。
这些环境变量可用于根据项目的部署位置有条件地显示信息或使用版本控制之外的敏感数据。
首先,您需要定义环境变量。例如,假设您想使用<form>
内的环境中定义的秘密:
render ( ) {
return (
< div >
< small > You are running this application in < b > { process . env . NODE_ENV } </ b > mode. </ small >
< form >
< input type = "hidden" defaultValue = { process . env . REACT_APP_SECRET_CODE } />
</ form >
</ div >
) ;
}
在构建过程中, process.env.REACT_APP_SECRET_CODE
将替换为REACT_APP_SECRET_CODE
环境变量的当前值。请记住, NODE_ENV
变量将自动为您设置。
当您在浏览器中加载应用程序并检查<input>
时,您将看到其值设置为abcdef
,并且粗体文本将显示使用npm start
时提供的环境:
< div >
< small > You are running this application in < b > development </ b > mode. </ small >
< form >
< input type =" hidden " value =" abcdef " />
</ form >
</ div >
上面的形式正在从环境中查找名为REACT_APP_SECRET_CODE
的变量。为了使用这个值,我们需要在环境中定义它。这可以通过两种方式完成:在 shell 中或在.env
文件中。这两种方式将在接下来的几节中进行描述。
访问NODE_ENV
对于有条件执行操作也很有用:
if ( process . env . NODE_ENV !== 'production' ) {
analytics . disable ( ) ;
}
当您使用npm run build
编译应用程序时,缩小步骤将消除此条件,并且生成的包会更小。
注意:此功能适用于
[email protected]
及更高版本。
您还可以访问public/index.html
中以REACT_APP_
开头的环境变量。例如:
< title > %REACT_APP_WEBSITE_NAME% </ title >
请注意,上述部分的警告适用:
NODE_ENV
和PUBLIC_URL
)之外,变量名称必须以REACT_APP_
开头才能工作。定义环境变量可能因操作系统而异。同样重要的是要知道这种方式对于 shell 会话的生命周期来说是暂时的。
set " REACT_APP_SECRET_CODE = abcdef " && npm start
(注意:变量赋值周围需要引号以避免尾随空格。)
( $ env: REACT_APP_SECRET_CODE = " abcdef " ) -and (npm start)
REACT_APP_SECRET_CODE=abcdef npm start
.env
中添加开发环境变量注意:此功能适用于
[email protected]
及更高版本。
要定义永久环境变量,请在项目的根目录中创建一个名为.env
的文件:
REACT_APP_SECRET_CODE=abcdef
注意:您必须创建以
REACT_APP_
开头的自定义环境变量。除NODE_ENV
之外的任何其他变量都将被忽略,以避免意外暴露机器上可能具有相同名称的私钥。更改任何环境变量都将要求您重新启动正在运行的开发服务器。
.env
文件应签入源代码管理(不包括.env*.local
)。
.env
文件?注意:此功能适用于
[email protected]
及更高版本。
.env
:默认。.env.local
:本地覆盖。除测试之外的所有环境都会加载此文件。.env.development
、 .env.test
、 .env.production
:特定于环境的设置。.env.development.local
、 .env.test.local
、 .env.production.local
:本地覆盖特定于环境的设置。左侧的文件比右侧的文件具有更高的优先级:
npm start
: .env.development.local
、 .env.development
、 .env.local
、 .env
npm run build
: .env.production.local
.local, .env.production
, .env.local
, .env
npm test
: .env.test.local
、 .env.test
、 .env
(注意.env.local
丢失)如果机器没有明确设置这些变量,它们将充当默认值。
请参阅 dotenv 文档了解更多详细信息。
注意:如果您正在定义用于开发的环境变量,您的 CI 和/或托管平台很可能也需要定义这些变量。请查阅他们的文档如何执行此操作。例如,请参阅 Travis CI 或 Heroku 的文档。
.env
中扩展环境变量注意:此功能适用于
[email protected]
及更高版本。
扩展计算机上已有的变量以在.env
文件中使用(使用 dotenv-expand)。
例如,获取环境变量npm_package_version
:
REACT_APP_VERSION=$npm_package_version
# also works:
# REACT_APP_VERSION=${npm_package_version}
或者扩展当前.env
文件的本地变量:
DOMAIN=www.example.com
REACT_APP_FOO=$DOMAIN/foo
REACT_APP_BAR=$DOMAIN/bar
许多流行的库在其文档中使用装饰器。
Create React App 目前不支持装饰器语法,因为:
但是,在许多情况下,您可以在没有装饰器的情况下重写基于装饰的代码。
请参考这两个线程以供参考:
当规格发展到稳定阶段时,创建React应用程序将添加装饰器支持。
React没有规定数据获取的特定方法,但是人们通常使用Axios之类的库或浏览器提供的fetch()
API。方便地,Create React应用程序包括用于fetch()
的polyfill,因此您可以使用它而不必担心浏览器支持。
全局fetch
功能允许轻松提出AJAX请求。它以URL为输入,并返回解决Response
对象的Promise
。您可以在此处找到有关fetch
的更多信息。
该项目还包括一个Promise Pollefill,该项目提供了Promises/A+的完整实现。一个承诺代表了异步操作的最终结果,您可以在此处和此处找到有关承诺的更多信息。 Axios和fetch()
都在引擎盖下使用承诺。您也可以使用async / await
语法来减少回调嵌套。
您可以在React网站上的常见问题解答条目中从React组件中提出AJAX请求的更多信息。
这些教程将帮助您将应用程序与在另一个端口上运行的API后端集成在一起,并使用fetch()
访问它。
查看本教程。您可以在此处找到同伴GitHub存储库。
查看本教程。您可以在此处找到同伴GitHub存储库。
注意:此功能可提供
[email protected]
及更高版本。
人们经常从同一主机和端口与后端实施服务前端React应用程序。
例如,在部署应用程序后,生产设置可能看起来像这样:
/ - static server returns index.html with React app
/todos - static server returns index.html with React app
/api/todos - server handles any /api/* requests using the backend implementation
不需要这种设置。但是,如果您确实有这样的设置,则很方便地编写诸如fetch('/api/todos')
之类的请求,而不必担心开发过程中将它们重定向到另一个主机或端口。
要告诉开发服务器以代理开发中的API服务器的任何未知请求,请在您的package.json
中添加proxy
字段。JSON,例如:
"proxy" : "http://localhost:4000" ,
这样,当您在开发中fetch('/api/todos')
时,开发服务器将认识到它不是静态资产,并且会将您的请求委托给http://localhost:4000/api/todos
作为后备。开发服务器只会尝试在其Accept
标头中未经text/html
发送请求到代理。
方便地,这避免了CORS问题和类似此类的错误消息:
Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
请记住, proxy
仅在开发中具有效果( npm start
),并且由您确保/api/todos
之类的URL指向生产中正确的东西。您不必使用/api
前缀。没有text/html
接受标头的任何未识别的请求将被重定向到指定的proxy
。
proxy
选项支持HTTP,HTTP和WebSocket连接。
如果proxy
选项对您来说还不够灵活,或者您可以:
启用proxy
选项时,您会选择更严格的主机检查。这是必要的,因为将后端留给远程主机会使您的计算机容易受到DNS重新攻击的攻击。本文和本问题都解释了这个问题。
在localhost
上开发时,这不应影响您,但是如果您在此处所描述的远程开发,则在启用proxy
选项后会在浏览器中看到此错误:
无效的主机标头
要围绕它,您可以在项目的根源中指定您的公共开发.env.development
。
HOST=mypublicdevhost.com
如果您现在重新启动开发服务器并从指定的主机加载应用程序,则应起作用。
如果您仍在遇到问题,或者您正在使用更奇特的环境(例如云编辑器),则可以通过在.env.development.local
中添加一条线来完全绕过主机检查。请注意,这很危险,并将您的计算机暴露于恶意网站上的远程代码执行:
# NOTE: THIS IS DANGEROUS!
# It exposes your machine to attacks from the websites you visit.
DANGEROUSLY_DISABLE_HOST_CHECK=true
我们不建议这种方法。
注意:此功能可提供
[email protected]
及更高版本。
如果proxy
选项对您来说不够灵活,则可以以以下形式指定对象(in package.json
)。
您还可以指定任何配置值http-proxy-middleware
或http-proxy
支持。
{
// ...
"proxy" : {
"/api" : {
"target" : "<url>" ,
"ws" : true
// ...
}
}
// ...
}
匹配此路径的所有请求将是代理,也不例外。这包括对text/html
的请求,标准proxy
选项不代理。
如果您需要指定多个代理,则可以通过指定其他条目来做到这一点。匹配是正则表达式,因此您可以使用REGEXP匹配多个路径。
{
// ...
"proxy" : {
// Matches any request starting with /api
"/api" : {
"target" : "<url_1>" ,
"ws" : true
// ...
} ,
// Matches any request starting with /foo
"/foo" : {
"target" : "<url_2>" ,
"ssl" : true ,
"pathRewrite" : {
"^/foo" : "/foo/beta"
}
// ...
} ,
// Matches /bar/abc.html but not /bar/sub/def.html
"/bar/[^/]*[.]html" : {
"target" : "<url_3>" ,
// ...
} ,
// Matches /baz/abc.html and /baz/sub/def.html
"/baz/.*/.*[.]html" : {
"target" : "<url_4>"
// ...
}
}
// ...
}
在设置WebSocket代理时,需要注意一些额外的注意事项。
如果您使用的是socket.io之类的WebSocket引擎,则必须运行socket.io服务器,可以用作代理目标。 socket.io将无法与标准的Websocket服务器一起使用。具体来说,不要指望socket.io可以与websocket.org echo测试一起使用。
有一些很好的文档可用于设置socket.io服务器。
标准Websockets将与标准的WebSocket服务器以及WebSocket.org Echo测试一起使用。您可以将诸如WS之类的库用于服务器,并在浏览器中使用本机Websocket。
无论哪种方式,您都可以在package.json
中手动委托Websocket请求:
{
// ...
"proxy" : {
"/socket" : {
// Your compatible WebSocket server
"target" : "ws://<socket_url>" ,
// Tell http-proxy-middleware that this is a WebSocket proxy.
// Also allows you to proxy WebSocket requests without an additional HTTP request
// https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
"ws" : true
// ...
}
}
// ...
}
注意:此功能可提供
[email protected]
及更高版本。
您可能要求开发服务器通过HTTPS提供页面。一种可能有用的特殊情况是,当该API服务器本身使用HTTPS时,将“代理”功能使用“代理”功能向API服务器发出。
为此,请将HTTPS
环境变量设置为true
,然后像往常一样在npm start
时启动Dev Server:
set HTTPS = true && npm start
( $ env: HTTPS = $true ) -and (npm start)
(注意:缺乏空格是故意的。)
HTTPS=true npm start
请注意,服务器将使用自签名的证书,因此您的Web浏览器在访问页面时几乎肯定会显示警告。
<meta>
标签由于Create React App不支持服务器渲染,因此您可能想知道如何制作<meta>
标签动态并反映当前的URL。为了解决这个问题,我们建议将占位符添加到HTML中,因此:
<!doctype html >
< html lang =" en " >
< head >
< meta property =" og:title " content =" __OG_TITLE__ " >
< meta property =" og:description " content =" __OG_DESCRIPTION__ " >
然后,在服务器上,无论您使用哪种后端,都可以将index.html
读取到内存中,然后替换__OG_TITLE__
, __OG_DESCRIPTION__
和任何其他具有值的其他占位符,具体取决于当前URL。只需确保消毒并逃脱插值值,以便它们可以安全地嵌入HTML!
如果您使用节点服务器,甚至可以在客户端和服务器之间共享路由匹配逻辑。但是,在简单的情况下,重复它也可以很好地工作。
如果您使用静态托管提供商托管build
,则可以使用React-Snapshot或React-Snap在您的应用程序中为每个路线或相对链接生成HTML页面。然后,当JavaScript束加载时,这些页面将无缝变得活跃或“水合”。
也有机会在静态托管之外使用它,以便在生成和缓存路线时承受服务器的压力。
预渲染的主要好处是,您可以通过HTML有效载荷获得每个页面的核心内容,而没有成功下载JavaScript捆绑包。这也增加了您应用程序的每条路线的可能性。
您可以在此处阅读有关零配置预先渲染(也称为快照)的更多信息。
与上一节类似,您可以将一些注入全局变量的HTML留在HTML中:
< ! doctype html >
< html lang = "en" >
< head >
< script >
window.SERVER_DATA = __SERVER_DATA__;
</ script >
然后,在服务器上,您可以在发送响应之前先用真实数据的json替换__SERVER_DATA__
。然后,客户端代码可以读取window.SERVER_DATA
来使用它。在将JSON发送给客户端之前,请确保对其进行消毒,因为它使您的应用程序容易受到XSS攻击的影响。
注意:此功能可提供
[email protected]
及更高版本。
阅读迁移指南,以了解如何在较旧的项目中启用它!
Create React App使用开玩笑作为其测试跑者。为了为这种整合做准备,我们对开玩笑进行了重大改造,因此,如果您几年前听到有关它的坏事,请再次尝试。
Jest是基于节点的跑步者。这意味着测试始终在节点环境中进行,而不是在真实的浏览器中进行。这使我们可以实现快速的迭代速度并防止片状。
虽然Jest提供了JSDON的浏览器Globals,例如window
,但它们只是真正的浏览器行为的近似值。开玩笑旨在用于您的逻辑和组件的单位测试,而不是DOM Quirks。
我们建议您使用单独的工具进行浏览器端到端测试。它们超出了创建React应用程序的范围。
Jest将寻找具有以下任何流行命名约定的测试文件:
__tests__
文件夹中的.js
后缀的文件。.test.js
后缀的文件。.spec.js
后缀的文件。 .test.js
/ .spec.js
文件(或__tests__
文件夹)位于src
顶级文件夹下的任何深度。
我们建议将测试文件(或__tests__
文件夹)放在他们正在测试的代码旁边,以使相对导入看起来更短。例如,如果App.test.js
和App.js
在同一文件夹中,则测试只需import App from './App'
而不是较长的相对路径。托管还有助于在大型项目中更快地找到测试。
当您运行npm test
时,JEST将在手表模式下启动。每次保存文件时,它都会重新运行测试,就像npm start
一样,重新编译代码。
观察者包括一个交互式命令行界面,具有运行所有测试或专注于搜索模式的能力。它是通过这种方式设计的,以便您可以保持打开状态并享受快速重新运行。您可以从“观看用法”中学习命令,请注意,观察者每次运行后都会打印出来:
默认情况下,当您运行npm test
时,JEST只会运行与上次提交以来更改的文件相关的测试。这是一种优化,旨在使您的测试快速进行,而不管您有多少个测试。但是,它假设您通常不会提交未通过测试的代码。
Jest将始终明确地提到它仅运行与上次提交以来更改的文件相关的测试。您也可以在手表模式下按a
迫使Jest进行所有测试。
开玩笑将始终在连续集成服务器上或项目不在git或mercurial存储库中。
要创建测试,请添加it()
(或test()
)块,其中具有测试名称及其代码。您可以选择将它们包装在逻辑分组中的describe()
块中,但这既不需要也不建议。
Jest提供了一个内置的expect()
全局函数来做出断言。基本测试看起来像这样:
import sum from './sum' ;
it ( 'sums numbers' , ( ) => {
expect ( sum ( 1 , 2 ) ) . toEqual ( 3 ) ;
expect ( sum ( 2 , 2 ) ) . toEqual ( 4 ) ;
} ) ;
JEST支持的所有expect()
匹配者在此处进行了广泛的记录。
您也可以使用jest.fn()
和expect(fn).toBeCalled()
创建“间谍”或模拟功能。
组件测试技术有广泛的范围。它们的范围从“烟雾测试”验证,验证组件是否不投掷,浅渲染和测试某些输出,到完整的渲染和测试组件生命周期和状态变化。
不同的项目根据组件变化的频率以及所包含多少逻辑选择不同的测试权衡。如果您尚未决定测试策略,我们建议您从为您的组件创建简单的烟雾测试开始:
import React from 'react' ;
import ReactDOM from 'react-dom' ;
import App from './App' ;
it ( 'renders without crashing' , ( ) => {
const div = document . createElement ( 'div' ) ;
ReactDOM . render ( < App /> , div ) ;
} ) ;
该测试将安装一个组件,并确保其在渲染过程中不会投掷。像这样的测试提供了很大的价值,因此它们作为起点很棒,这是您在src/App.test.js
中找到的测试。
当您遇到由变化的组件引起的错误时,您将获得更深入的了解,其中哪些部分值得在应用程序中进行测试。这可能是引入更具体测试的好时机,主张特定的预期产出或行为。
如果您想与它们渲染的儿童组件隔离测试组件,我们建议使用shallow()
呈现API的API。要安装它,请运行:
npm install --save enzyme enzyme-adapter-react-16 react-test-renderer
或者,您可以使用yarn
:
yarn add enzyme enzyme-adapter-react-16 react-test-renderer
在酶3中,您将需要安装酶以及与您使用的React版本相对应的适配器。 (上面的示例使用适配器进行react 16。
适配器还需要在您的全局设置文件中进行配置:
src/setupTests.js
import { configure } from 'enzyme' ;
import Adapter from 'enzyme-adapter-react-16' ;
configure ( { adapter : new Adapter ( ) } ) ;
注意:请记住,如果您决定在创建
src/setupTests.js
之前“弹出”,则结果package.json
文件将不包含对其的任何引用。在此处阅读以了解弹出后如何添加此内容。
现在您可以用它进行烟雾测试:
import React from 'react' ;
import { shallow } from 'enzyme' ;
import App from './App' ;
it ( 'renders without crashing' , ( ) => {
shallow ( < App /> ) ;
} ) ;
与以前使用ReactDOM.render()
烟雾测试不同,此测试仅渲染<App>
,并且不会更深。例如,即使<App>
本身会呈现一个投掷的<Button>
,此测试也会通过。浅渲染非常适合隔离的单元测试,但是您可能仍需要创建一些完整的渲染测试以确保组件正确集成。酶支持使用mount()
完全渲染,您也可以将其用于测试状态变化和组件生命周期。
您可以阅读酶文档以获取更多测试技术。酶文档使用Chai和Sinon进行断言,但您不必使用它们,因为JEST为SPIE提供了内置的expect()
和jest.fn()
。
这是酶文档中的一个示例,该酶断言特定的输出,重写以使用开玩笑的匹配器:
import React from 'react' ;
import { shallow } from 'enzyme' ;
import App from './App' ;
it ( 'renders welcome message' , ( ) => {
const wrapper = shallow ( < App /> ) ;
const welcome = < h2 > Welcome to React </ h2 > ;
// expect(wrapper.contains(welcome)).to.equal(true);
expect ( wrapper . contains ( welcome ) ) . toEqual ( true ) ;
} ) ;
所有的玩笑匹配者都在此处进行了广泛的记录。
但是,如果您愿意,您可以使用像Chai这样的第三方断言库,如下所述。
此外,您可能会发现开玩笑的酶有助于使用可读的匹配器简化测试。以上contains
代码可以用开玩笑的酶编写。
expect ( wrapper ) . toContainReact ( welcome )
要启用此功能,请安装jest-enzyme
:
npm install --save jest-enzyme
或者,您可以使用yarn
:
yarn add jest-enzyme
在src/setupTests.js
中导入它,以使其匹配器在每个测试中可用:
import 'jest-enzyme' ;
我们建议您将expect()
用于主张,而jest.fn()
用于间谍。如果您对它们有问题,请针对Jest提出这些问题,我们将修复它们。我们打算继续使它们更好地进行反应,例如支持jsx的相当印刷元素。
但是,如果您习惯了其他库,例如Chai和Sinon,或者使用要移植的现有代码,则可以正常地导入它们:
import sinon from 'sinon' ;
import { expect } from 'chai' ;
然后像往常一样在测试中使用它们。
注意:此功能可提供
[email protected]
及更高版本。
如果您的应用程序使用您需要在测试中嘲笑的浏览器API,或者在运行测试之前只需要全局设置,请在项目中添加src/setupTests.js
。它将在运行测试之前自动执行。
例如:
src/setupTests.js
const localStorageMock = {
getItem : jest . fn ( ) ,
setItem : jest . fn ( ) ,
clear : jest . fn ( )
} ;
global . localStorage = localStorageMock
注意:请记住,如果您决定在创建
src/setupTests.js
之前“弹出”setupTestFrameworkScriptFile
则结果package.json
。如下所示:
"jest" : { // ... "setupTestFrameworkScriptFile" : "<rootDir>/src/setupTests.js" }
您可以将it()
替换为xit()
以暂时将测试排除在执行中。
同样, fit()
可让您专注于特定的测试,而无需进行任何其他测试。
Jest具有一个集成的覆盖记者,可与ES6配合使用,不需要配置。
运行npm test -- --coverage
(在中间注意额外--
额外),以包括这样的覆盖范围报告:
请注意,测试的覆盖范围较慢,因此建议将其与普通工作流程分开运行。
可以通过将以下任何支持的密钥添加到软件包中的jest config。
支持的替代:
collectCoverageFrom
coverageReporters
coverageThreshold
snapshotSerializers
示例软件包。
{
"name" : " your-package " ,
"jest" : {
"collectCoverageFrom" : [
" src/**/*.{js,jsx} " ,
" !<rootDir>/node_modules/ " ,
" !<rootDir>/path/to/dir/ "
],
"coverageThreshold" : {
"global" : {
"branches" : 90 ,
"functions" : 90 ,
"lines" : 90 ,
"statements" : 90
}
},
"coverageReporters" : [ " text " ],
"snapshotSerializers" : [ " my-serializer-module " ]
}
}
默认情况下, npm test
将使用Interactive CLI运行观察者。但是,您可以强迫它运行一次测试,并通过设置称为CI
环境变量来完成该过程。
默认情况下,使用npm run build
Linter警告创建应用程序的构建时。像npm test
一样,您可以通过设置环境变量CI
强迫构建来执行衬里警告检查。如果遇到任何警告,则构建失败。
流行的CI服务器默认情况下已经设置了环境变量CI
但是您也可以自己执行此操作:
.travis.yml
文件添加到您的git存储库中。 language: node_js
node_js:
- 6
cache:
directories:
- node_modules
script:
- npm run build
- npm test
请按照本文使用Create React App Project设置CircleCi。
set CI = true && npm test
set CI = true && npm run build
(注意:缺乏空格是故意的。)
( $ env: CI = $true ) -and (npm test)
( $ env: CI = $true ) -and (npm run build)
CI=true npm test
CI=true npm run build
测试命令将迫使玩笑一次进行测试,而不是启动观察者。
如果您发现自己经常在开发中进行此操作,请提出一个问题来告诉我们您的用例,因为我们希望使Watcher获得最佳体验,并愿意更改其工作方式以适应更多的工作流程。
构建命令将检查是否有衬里警告,如果发现有任何警告,则会失败。
默认情况下,生成项目的package.json
看起来像这样:
"scripts" : {
"start" : "react-scripts start" ,
"build" : "react-scripts build" ,
"test" : "react-scripts test --env=jsdom"
如果您知道您的测试都不取决于JSDOM,则可以安全地删除--env=jsdom
,并且您的测试将更快地运行:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
- "test": "react-scripts test --env=jsdom"
+ "test": "react-scripts test"
为了帮助您下定决心,以下是需要JSDOM的API列表:
window
和document
等任何浏览器全球范围ReactDOM.render()
TestUtils.renderIntoDocument()
(上述快捷方式)mount()
相比之下,以下API不需要JSDOM :
TestUtils.createRenderer()
(浅渲染)shallow()
最后,快照测试也不需要JSDOM。
快照测试是Jest的一个功能,它会自动生成组件的文本快照并将其保存在磁盘上,因此,如果UI输出更改,则不会在组件输出上手动编写任何断言而通知您。阅读有关快照测试的更多信息。
如果您使用Visual Studio代码,则有一个开玩笑的扩展名,可与Create Apple一起使用。使用文本编辑器时,这提供了许多类似IDE的功能:显示潜在的失败消息内联的测试状态,自动启动和停止观察者,并提供一键式快照更新。
有多种方法可以为您的玩笑测试设置调试器。我们涵盖Chrome和Visual Studio代码中的调试。
注意:调试测试需要节点8或更高。
将以下内容添加到您项目package.json
中的scripts
部分。
"scripts" : {
"test:debug" : " react-scripts --inspect-brk test --runInBand --env=jsdom "
}
位置debugger;
任何测试和运行中的语句:
$ npm run test:debug
这将开始进行开玩笑的测试,但在执行之前暂停,以允许调试器附加到该过程。
在Chrome中打开以下内容
about:inspect
打开该链接后,将显示Chrome开发人员工具。选择您的过程中的inspect
,将在React脚本的第一行中设置断点(这只是为了让您有时间打开开发人员工具并防止JEST在您有时间之前执行)。单击屏幕右上方的“播放”按钮的按钮继续执行。当Jest执行包含Debugger语句的测试时,执行将暂停,您可以检查当前范围并调用堆栈。
注意: - runinband CLI选项可确保在同一过程中开玩笑地运行测试,而不是为单个测试产卵过程。通常,开玩笑平行于测试跨过程运行,但很难同时调试许多过程。
开箱即用的开箱即用调试JEST测试。
使用以下launch.json
配置文件:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug CRA Tests",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
"args": [
"test",
"--runInBand",
"--no-cache",
"--env=jsdom"
],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}
通常,在应用程序中,您有很多UI组件,并且每个UI组件都有许多不同的状态。例如,一个简单的按钮组件可能具有以下状态:
通常,很难看到这些状态而不运行示例应用程序或一些示例。
Create React App默认不包含任何工具,但是您可以轻松地将故事书添加到React(Source)或React Styleguidist(源)中。这些是第三方工具,可让您开发组件,并与您的应用程序孤立地看到其所有状态。
您还可以将故事书或样式指南部署为静态应用。这样,团队中的每个人都可以在不启动后端服务器或在应用程序中创建帐户的情况下查看和查看UI组件的不同状态。
Storybook是React UI组件的开发环境。它允许您浏览组件库,查看每个组件的不同状态,并进行交互开发和测试组件。
首先,全球安装以下NPM软件包:
npm install -g @storybook/cli
然后,在应用程序目录中运行以下命令:
getstorybook
之后,请按照屏幕上的说明进行操作。
了解有关React Storybook的更多信息:
Styleguidist结合了样式指南,其中所有组件都呈现在单个页面上,其中包含其道具文档和用法示例,以及一个与Storybook类似的隔离组件的环境。在StyleGuidist中,您可以在Markdown中编写示例,其中每个代码段都被渲染为现场编辑的操场。
首先,安装StyleGuidist:
npm install --save react-styleguidist
或者,您可以使用yarn
:
yarn add react-styleguidist
然后,将这些脚本添加到您的package.json
:
"scripts": {
+ "styleguide": "styleguidist server",
+ "styleguide:build": "styleguidist build",
"start": "react-scripts start",
然后,在应用程序目录中运行以下命令:
npm run styleguide
之后,请按照屏幕上的说明进行操作。
了解有关React StyleGidist的更多信息:
Create React应用程序没有提供任何内置功能,可以将组件发布到NPM。如果您准备从项目中提取组件,以便其他人可以使用它,我们建议将其移至项目外的单独目录,然后使用NWB之类的工具来准备出版。
默认情况下,生产构建是一个功能齐全的脱机渐进式网络应用程序。
渐进的网络应用程序比传统网页更快,更可靠,并提供引人入胜的移动体验:
sw-precache-webpack-plugin
已集成到生产配置中,它将负责生成一个服务工作者文件,该文件将自动占地所有本地资产,并在部署更新时保持最新状态。服务工作者将使用缓存优先的策略来处理所有本地资产的请求,包括初始HTML,以确保您的Web应用程序快速快速,即使在缓慢或不可靠的网络上也是如此。
如果您希望在初始生产部署之前不启用服务工作人员,请从src/index.js
删除registerServiceWorker()
的呼叫。
如果您以前曾在生产部署中启用了服务人员,并决定您希望为所有现有用户禁用它们,则可以首先通过修改服务服务工作者导入的src/index.js
中的registerServiceWorker()
:
import { unregister } from './registerServiceWorker' ;
然后致电unregister()
。用户访问一个unregister()
的页面后,服务工作者将被卸载。请注意,根据如何提供如何/service-worker.js
,可能需要24小时才能使缓存无效。
服务工作人员需要HTTP,尽管为了促进本地测试,但该政策不适用于localhost
。如果您的生产Web服务器不支持HTTP,则服务工作者注册将失败,但是您的Web应用程序的其余部分将保持功能。
目前,所有Web浏览器中尚未支持服务工作人员。服务工作者注册不会尝试缺乏支持的浏览器。
服务工作者仅在生产环境中启用,例如npm run build
的输出。建议您不要在开发环境中启用离线服务工作者,因为当使用以前的缓存资产时,它可能会导致挫败感,并且不包括您在当地进行的最新更改。
如果您需要在本地测试您的离线优先服务工作者,请构建应用程序(使用npm run build
),然后从构建目录运行简单的HTTP服务器。运行构建脚本后, create-react-app
将提供一种指令,以一种在本地测试生产构建的方法,并且部署说明具有使用其他方法的说明。请务必始终使用隐身窗口,以避免使用浏览器缓存并发症。
如果可能的话,将生产环境配置为使用HTTP缓存服务的生成的service-worker.js
服务。如果不可能 - 例如,github页面不允许您更改默认的10分钟HTTP高速缓存寿命 - 然后请注意,如果您访问生产站点,然后在service-worker.js
从您的生产站点进行重新访问HTTP缓存,您将继续从服务工作者那里获得以前的缓存资产。如果您立即需要查看更新的生产部署,则执行换挡措施将暂时禁用服务工作者并从网络中检索所有资产。
用户并不总是熟悉离线优先的Web应用程序。让用户知道服务工作者何时完成填充您的缓存可能会很有用(显示“此Web应用程序脱机!”消息),也让他们知道服务工作者何时提取了最新的更新下次他们加载页面时(显示“可用新内容;请刷新”。消息)。目前,显示此消息是向开发人员练习的,但是作为起点,您可以使用src/registerServiceWorker.js
中包含的逻辑,该逻辑演示了哪些服务工作者的生命周期事件来聆听以检测每种情况,并且默认情况下,只需将适当的消息记录到JavaScript控制台即可。
默认情况下,生成的服务工作者文件将不会拦截或缓存任何交叉原始流量,例如HTTP API请求,图像或从其他域中加载的嵌入。如果您想为这些请求使用运行时缓存策略,则可以eject
,然后在webpack.config.prod.js
的SWPrecacheWebpackPlugin
部分中配置runtimeCaching
选项。
默认配置包括位于public/manifest.json
上的Web应用清单,您可以使用特定于Web应用程序的详细信息进行自定义。
当用户使用Chrome或Firefox上的Android上的Chrome或Firefox将Web应用程序添加到HOMESCREEN时, manifest.json
中的元数据。JSON确定显示Web应用程序时要使用的图标,名称和品牌颜色。 Web应用清单指南提供了更多有关每个字段的含义以及您的自定义如何影响用户体验的上下文。
源地图Explorer使用源地图分析JavaScript捆绑包。这可以帮助您了解代码膨胀的来源。
要将源地图Explorer添加到创建React App项目中,请按照以下步骤:
npm install --save source-map-explorer
或者,您可以使用yarn
:
yarn add source-map-explorer
然后在package.json
中,将以下行添加到scripts
:
"scripts": {
+ "analyze": "source-map-explorer build/static/js/main.*",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
然后,要分析捆绑包,运行生产构建,然后运行分析脚本。
npm run build
npm run analyze
npm run build
通过您的应用程序的生产构建创建一个build
目录。设置您喜欢的http服务器,以便为您的/static/js/main.<hash>.js
提供index.html
/static/js/main.<hash>.js
/static/js/main.<hash>.js
文件。
对于使用节点的环境,处理此操作的最简单方法是安装服务并让其处理其余部分:
npm install -g serve
serve -s build
上面显示的最后一个命令将在端口5000上为您的静态站点提供服务。像Serve的许多内部设置一样,可以使用-p
或--port
标志调整端口。
运行此命令以获取可用选项的完整列表:
serve -h
您不一定需要静态服务器来在生产中运行创建React App项目。它的工作原理同样可以整合到现有动力学中。
这是使用节点和Express的程序化示例:
const express = require ( 'express' ) ;
const path = require ( 'path' ) ;
const app = express ( ) ;
app . use ( express . static ( path . join ( __dirname , 'build' ) ) ) ;
app . get ( '/' , function ( req , res ) {
res . sendFile ( path . join ( __dirname , 'build' , 'index.html' ) ) ;
} ) ;
app . listen ( 9000 ) ;
您的服务器软件的选择也不重要。由于Create React App完全是平台-Nostic,因此无需明确使用节点。
带有静态资产的build
文件夹是Create React应用程序产生的唯一输出。
但是,如果您使用客户端路由,这还不够。如果您想在单页应用中支持/todos/42
之类的URL,请阅读下一节。
如果您使用在引擎盖下使用HTML5 pushState
历史记录API的路由器(例如,带有browserHistory
React路由器),许多静态文件服务器将失败。例如,如果您使用/todos/42
的路由使用React路由器,则开发服务器将适当地响应localhost:3000/todos/42
,但是如上所述的Express为生产构建服务不会。
这是因为当A /todos/42
有一个新的页面加载时,服务器会寻找文件build/todos/42
,但找不到它。需要配置服务器,以通过服务index.html
响应/todos/42
的请求。例如,我们可以修改上面的明确示例,以服务于任何未知路径: index.html
:
app.use(express.static(path.join(__dirname, 'build')));
- app.get('/', function (req, res) {
+ app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
如果您使用的是Apache HTTP服务器,则需要在看起来像这样的public
文件夹中创建一个.htaccess
文件:
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
运行npm run build
时,它将被复制到build
文件夹。
如果您使用的是Apache Tomcat,则需要按照此堆栈溢出答案。
现在,对/todos/42
的请求将在开发和生产中正确处理。
On a production build, and in a browser that supports service workers, the service worker will automatically handle all navigation requests, like for /todos/42
, by serving the cached copy of your index.html
. This service worker navigation routing can be configured or disabled by eject
ing and then modifying the navigateFallback
and navigateFallbackWhitelist
options of the SWPreachePlugin
configuration.
When users install your app to the homescreen of their device the default configuration will make a shortcut to /index.html
. This may not work for client-side routers which expect the app to be served from /
. Edit the web app manifest at public/manifest.json
and change start_url
to match the required URL scheme, for example:
"start_url" : "." ,
By default, Create React App produces a build assuming your app is hosted at the server root.
To override this, specify the homepage
in your package.json
, for example:
"homepage" : "http://mywebsite.com/relativepath" ,
This will let Create React App correctly infer the root path to use in the generated HTML file.
Note : If you are using react-router@^4
, you can root <Link>
s using the basename
prop on any <Router>
.
更多信息请点击此处。
例如:
< BrowserRouter basename = "/calendar" />
< Link to = "/today" / > // renders <a href="/calendar/today">
Note: this feature is available with
[email protected]
and higher.
If you are not using the HTML5 pushState
history API or not using client-side routing at all, it is unnecessary to specify the URL from which your app will be served. Instead, you can put this in your package.json
:
"homepage" : "." ,
This will make sure that all the asset paths are relative to index.html
. You will then be able to move your app from http://mywebsite.com
to http://mywebsite.com/relativepath
or even http://mywebsite.com/relative/path
without having to rebuild it.
See this blog post on how to deploy your React app to Microsoft Azure.
See this blog post or this repo for a way to use automatic deployment to Azure App Service.
Install the Firebase CLI if you haven't already by running npm install -g firebase-tools
. Sign up for a Firebase account and create a new project. Run firebase login
and login with your previous created Firebase account.
Then run the firebase init
command from your project's root. You need to choose the Hosting: Configure and deploy Firebase Hosting sites and choose the Firebase project you created in the previous step. You will need to agree with database.rules.json
being created, choose build
as the public directory, and also agree to Configure as a single-page app by replying with y
.
=== Project Setup
First, let ' s associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we ' ll just set up a default project.
? What Firebase project do you want to associate as default ? Example app (example-app-fd690)
=== Database Setup
Firebase Realtime Database Rules allow you to define how your data should be
structured and when your data can be read from and written to.
? What file should be used for Database Rules ? database.rules.json
✔ Database Rules for example-app-fd690 have been downloaded to database.rules.json.
Future modifications to database.rules.json will update Database Rules when you run
firebase deploy.
=== Hosting Setup
Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to uploaded with firebase deploy. If you
have a build process for your assets, use your build ' s output directory.
? What do you want to use as your public directory? build
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
✔ Wrote build/index.html
i Writing configuration info to firebase.json...
i Writing project information to .firebaserc...
✔ Firebase initialization complete!
IMPORTANT: you need to set proper HTTP caching headers for service-worker.js
file in firebase.json
file or you will not be able to see changes after first deployment (issue #2440). It should be added inside "hosting"
key like next:
{
"hosting": {
...
"headers": [
{"source": "/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}]}
]
...
Now, after you create a production build with npm run build
, you can deploy it by running firebase deploy
.
=== Deploying to ' example-app-fd690 ' ...
i deploying database, hosting
✔ database: rules ready to deploy.
i hosting: preparing build directory for upload...
Uploading: [ ============================== ] 75%✔ hosting: build folder uploaded successfully
✔ hosting: 8 files uploaded successfully
i starting release process (may take several minutes)...
✔ Deploy complete !
Project Console: https://console.firebase.google.com/project/example-app-fd690/overview
Hosting URL: https://example-app-fd690.firebaseapp.com
For more information see Add Firebase to your JavaScript Project.
Note: this feature is available with
[email protected]
and higher.
homepage
to package.json
The step below is important!
If you skip it, your app will not deploy correctly.
Open your package.json
and add a homepage
field for your project:
"homepage" : " https://myusername.github.io/my-app " ,
or for a GitHub user page:
"homepage" : " https://myusername.github.io " ,
Create React App uses the homepage
field to determine the root URL in the built HTML file.
gh-pages
and add deploy
to scripts
in package.json
Now, whenever you run npm run build
, you will see a cheat sheet with instructions on how to deploy to GitHub Pages.
To publish it at https://myusername.github.io/my-app, run:
npm install --save gh-pages
Alternatively you may use yarn
:
yarn add gh-pages
Add the following scripts in your package.json
:
"scripts": {
+ "predeploy": "npm run build",
+ "deploy": "gh-pages -d build",
"start": "react-scripts start",
"build": "react-scripts build",
The predeploy
script will run automatically before deploy
is run.
If you are deploying to a GitHub user page instead of a project page you'll need to make two additional modifications:
package.json
scripts to push deployments to master : "scripts": {
"predeploy": "npm run build",
- "deploy": "gh-pages -d build",
+ "deploy": "gh-pages -b master -d build",
npm run deploy
然后运行:
npm run deploy
gh-pages
Finally, make sure GitHub Pages option in your GitHub project settings is set to use the gh-pages
branch:
You can configure a custom domain with GitHub Pages by adding a CNAME
file to the public/
folder.
GitHub Pages doesn't support routers that use the HTML5 pushState
history API under the hood (for example, React Router using browserHistory
). This is because when there is a fresh page load for a url like http://user.github.io/todomvc/todos/42
, where /todos/42
is a frontend route, the GitHub Pages server returns 404 because it knows nothing of /todos/42
. If you want to add a router to a project hosted on GitHub Pages, here are a couple of solutions:
hashHistory
for this effect, but the URL will be longer and more verbose (for example, http://user.github.io/todomvc/#/todos/42?_k=yknaj
) 。 Read more about different history implementations in React Router.index.html
page with a special redirect parameter. You would need to add a 404.html
file with the redirection code to the build
folder before deploying your project, and you'll need to add code handling the redirect parameter to index.html
. You can find a detailed explanation of this technique in this guide.Use the Heroku Buildpack for Create React App.
You can find instructions in Deploying React with Zero Configuration.
Sometimes npm run build
works locally but fails during deploy via Heroku. Following are the most common cases.
If you get something like this:
remote: Failed to create a production build. Reason:
remote: Module not found: Error: Cannot resolve 'file' or 'directory'
MyDirectory in /tmp/build_1234/src
It means you need to ensure that the lettercase of the file or directory you import
matches the one you see on your filesystem or on GitHub.
This is important because Linux (the operating system used by Heroku) is case sensitive. So MyDirectory
and mydirectory
are two distinct directories and thus, even though the project builds locally, the difference in case breaks the import
statements on Heroku remotes.
If you exclude or ignore necessary files from the package you will see a error similar this one:
remote: Could not find a required file.
remote: Name: `index.html`
remote: Searched in: /tmp/build_a2875fc163b209225122d68916f1d4df/public
remote:
remote: npm ERR! Linux 3.13.0-105-generic
remote: npm ERR! argv "/tmp/build_a2875fc163b209225122d68916f1d4df/.heroku/node/bin/node" "/tmp/build_a2875fc163b209225122d68916f1d4df/.heroku/node/bin/npm" "run" "build"
In this case, ensure that the file is there with the proper lettercase and that's not ignored on your local .gitignore
or ~/.gitignore_global
.
To do a manual deploy to Netlify's CDN:
npm install netlify-cli -g
netlify deploy
Choose build
as the path to deploy.
To setup continuous delivery:
With this setup Netlify will build and deploy when you push to git or open a pull request:
yarn build
as the build command and build
as the publish directoryDeploy site
Support for client-side routing:
To support pushState
, make sure to create a public/_redirects
file with the following rewrite rules:
/* /index.html 200
When you build the project, Create React App will place the public
folder contents into the build output.
Now offers a zero-configuration single-command deployment. You can use now
to deploy your app for free.
Install the now
command-line tool either via the recommended desktop tool or via node with npm install -g now
.
Build your app by running npm run build
.
Move into the build directory by running cd build
.
Run now --name your-project-name
from within the build directory. You will see a now.sh URL in your output like this:
> Ready! https://your-project-name-tpspyhtdtk.now.sh (copied to clipboard)
Paste that URL into your browser when the build is complete, and you will see your deployed app.
Details are available in this article.
See this blog post on how to deploy your React app to Amazon Web Services S3 and CloudFront.
Install the Surge CLI if you haven't already by running npm install -g surge
. Run the surge
command and log in you or create a new account.
When asked about the project path, make sure to specify the build
folder, for example:
project path: /path/to/project/build
Note that in order to support routers that use HTML5 pushState
API, you may want to rename the index.html
in your build folder to 200.html
before deploying to Surge. This ensures that every URL falls back to that file.
You can adjust various development and production settings by setting environment variables in your shell or with .env.
多变的 | 发展 | 生产 | 用法 |
---|---|---|---|
浏览器 | ✅ | By default, Create React App will open the default system browser, favoring Chrome on macOS. Specify a browser to override this behavior, or set it to none to disable it completely. If you need to customize the way the browser is launched, you can specify a node script instead. Any arguments passed to npm start will also be passed to this script, and the url where your app is served will be the last argument. Your script's file name must have the .js extension. | |
主持人 | ✅ | By default, the development web server binds to localhost . You may use this variable to specify a different host. | |
港口 | ✅ | By default, the development web server will attempt to listen on port 3000 or prompt you to attempt the next available port. You may use this variable to specify a different port. | |
HTTPS | ✅ | When set to true , Create React App will run the development server in https mode. | |
PUBLIC_URL | ✅ | Create React App assumes your application is hosted at the serving web server's root or a subpath as specified in package.json ( homepage ). Normally, Create React App ignores the hostname. You may use this variable to force assets to be referenced verbatim to the url you provide (hostname included). This may be particularly useful when using a CDN to host your application. | |
CI | ? | ✅ | When set to true , Create React App treats warnings as failures in the build. It also makes the test runner non-watching. Most CIs set this flag by default. |
REACT_EDITOR | ✅ | When an app crashes in development, you will see an error overlay with clickable stack trace. When you click on it, Create React App will try to determine the editor you are using based on currently running processes, and open the relevant source file. You can send a pull request to detect your editor of choice. Setting this environment variable overrides the automatic detection. If you do it, make sure your systems PATH environment variable points to your editor's bin folder. You can also set it to none to disable it completely. | |
CHOKIDAR_USEPOLLING | ✅ | When set to true , the watcher runs in polling mode, as necessary inside a VM. Use this option if npm start isn't detecting changes. | |
GENERATE_SOURCEMAP | ✅ | When set to false , source maps are not generated for a production build. This solves OOM issues on some smaller machines. | |
节点路径 | ✅ | ✅ | Same as NODE_PATH in Node.js, but only relative folders are allowed. Can be handy for emulating a monorepo setup by setting NODE_PATH=src . |
npm start
doesn't detect changes When you save a file while npm start
is running, the browser should refresh with the updated code.
If this doesn't happen, try one of the following workarounds:
index.js
and you're referencing it by the folder name, you need to restart the watcher due to a Webpack bug..env
file in your project directory if it doesn't exist, and add CHOKIDAR_USEPOLLING=true
to it. This ensures that the next time you run npm start
, the watcher uses the polling mode, as necessary inside a VM.If none of these solutions help please leave a comment in this thread.
npm test
hangs on macOS Sierra If you run npm test
and the console gets stuck after printing react-scripts test --env=jsdom
to the console there might be a problem with your Watchman installation as described in facebookincubator/create-react-app#713.
We recommend deleting node_modules
in your project and running npm install
(or yarn
if you use it) first. If it doesn't help, you can try one of the numerous workarounds mentioned in these issues:
It is reported that installing Watchman 4.7.0 or newer fixes the issue. If you use Homebrew, you can run these commands to update it:
watchman shutdown-server
brew update
brew reinstall watchman
You can find other installation methods on the Watchman documentation page.
If this still doesn't help, try running launchctl unload -F ~/Library/LaunchAgents/com.github.facebook.watchman.plist
.
There are also reports that uninstalling Watchman fixes the issue. So if nothing else helps, remove it from your system and try again.
npm run build
exits too early It is reported that npm run build
can fail on machines with limited memory and no swap space, which is common in cloud environments. Even with small projects this command can increase RAM usage in your system by hundreds of megabytes, so if you have less than 1 GB of available memory your build is likely to fail with the following message:
The build failed because the process exited too early. This probably means the system ran out of memory or someone called
kill -9
on the process.
If you are completely sure that you didn't terminate the process, consider adding some swap space to the machine you're building on, or build the project locally.
npm run build
fails on HerokuThis may be a problem with case sensitive filenames. Please refer to this section.
If you use a Moment.js, you might notice that only the English locale is available by default. This is because the locale files are large, and you probably only need a subset of all the locales provided by Moment.js.
To add a specific Moment.js locale to your bundle, you need to import it explicitly.
例如:
import moment from 'moment' ;
import 'moment/locale/fr' ;
If import multiple locales this way, you can later switch between them by calling moment.locale()
with the locale name:
import moment from 'moment' ;
import 'moment/locale/fr' ;
import 'moment/locale/es' ;
// ...
moment . locale ( 'fr' ) ;
This will only work for locales that have been explicitly imported before.
npm run build
fails to minifySome third-party packages don't compile their code to ES5 before publishing to npm. This often causes problems in the ecosystem because neither browsers (except for most modern versions) nor some tools currently support all ES6 features. We recommend to publish code on npm as ES5 at least for a few more years.
module
field in package.json
. Note that even if a library provides an ES Modules version, it should still precompile other ES6 features to ES5 if it intends to support older browsers .Fork the package and publish a corrected version yourself.
If the dependency is small enough, copy it to your src/
folder and treat it as application code.
In the future, we might start automatically compiling incompatible third-party modules, but it is not currently supported. This approach would also slow down the production builds.
Ejecting lets you customize anything, but from that point on you have to maintain the configuration and scripts yourself. This can be daunting if you have many similar projects. In such cases instead of ejecting we recommend to fork react-scripts
and any other packages you need. This article dives into how to do it in depth. You can find more discussion in this issue.
If you have ideas for more “How To” recipes that should be on this page, let us know or contribute some!