401 / react-installer
401 React Installer
Requires
- php: >=5.3.2
- composer/installers: ~1.0.12
This package is auto-updated.
Last update: 2024-09-06 09:48:07 UTC
README
该项目使用 Create React App 引导。
以下是一些常见任务的执行信息。
您可以在此 找到本指南的最新版本。
目录
- 更新到新版本
- 发送反馈
- 文件夹结构
- 可用脚本
- 支持的浏览器
- 支持的语言特性和polyfills
- 编辑器中的语法高亮
- 在编辑器中显示lint输出
- 在编辑器中进行调试
- 自动格式化代码
- 更改页面
<title>
- 安装依赖项
- 导入组件
- 代码分割
- 添加样式表
- 后处理CSS
- 添加CSS预处理器(Sass,Less等)
- 添加图片、字体和文件
- 使用
public
文件夹 - 使用全局变量
- 添加Bootstrap
- 添加Flow
- 添加路由器
- 添加自定义环境变量
- 我可以使用装饰器吗?
- 使用AJAX请求获取数据
- 与API后端集成
- 在开发中代理API请求
- 在开发中使用HTTPS
- 在服务器上生成动态
<meta>
标签 - 预渲染到静态HTML文件
- 从服务器将数据注入页面
- 运行测试
- 调试测试
- 独立开发组件
- 将组件发布到npm
- 制作渐进式Web应用
- 分析包大小
- 部署
- 高级配置
- 故障排除
- 退出替代方案
- 缺少什么吗?
更新到新版本
创建React应用分为两个包
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
内部创建子目录。为了加快重建速度,只有 src
内部的文件会被 Webpack 处理。
您需要 将任何JS和CSS文件放在 src
内部,否则 Webpack 将看不到它们。
只有 public
内部的文件可以从 public/index.html
使用。
请阅读下面的说明,了解如何使用JavaScript和HTML中的资产。
然而,您可以创建更多的顶级目录。
它们不会被包含在生产构建中,因此您可以用于文档等。
可用脚本
在项目目录中,您可以运行
npm start
以开发模式运行应用程序。
打开 https://:3000 在浏览器中查看。
如果您进行编辑,页面将重新加载。
您还将看到控制台中的任何lint错误。
npm test
以交互式监视模式启动测试运行器。
有关更多信息,请参阅运行测试部分。
npm run build
将应用程序构建到 build
文件夹中,用于生产。
它正确地以生产模式捆绑React,并优化构建以获得最佳性能。
构建已压缩,文件名包含哈希值。
您的应用程序已准备好部署!
有关更多信息,请参阅部署部分。
npm run eject
注意:这是一个单向操作。一旦 eject
,就无法返回!
如果您对构建工具和配置选择不满意,可以随时 eject
。此命令将从您的项目中删除单个构建依赖项。
相反,它将所有配置文件和传递依赖项(Webpack、Babel、ESLint等)直接复制到您的项目中,以便您完全控制它们。除了 eject
之外的所有命令都将仍然工作,但它们将指向复制的脚本,因此您可以对其进行调整。此时您将自行负责。
您无需使用eject
。精选功能集适合小型和中型部署,您不需要强制使用此功能。然而,我们理解,如果您在需要时无法自定义此工具,则此工具将无助于您。
支持的浏览器
默认情况下,生成的项目使用最新版本的React。
有关受支持浏览器的更多信息,您可以参考React文档。
支持的语言特性和polyfills
此项目支持最新JavaScript标准的超集。
除了ES6语法功能外,它还支持
- 指数运算符(ES2016)。
- Async/await(ES2017)。
- 对象余/扩展属性(第3阶段提案)。
- 动态import()(第3阶段提案)
- 类字段和静态属性(第3阶段提案的一部分)。
- JSX和Flow语法。
有关不同提案阶段的更多信息,请参阅不同提案阶段。
虽然我们建议谨慎使用实验性提案,但Facebook在产品代码中大量使用这些功能,因此如果这些提案中的任何一个在未来发生变化,我们打算提供代码修改。
请注意,项目仅包含一些ES6polyfill
如果您使用任何其他需要运行时支持的ES6+功能(如Array.from()
或Symbol
),请确保您手动包含适当的polyfill,或者您要针对的浏览器已经支持它们。
此外,请注意,使用一些较新的语法功能,如for...of
或[...nonArrayValue]
会导致Babel生成依赖于ES6运行时功能的代码,并且可能在没有polyfill的情况下无法工作。如有疑问,请使用Babel REPL查看任何特定语法编译成什么。
编辑器中的语法高亮
要配置您最喜欢的文本编辑器的语法高亮显示,请访问相关Babel文档页面并按照说明操作。一些最流行的编辑器已涵盖。
在编辑器中显示lint输出
>注意:此功能在react-scripts@0.2.0
及更高版本中可用。
>它也只与npm 3或更高版本一起工作。
一些编辑器,包括Sublime Text、Atom和Visual Studio Code,提供ESLint插件。
它们不是必需的。您应该可以在终端以及浏览器控制台中看到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 代码,最重要的是,它使您能够拥有一个连续的开发工作流程,上下文切换最小,因为您不必在工具之间切换。
Visual Studio Code
您需要安装最新版本的 VS Code 和 VS Code Chrome Debugger 扩展。
然后将下面的块添加到您的 launch.json
文件中,并将其放置在应用程序根目录中的 .vscode
文件夹内。
{
"version": "0.2.0",
"configurations": [{
"name": "Chrome",
"type": "chrome",
"request": "launch",
"url": "https://:3000",
"webRoot": "${workspaceRoot}/src",
"sourceMapPathOverrides": {
"webpack:///src/*": "${webRoot}/*"
}
}]
}
注意:如果您通过 HOST 或 PORT 环境变量 进行了调整,URL 可能会有所不同。
通过运行 npm start
启动您的应用程序,然后按 F5
或单击绿色的调试图标在 VS Code 中开始调试。您现在可以编写代码、设置断点、更改代码并从您的编辑器调试您新修改的代码。
在 VS Code 中遇到调试问题?请参阅他们的 故障排除指南。
WebStorm
您需要安装 WebStorm 和 JetBrains IDE Support Chrome 扩展。
在 WebStorm 菜单中选择 Run
,然后选择 Edit Configurations...
。然后单击 +
并选择 JavaScript Debug
。将 https://: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
使您能够像使用 npm 脚本一样使用 githooks。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集成到你的 favorite 编辑器中。请阅读Prettier GitHub页面上的编辑器集成部分。
更改页面 <title>
生成的项目中的源HTML文件位于public
文件夹中。你可以编辑其中的<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
,该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
如果您正在使用React Router,请查看有关如何使用代码分割的教程:这里。您可以在以下GitHub仓库找到配套代码:这里。
还可以查看React文档中的代码拆分部分。
添加样式表
本项目设置使用Webpack来处理所有资产。Webpack提供了一种自定义方式来“扩展”import
的概念,使其超越JavaScript。要表达一个JavaScript文件依赖于一个CSS文件,您需要从JavaScript文件中导入CSS。
Button.css
.Button {
padding: 20px;
}
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自动压缩CSS并添加供应商前缀,因此您无需担心。
例如,这
.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预处理器(Sass,Less等)
通常,我们建议您不要在不同组件之间重用相同的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";
变量定义。
要启用不使用相对路径导入文件,您可以在package.json
中命令中添加--include-path
选项。
"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
已被报告存在以下问题
node-sass-chokidar
在这里被使用,因为它解决了这些问题。
添加图片、字体和文件
使用Webpack,使用静态资产(如图像和字体)的工作方式类似于CSS。
您可以直接在JavaScript模块中导入
一个文件。这告诉Webpack将此文件包含在包中。与CSS导入不同,导入文件会返回一个字符串值。此值是您可以在代码中引用的最终路径,例如图像的src
属性或指向PDF链接的href
。
为了减少对服务器的请求数量,小于10,000字节的图像导入返回一个data 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
文件夹
>注意:此功能在react-scripts@0.5.0
及以上版本中可用。
更改HTML
公共文件夹包含HTML文件,因此您可以对其进行修改,例如,设置页面标题。编译过程中将自动将包含编译代码的<script>
标签添加到其中。
在模块系统外添加资产
您还可以将其他资源添加到公共文件夹中。
请注意,我们通常建议您在JavaScript文件中导入资源。例如,请参阅有关添加样式表和添加图片和字体的部分。此机制提供了一系列好处
- 脚本和样式表会被压缩并打包在一起,以避免额外的网络请求。
- 缺少的文件将导致编译错误,而不是用户看到404错误。
- 结果文件名包括内容哈希,因此您不必担心浏览器缓存其旧版本。
但是,您可以使用一个“逃生口”来将资源添加到模块系统之外。
如果您将文件放入公共文件夹,它将不会被Webpack处理。相反,它将被无修改地复制到构建文件夹。要引用公共文件夹中的资源,您需要使用一个名为PUBLIC_URL
的特殊变量。
在index.html
内部,您可以这样使用它
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
只有公共文件夹内的文件才能通过%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'} />;
}
请注意此方法的缺点
- 公共文件夹中的所有文件都不会进行后处理或压缩。
- 缺少的文件在编译时不会被调用,并将导致用户看到404错误。
- 结果文件名不会包含内容哈希,因此您需要每次更改时都添加查询参数或重命名。
何时使用 public
文件夹
通常我们建议从JavaScript导入样式表、图片和字体。公共文件夹对于一些不太常见的用例很有用
- 您需要在构建输出中包含具有特定名称的文件,例如
manifest.webmanifest
。 - 您有成千上万张图片,需要动态引用它们的路径。
- 您想要在捆绑代码之外包含一个小的脚本,如
pace.js
。 - 某些库可能与Webpack不兼容,您别无选择,只能将其作为
<script>
标签包含。
请注意,如果您添加了一个声明全局变量的<script>
,您还需要阅读有关使用它们的下一节。
使用全局变量
当您在HTML文件中包含一个定义全局变量的脚本并尝试在代码中使用这些变量之一时,检查器会抱怨因为它看不到变量的定义。
您可以通过从window
对象显式读取全局变量来避免这种情况,例如
const $ = window.$;
这使得您明确知道您有意使用全局变量,而不是因为打字错误。
或者,您可以通过在之后添加// eslint-disable-line
来强制检查器忽略任何行。
添加Bootstrap
您不必将 React Bootstrap 与 React 同时使用,但它是一个将 Bootstrap 集成到 React 应用中的流行库。如果您需要它,可以按照以下步骤通过 Create React App 集成 React Bootstrap:
从 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。
- 添加必要的构建步骤以调整主题,并在 npm 上发布您的包。
- 将您的自定义主题 npm 包作为您的应用程序的依赖项安装。
以下是一个添加 自定义 Bootstrap 的示例,它遵循这些步骤。
添加Flow
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
中的所有代码,并将其替换为其网站上任何示例。从 基本示例 开始是一个不错的选择。
请注意,在部署应用程序之前,您可能需要配置生产服务器以支持客户端路由。
添加自定义环境变量
>注意:此功能在 react-scripts@0.2.3
和更高版本中可用。
您的项目可以像在本地 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
编译应用程序时,压缩步骤将删除此条件,并且生成的包将更小。
在HTML中引用环境变量
>注意:此功能在 react-scripts@0.9.0
及更高版本中可用。
您还可以在 public/index.html
中访问以 REACT_APP_
开头的环境变量。例如
<title>%REACT_APP_WEBSITE_NAME%</title>
注意,上述部分中的限制也适用
- 除了少数内置变量(
NODE_ENV
和PUBLIC_URL
)之外,变量名称必须以REACT_APP_
开头才能正常工作。 - 环境变量是在构建时注入的。如果需要在运行时注入,请遵循此方法。
在您的Shell中添加临时环境变量
定义环境变量的方式在不同操作系统之间可能有所不同。还重要的是要知道,这种方式对于 shell 会话的生命周期来说是临时的。
Windows (cmd.exe)
set "REACT_APP_SECRET_CODE=abcdef" && npm start
(注意:变量分配的引号是必需的,以避免尾随空格。)
Windows (Powershell)
($env:REACT_APP_SECRET_CODE = "abcdef") -and (npm start)
Linux,macOS (Bash)
REACT_APP_SECRET_CODE=abcdef npm start
在 .env
中添加开发环境变量
>注意:此功能在react-scripts@0.5.0
及以上版本中可用。
要定义永久环境变量,请在项目的根目录中创建一个名为 .env
的文件
REACT_APP_SECRET_CODE=abcdef
>注意:您必须创建以 REACT_APP_
开头的自定义环境变量。除了 NODE_ENV
之外的其他变量将被忽略,以避免意外泄露可能在机器上具有相同名称的私钥。更改任何环境变量都需要您重启正在运行的开发服务器。
.env
文件应 提交到源代码控制(排除 .env*.local
)。
还可以使用哪些 .env
文件?
>注意:此功能在 react-scripts@1.0.0
及更高版本中可用。
.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
、.env.production
、.env.local
、.env
npm test
:.env.test.local
、.env.test
、.env
(注意.env.local
缺失)
如果机器未明确设置这些变量,则这些变量将作为默认值。
有关更多详细信息,请参阅dotenv 文档。
>注意:如果您正在为开发定义环境变量,则您的 CI 和/或托管平台可能也需要定义这些变量。请查阅它们的文档了解如何操作。例如,请参阅Travis CI 或 Heroku 的文档。
在 .env
中扩展环境变量
>注意:此功能在 react-scripts@1.1.0
及更高版本中可用。
使用 dotenv-expand 扩展您机器上已存在的变量,以便在您的 .env
文件中使用。
例如,要获取环境变量 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
我可以使用装饰器吗?
许多流行的库在它们的文档中使用了 装饰器。
创建 React App 目前不支持装饰器语法,因为
- 这是一个实验性提议,可能会更改。
- 当前规范版本尚未得到 Babel 的官方支持。
- 如果规范发生变化,我们无法编写 codemod,因为我们没有在 Facebook 内部使用它们。
然而,在许多情况下,您可以在不使用装饰器的情况下很好地重写基于装饰器的代码。
请参考这两个线程以供参考
当规范发展到稳定阶段时,Create React App 将添加装饰器支持。
使用AJAX请求获取数据
React 没有规定数据获取的具体方法,但人们通常使用像 axios 这样的库或浏览器提供的 fetch()
API。方便的是,Create React App 包含了 fetch()
的 polyfill,因此您可以在不担心浏览器支持的情况下使用它。
全局的 fetch
函数允许轻松地进行 AJAX 请求。它接受一个 URL 作为输入,并返回一个解析为 Response
对象的 Promise
。您可以在这里找到有关 fetch
的更多信息。
此项目还包括一个 Promise polyfill,它提供了 Promises/A+ 的完整实现。Promise 表示异步操作最终的结果,您可以在这里和这里找到有关 Promise 的更多信息。axios 和 fetch()
在底层都使用 Promise。您还可以使用 async / await
语法来减少回调嵌套。
您可以在 React 网站的常见问题解答条目中了解更多有关从 React 组件中制作 AJAX 请求的信息。
与API后端集成
这些教程将帮助您将您的应用程序与运行在其他端口的 API 后端集成,使用 fetch()
来访问它。
Node
Ruby on Rails
在开发中代理API请求
>注意:此功能在 react-scripts@0.2.3
和更高版本中可用。
人们通常将前端 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
字段,例如
"proxy": "https://:4000",
这样,当您在开发中使用 fetch('/api/todos')
时,开发服务器将识别它不是一个静态资源,并将其作为后备代理到 https://:4000/api/todos
。开发服务器将仅尝试将具有不带 text/html
的 Accept
标头的请求发送到代理。
方便的是,这避免了CORS 问题以及开发期间出现的类似错误信息
Fetch API cannot load https://:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://: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、HTTPS 和 WebSocket 连接。
如果 proxy
选项不够灵活,您还可以
- 自行配置代理
- 在您的服务器上启用 CORS(这里是如何为 Express 做的)。
- 使用环境变量将正确的服务器主机和端口注入到您的应用程序中。
配置代理后出现的 "无效的主机头" 错误
当您启用 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
我们不推荐这种方法。
手动配置代理
>注意:此功能在 react-scripts@1.0.0
及更高版本中可用。
如果 proxy
选项对您来说不够灵活,您可以在 package.json
中指定以下形式的对象。
您还可以指定任何配置值,这些配置值由 http-proxy-middleware
或 http-proxy
支持。
{
// ...
"proxy": {
"/api": {
"target": "<url>",
"ws": true
// ...
}
}
// ...
}
所有匹配此路径的请求都将被代理,没有例外。这包括对 text/html
的请求,这是标准 proxy
选项不代理的。
如果您需要指定多个代理,可以通过指定额外的条目来实现。匹配是正则表达式,因此您可以使用正则表达式来匹配多个路径。
{
// ...
"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代理
在设置 WebSocket 代理时,有一些额外的注意事项需要了解。
如果您使用的是像 Socket.io 这样的 WebSocket 引擎,您必须有一个运行的 Socket.io 服务器,您可以使用它作为代理目标。Socket.io 不能与标准的 WebSocket 服务器一起工作。具体来说,不要期望 Socket.io 与websocket.org echo test一起工作。
有关设置 Socket.io 服务器的一些良好文档可供参考。
标准 WebSockets 将与标准 WebSocket 服务器以及 websocket.org echo test 一起工作。您可以使用库如 ws 作为服务器,并在浏览器中使用 原生的 WebSockets。
无论哪种方式,您都可以在 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
// ...
}
}
// ...
}
在开发中使用HTTPS
>注意:此功能在 react-scripts@0.4.0
及更高版本中可用。
您可能需要开发服务器通过 HTTPS 来提供页面。在以下情况下这可能很有用:当 API 服务器本身也在提供 HTTPS 时,使用“proxy”功能代理到 API 服务器。
为此,将 HTTPS
环境变量设置为 true
,然后使用 npm start
像往常一样启动开发服务器。
Windows (cmd.exe)
set HTTPS=true&&npm start
Windows (Powershell)
($env:HTTPS = $true) -and (npm start)
(注意:空白不足是故意的。)
Linux,macOS (Bash)
HTTPS=true npm start
请注意,服务器将使用自签名证书,因此您的网络浏览器在访问页面时几乎肯定会显示警告。
在服务器上生成动态 <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
读取到内存中,并用根据当前URL的值替换__OG_TITLE__
、__OG_DESCRIPTION__
和其他任何占位符。只需确保对插值值进行清理和转义,以确保它们安全地嵌入到HTML中!
如果您使用的是Node服务器,您甚至可以在客户端和服务器之间共享路由匹配逻辑。然而,在简单情况下,复制它也完全可以。
预渲染到静态HTML文件
如果您使用静态托管提供商托管您的build
,您可以使用react-snapshot或react-snap为应用程序中的每个路由或相对链接生成HTML页面。然后,当JavaScript包加载完成后,这些页面将无缝变为活动状态或“水合”。
此外,还有机会在静态托管之外使用此功能,以减轻服务器生成和缓存路由的压力。
预渲染的主要好处是,您可以在HTML有效负载中获取每个页面的核心内容——无论JavaScript包是否成功下载。它还增加了搜索引擎抓取您应用程序每个路由的可能性。
您可以在这里了解更多关于零配置预渲染(也称为快照)的信息。
从服务器将数据注入页面
与上一节类似,您可以在HTML中留下一些占位符以注入全局变量,例如
<!doctype html>
<html lang="en">
<head>
<script>
window.SERVER_DATA = __SERVER_DATA__;
</script>
然后,在服务器上,您可以在发送响应之前将__SERVER_DATA__
替换为包含真实数据的JSON。然后客户端代码可以读取window.SERVER_DATA
来使用它。确保在发送到客户端之前清理JSON,因为它会使您的应用程序容易受到XSS攻击。
运行测试
>>注意:此功能在react-scripts@0.3.0
及以上版本中可用。
>>阅读迁移指南以了解如何在旧项目中启用它!
Create React App使用Jest作为其测试运行器。为了准备此集成,我们对Jest进行了重大更新,如果您几年前听到了关于它的负面消息,请再试一次。
Jest是一个基于Node的运行器。这意味着测试始终在Node环境中运行,而不是在真实的浏览器中。这使我们能够启用快速的迭代速度并防止不稳定性。
虽然Jest通过jsdom提供了浏览器全局变量,如window
,但它们只是真实浏览器行为的近似。Jest旨在用于逻辑和组件的单元测试,而不是DOM怪癖。
如果您需要浏览器端到端测试,我们建议您使用单独的工具。这超出了Create React App的范围。
文件名约定
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 运行所有测试。
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()
匹配器都在这里有广泛的文档: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
中找到这样的测试。
当你遇到由更改组件引起的错误时,你将更深入地了解应用程序中哪些部分值得测试。这可能是一个引入更具体测试的好时机,以断言特定的预期输出或行为。
如果你想要在渲染的子组件之外测试组件,我们建议使用来自 Enzyme 的 shallow()
渲染 API。要安装它,运行
npm install --save enzyme enzyme-adapter-react-16 react-test-renderer
或者您也可以使用 yarn
yarn add enzyme enzyme-adapter-react-16 react-test-renderer
截至 Enzyme 3,你需要安装与您使用的 React 版本对应的适配器以及 Enzyme。(上面的例子使用的是 React 16 的适配器。)
适配器也需要在您的全局设置文件中进行配置
src/setupTests.js
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
>注意:如果您在创建 src/setupTests.js
之前选择“eject”,则生成的 package.json
文件将不包含对它的任何引用。在此处阅读了解如何在eject后添加它。
现在您可以使用它编写一个烟雾测试
import React from 'react';
import { shallow } from 'enzyme';
import App from './App';
it('renders without crashing', () => {
shallow(<App />);
});
与之前使用 ReactDOM.render()
进行的烟雾测试不同,此测试仅渲染 <App>
而不深入。例如,即使 <App>
本身渲染了一个引发错误的 <Button>
,此测试也会通过。浅渲染非常适合隔离单元测试,但您可能仍然想创建一些完整的渲染测试,以确保组件正确集成。Enzyme 支持使用 mount()
进行完整渲染,您还可以用它来测试状态变化和组件生命周期。
您可以通过Enzyme 文档了解更多的测试技术。Enzyme 文档使用 Chai 和 Sinon 进行断言,但您不必使用它们,因为 Jest 提供了内置的 expect()
和 jest.fn()
用于间谍。
以下是一个来自 Enzyme 文档的示例,它断言特定的输出,重写为使用 Jest 匹配器
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);
});
所有 Jest 匹配器都在此处进行了广泛的文档说明。
尽管如此,如果您愿意,可以使用第三方断言库,如Chai,如下所述。
此外,您可能会发现 jest-enzyme 非常有助于使用可读的匹配器简化测试。上面的 contains
代码可以使用 jest-enzyme 写得更简单。
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,我们会修复它们。我们打算继续为 React 优化它们,例如,支持将 React 元素以 JSX 格式打印。
但是,如果您习惯了其他库,例如 Chai 和 Sinon,或者如果您有使用这些库的现有代码并希望将其迁移过来,您可以像这样正常导入它们
import sinon from 'sinon';
import { expect } from 'chai';
然后像平常一样在测试中使用它们。
初始化测试环境
>注意:此功能在 react-scripts@0.4.0
及更高版本中可用。
如果您的应用程序使用需要在测试中进行模拟的浏览器 API 或在运行测试之前需要全局设置,请向您的项目添加一个 src/setupTests.js
。它将在运行测试之前自动执行。
例如
src/setupTests.js
const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
clear: jest.fn()
};
global.localStorage = localStorageMock
>注意:如果您在创建 src/setupTests.js
之前选择“eject”,则生成的 package.json
文件将不包含对它的任何引用,因此您应该在 Jest 的配置中手动创建属性 setupTestFrameworkScriptFile
,如下所示
>`
js >"jest": {
// ... "setupTestFrameworkScriptFile": "
聚焦和排除测试
您可以使用 it()
替换为 xit()
来暂时排除一个测试的执行。
同样,fit()
允许您专注于特定测试而无需运行任何其他测试。
覆盖率报告
Jest 集成了覆盖报告器,与 ES6 兼容且无需配置。
运行 npm test -- --coverage
(注意中间的额外 --
)以包含如下覆盖报告
注意,带有覆盖的测试运行速度会慢很多,因此建议将其与常规工作流程分开运行。
配置
默认的 Jest 覆盖配置可以通过在 package.json 中的 Jest 配置中添加以下支持的键之一来覆盖。
支持的覆盖
示例 package.json
{
"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
运行带有交互式 CLI 的监视器。但是,您可以通过设置名为 CI
的环境变量来强制其运行一次测试并结束进程。
使用 npm run build
创建应用程序的构建时,默认情况下不会检查代码检查警告。与 npm test
一样,您可以通过设置环境变量 CI
来强制构建执行代码检查警告检查。如果遇到任何警告,则构建失败。
流行的 CI 服务器已默认设置环境变量 CI
,但您也可以自行设置
在 CI 服务器上
Travis CI
- 按照 Travis 入门 指南将 GitHub 仓库与 Travis 同步。您可能需要在您的 配置文件 页面上手动初始化一些设置。
- 将
.travis.yml
文件添加到您的 git 仓库中。language: node_js node_js: - 6 cache: directories: - node_modules script: - npm run build - npm test
- 通过 git push 触发您的第一次构建。
- 如有需要,请自定义 Travis CI 构建。
CircleCI
按照 这篇文章 设置 CircleCI 与 Create React App 项目。
在自己的环境中
Windows (cmd.exe)
set CI=true&&npm test
set CI=true&&npm run build
(注意:空白不足是故意的。)
Windows (Powershell)
($env:CI = $true) -and (npm test)
($env:CI = $true) -and (npm run build)
Linux,macOS (Bash)
CI=true npm test
CI=true npm run build
测试命令将强制 Jest 一次性运行测试而不是启动监视器。
如果您在开发中经常这样做,请 提交一个问题 告诉我们您的用例,因为我们希望监视器有最好的体验,并且愿意改变其工作方式以适应更多的工作流程。
构建命令将检查代码检查警告,如果发现任何警告则构建失败。
禁用jsdom
默认情况下,生成的项目的 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()
在 Enzyme
相比之下,以下 API 不需要 jsdom
最后,jsdom 也不需要用于 快照测试。
快照测试
快照测试是 Jest 的一项功能,它可以自动生成组件的文本快照并保存在磁盘上。这样一来,如果 UI 输出发生变化,你将收到通知,无需手动编写任何断言来检查组件输出。 了解更多关于快照测试的信息。
编辑器集成
如果你使用 Visual Studio Code,有一个 Jest 扩展,它可以与 Create React App 直接配合使用。这提供了许多类似 IDE 的功能,同时在文本编辑器中使用:显示测试运行的状况以及潜在失败的消息,自动启动和停止监视器,并提供一键更新快照。
调试测试
为 Jest 测试设置调试器有多种方法。我们介绍了在 Chrome 和 Visual Studio Code 中的调试。
>注意:调试测试需要 Node 8 或更高版本。
在Chrome中调试测试
将以下内容添加到项目 package.json
文件的 scripts
部分
"scripts": {
"test:debug": "react-scripts --inspect-brk test --runInBand --env=jsdom"
}
在任何测试中放置 debugger;
语句并运行
$ npm run test:debug
这将开始运行你的 Jest 测试,但在执行前会暂停,以便调试器可以连接到进程。
在 Chrome 中打开以下链接
about:inspect
打开该链接后,Chrome 开发者工具将显示。选择你的进程上的 inspect
,在 react 脚本的第 1 行设置一个断点(这样做是为了给你时间打开开发者工具,并防止 Jest 在你有机会这样做之前执行)。点击屏幕右上角看起来像“播放”按钮的按钮以继续执行。当 Jest 执行包含调试器语句的测试时,执行将暂停,你可以检查当前作用域和调用堆栈。
>注意:--runInBand 命令行选项确保 Jest 在同一个进程中运行测试,而不是为单个测试生成进程。通常 Jest 在进程间并行化测试运行,但调试多个进程比较困难。
在Visual Studio Code中调试测试
Jest 测试的调试在 Visual Studio Code 中是开箱即用的。
使用以下 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 组件,每个组件都有很多不同的状态。例如,一个简单的按钮组件可能有以下状态
- 在正常状态下,带有文本标签。
- 在禁用模式下。
- 在加载状态下。
通常,没有运行示例应用或示例,很难看到这些状态。
Create React App 默认不包含任何工具,但你可以轻松地将 Storybook for React (source) 或 React Styleguidist (source) 添加到项目中。这些是第三方工具,让你在独立于应用的情况下开发组件并查看它们的所有状态。
你还可以将 Storybook 或风格指南作为静态应用部署。这样,团队中的每个人都可以查看和审查 UI 组件的不同状态,无需启动后端服务器或在应用中创建账户。
开始使用Storybook
Storybook 是 React UI 组件的开发环境。它允许你浏览组件库,查看每个组件的不同状态,并交互式地开发测试组件。
首先,全局安装以下 npm 包
npm install -g @storybook/cli
然后,在应用的目录内运行以下命令
getstorybook
之后,按照屏幕上的说明操作。
了解有关React Storybook的更多信息
- 屏幕录像: React Storybook入门
- GitHub仓库
- 文档
- 使用Storybook和addon/storyshot进行快照测试UI
开始使用Styleguidist
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 Styleguidist的更多信息
将组件发布到npm
Create React App不提供任何内置功能来将组件发布到npm。如果你准备好从你的项目中提取组件,以便其他人可以使用,我们建议将其移动到项目外的单独目录,然后使用nwb等工具来准备发布。
制作渐进式Web应用
默认情况下,生产构建是一个完全功能性的、离线优先的渐进式Web应用。
渐进式Web应用比传统Web页面更快、更可靠,并提供引人入胜的移动体验
- 所有静态站点资产都会被缓存,这样无论网络连接性如何(如2G或3G),你的页面在后续访问时都能快速加载。更新将在后台下载。
- 无论网络状态如何,你的应用都将正常运行,即使在离线状态下。这意味着你的用户可以在10,000英尺高空和地铁上使用你的应用。
- 在移动设备上,你的应用可以直接添加到用户的首页,包括应用图标。你还可以使用web 推送通知重新吸引用户,这消除了对应用商店的需求。
sw-precache-webpack-plugin
已集成到生产配置中,并将负责生成一个服务工作者文件,该文件将自动预缓存所有本地资产,并在你部署更新时保持它们最新。服务工作者将使用先缓存策略来处理所有本地资产的请求,包括初始HTML,确保你的Web应用即使在缓慢或不稳定网络上也能可靠快速。
选择退出缓存
如果你希望在初始生产部署之前不启用服务工作者,请从src/index.js
中移除对registerServiceWorker()
的调用。
如果你之前在生产部署中启用了服务工作者,并决定希望为所有现有用户禁用它们,你可以先通过修改服务工作者导入来替换src/index.js
中的registerServiceWorker()
调用
import { unregister } from './registerServiceWorker';
然后调用unregister()
代替。用户访问包含unregister()
的页面后,服务工作者将被卸载。请注意,根据如何提供/service-worker.js
,缓存失效可能需要长达24小时。
离线第一考虑事项
服务工作者要求使用HTTPS,尽管为了方便本地测试,该策略不适用于
localhost
。如果你的生产Web服务器不支持HTTPS,则服务工作者注册将失败,但你的Web应用的其余部分仍然可以正常工作。服务工作者目前不是所有Web浏览器的支持功能。在缺少支持的浏览器上,将不会尝试进行服务工作者注册。
服务工作者仅在生产环境中启用,例如
npm run build
的输出。建议你在开发环境中不要启用离线优先的服务工作者,因为它可能导致当使用之前缓存的资源且这些资源不包括你本地所做的最新更改时产生挫败感。如果你需要本地测试你的离线优先服务工作者,请构建应用(使用
npm run build
),并从构建目录运行一个简单的http服务器。在运行构建脚本后,create-react-app
将给出一种在本地测试你的生产构建的方法,以及部署说明将给出使用其他方法的说明。请确保始终使用无痕窗口以避免浏览器缓存引起的复杂性。如果可能,配置你的生产环境以禁用HTTP缓存来提供生成的
service-worker.js
。如果这不可能——例如,GitHub Pages不允许你更改默认的10分钟HTTP缓存生存期——那么请记住,如果你在service-worker.js
从你的HTTP缓存中过期之前再次访问你的生产网站,你将仍然从服务工作者获取之前缓存的资源。如果你需要立即查看你的更新后的生产部署,执行快速刷新将暂时禁用服务工作者并从网络检索所有资源。用户并不总是熟悉离线优先的Web应用。当服务工作者完成填充你的缓存(显示“此Web应用可在离线使用!”消息)以及获取下次加载页面时将可用的最新更新时(显示“有新内容可供使用;请刷新。”消息),通知用户是有用的。显示这些消息目前留给开发者自行处理,但作为一个起点,你可以使用
src/registerServiceWorker.js
中包含的逻辑,它演示了如何监听每个场景的服务工作者生命周期事件,并将适当的消息作为默认值记录到JavaScript控制台。默认情况下,生成的服务工作者文件不会拦截或缓存任何跨源流量,例如来自不同域的HTTP API请求、图片或嵌入内容。如果您想为这些请求使用运行时缓存策略,可以在
eject
之后,在runtimeCaching
选项中配置webpack.config.prod.js
文件中的SWPrecacheWebpackPlugin
部分。
渐进式Web应用元数据
默认配置包括位于public/manifest.json
的Web应用清单,您可以自定义与您的Web应用程序相关的详细信息。
当用户使用Android上的Chrome或Firefox将Web应用添加到主屏幕时,manifest.json
中的元数据将确定Web应用显示时使用的图标、名称和品牌颜色。Web App Manifest指南提供了有关每个字段含义以及您的自定义如何影响用户体验的更多上下文。
分析包大小
源映射探索器使用源映射分析JavaScript包。这有助于您了解代码膨胀的来源。
要将源映射探索器添加到Create 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服务器,以便访问您站点的访客被提供index.html
,对像/static/js/main.<hash>.js
这样的静态路径的请求使用/static/js/main.<hash>.js
文件的內容进行服务。
静态服务器
对于使用Node的环境,最简单的方法是安装serve,然后由它处理其余的工作
npm install -g serve
serve -s build
上述最后一个命令将在端口5000上提供您的静态站点。像serve的许多内部设置一样,端口号可以使用-p
或--port
标志进行调整。
运行此命令以获取可用选项的完整列表
serve -h
其他解决方案
运行Create React App项目并不一定需要静态服务器。它可以很好地集成到现有的动态服务器中。
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是完全平台无关的,因此无需显式使用Node。
包含静态资产的build
文件夹是Create React App产生的唯一输出。
但是,如果您使用客户端路由,这还不够。如果您想在单页应用程序中支持像/todos/42
这样的URL,请阅读下一节。
使用客户端路由服务应用
如果您使用的路由器内部使用了HTML5 pushState
历史API(例如,使用 React Router 并开启 browserHistory
),则许多静态文件服务器可能会失败。例如,如果您使用React Router为 /todos/42
路由,开发服务器将正确响应 localhost:3000/todos/42
,但如上所述的Express服务器则不会。
这是因为当加载一个全新的 /todos/42
页面时,服务器会查找 build/todos/42
文件,但找不到它。服务器需要配置为在接收到对 /todos/42
的请求时,通过提供 index.html
来响应。例如,我们可以修改上面的Express示例,以服务任何未知路径的 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 Server,您需要在 public
文件夹中创建一个类似于以下的 .htaccess
文件。
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
当您运行 npm run build
时,它将被复制到 build
文件夹。
如果您使用的是 Apache Tomcat,您需要遵循 这个Stack Overflow回答。
现在,无论是开发阶段还是生产阶段,对 /todos/42
的请求都将被正确处理。
在生产构建中,以及支持 service workers 的浏览器中,service worker将自动处理所有导航请求,例如对 /todos/42
的请求,通过提供缓存的 index.html
来处理。可以通过 eject
并修改 SWPreachePlugin
的 navigateFallback
和 navigateFallbackWhitelist
选项来配置或禁用此服务工作者导航路由。
当用户将您的应用安装到设备的主屏幕时,默认配置将创建指向 /index.html
的快捷方式。这可能不适用于期望应用从 /
路径提供的客户端路由器。编辑位于 public/manifest.json
的Web应用清单,并将 start_url
修改为所需的URL方案,例如
"start_url": ".",
为相对路径构建
默认情况下,Create React App假设您的应用托管在服务器根目录。
要覆盖此设置,请在您的 package.json
中指定 homepage
,例如
"homepage": "http://mywebsite.com/relativepath",
这会让Create React App正确推断在生成的HTML文件中使用的根路径。
注意:如果您正在使用 react-router@^4
,您可以使用任何 <Router>
上的 basename
属性来根化 <Link>
。
更多信息请查看这里。
例如
<BrowserRouter basename="/calendar"/>
<Link to="/today"/> // renders <a href="/calendar/today">
从不同路径提供相同的构建
>注意:此功能在 react-scripts@0.9.0
及更高版本中可用。
如果您没有使用HTML5 pushState
历史API,或者根本就没有使用客户端路由,那么指定应用将从哪个URL提供是不必要的。相反,您可以将此放在您的 package.json
中
"homepage": ".",
这将确保所有资产路径都是相对于 index.html
的。然后您可以将您的应用从 http://mywebsite.com
移动到 http://mywebsite.com/relativepath
或甚至 http://mywebsite.com/relative/path
,而无需重新构建。
Azure
请参阅这篇博客文章,了解如何将React应用部署到Microsoft Azure。
请参阅这篇博客文章或这个存储库,了解如何使用自动部署到Azure App Service的方法。
Firebase
如果您还没有安装,请运行npm install -g firebase-tools
来安装Firebase CLI。注册一个Firebase账号并创建一个新的项目。运行firebase login
并使用您之前创建的Firebase账号进行登录。
然后从项目的根目录运行firebase init
命令。您需要选择Hosting: 配置和部署Firebase Hosting站点并选择在上一步骤中创建的Firebase项目。您需要同意创建database.rules.json
,选择build
作为公共目录,并回答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!
重要提示:您需要在firebase.json
文件中为service-worker.js
文件设置正确的HTTP缓存头,否则在首次部署后您将无法看到更改(问题#2440)。它应该添加到"hosting"
键中,如下所示:
{
"hosting": {
...
"headers": [
{"source": "/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}]}
]
...
现在,在您使用npm run build
创建生产构建后,您可以通过运行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
有关更多信息,请参阅将Firebase添加到JavaScript项目。
GitHub Pages
>注意:此功能在react-scripts@0.2.0
及更高版本中可用。
步骤1:将homepage
添加到package.json
以下步骤很重要!
如果您跳过此步骤,则您的应用程序将无法正确部署。
打开您的package.json
,并为您的项目添加一个homepage
字段
"homepage": "https://myusername.github.io/my-app",
或GitHub用户页面
"homepage": "https://myusername.github.io",
React App使用homepage
字段来确定构建HTML文件的根URL。
步骤2:安装gh-pages
并将deploy
添加到package.json
中的scripts
现在,每次您运行npm run build
时,您都会看到一个包含如何部署到GitHub Pages的说明的快捷方式。
要将其发布到https://myusername.github.io/my-app,请运行
npm install --save gh-pages
或者您也可以使用 yarn
yarn add gh-pages
在package.json
中添加以下脚本
"scripts": {
+ "predeploy": "npm run build",
+ "deploy": "gh-pages -d build",
"start": "react-scripts start",
"build": "react-scripts build",
predeploy
脚本将在运行deploy
之前自动运行。
如果您正在部署到GitHub用户页面而不是项目页面,则需要做出两个额外的修改
- 首先,将您的仓库源分支更改为除
master
之外的任何分支。 - 此外,调整您的
package.json
脚本以将部署推送到master
"scripts": { "predeploy": "npm run build", - "deploy": "gh-pages -d build", + "deploy": "gh-pages -b master -d build",
步骤3:通过运行npm run deploy
来部署站点
然后运行
npm run deploy
步骤4:确保您的项目设置使用gh-pages
最后,确保在GitHub项目设置中强制的GitHub Pages选项使用gh-pages
分支
步骤5:(可选)配置域名
您可以通过在public/
文件夹中添加一个CNAME
文件,使用GitHub Pages配置自定义域名。
关于客户端路由的说明
GitHub Pages不支持底层使用HTML5 pushState
历史API的路由器(例如,使用browserHistory
的React Router)。这是因为当一个页面如http://user.github.io/todomvc/todos/42
进行新鲜页面加载时,其中/todos/42
是前端路由,GitHub Pages服务器返回404,因为它不知道/todos/42
。如果您想将路由器添加到托管在GitHub Pages上的项目,以下是一些解决方案:
- 您可以从使用HTML5历史API切换到基于哈希的路由。如果您使用React Router,可以将路由切换到
hashHistory
来实现此效果,但URL会更长、更冗长(例如,http://user.github.io/todomvc/#/todos/42?_k=yknaj
)。有关React Router中不同历史实现的更多信息,请参阅此处。 - 或者,您可以使用一个技巧来教会GitHub Pages通过特殊重定向参数重定向到您的
index.html
页面来处理404错误。在部署项目之前,您需要在build
文件夹中添加包含重定向代码的404.html
文件,并且您需要将处理重定向参数的代码添加到index.html
中。您可以在此指南中找到关于此技术的详细说明。
Heroku
使用Create React App的Heroku构建包。
您可以在无配置部署React中找到说明。
解决Heroku部署错误
有时在本地使用npm run build
正常工作,但在通过Heroku部署时失败。以下是最常见的几种情况。
"无法找到模块:错误:无法解析'文件'或'目录'"
如果您遇到类似以下内容的情况
remote: Failed to create a production build. Reason:
remote: Module not found: Error: Cannot resolve 'file' or 'directory'
MyDirectory in /tmp/build_1234/src
这意味着您需要确保您import
的文件或目录的字母大小写与您在文件系统或GitHub上看到的一致。
这很重要,因为Linux(Heroku使用的操作系统)是大小写敏感的。因此,MyDirectory
和mydirectory
是两个不同的目录,因此,尽管项目在本地构建,但大小写的差异会在Heroku远程服务器上的import
语句中破坏。
"无法找到所需的文件。"
如果您从包中排除或忽略必要的文件,您将看到类似的错误
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"
在这种情况下,请确保文件存在且字母大小写正确,并且在您的本地.gitignore
或~/.gitignore_global
中没有忽略。
Netlify
手动部署到Netlify的CDN
npm install netlify-cli -g
netlify deploy
将build
作为部署路径。
设置持续交付
有了这个设置,Netlify将在您推送到git或打开一个pull request时构建和部署。
- 开始一个新的Netlify项目
- 选择您的Git托管服务并选择您的存储库
- 将
yarn build
设置为构建命令,将build
设置为发布目录 - 点击
部署站点
客户端路由支持
要支持pushState
,请确保创建一个包含以下重写规则的public/_redirects
文件
/* /index.html 200
构建项目时,Create React App会将public
文件夹的内容放入构建输出中。
Now
现在提供零配置的单命令部署。您可以使用now
免费部署您的应用程序。
通过推荐桌面工具或通过node使用
npm install -g now
安装now
命令行工具。通过运行
npm run build
构建您的应用程序。通过运行
cd build
进入构建目录。在构建目录中运行
now --name your-project-name
。您将在输出中看到一个类似的now.sh
URL> Ready! https://your-project-name-tpspyhtdtk.now.sh (copied to clipboard)
构建完成后,将此URL粘贴到浏览器中,您将看到已部署的应用程序。
有关详细信息,请参阅这篇文章。
S3和CloudFront
请参阅这篇关于如何将 React 应用部署到亚马逊云服务 S3 和 CloudFront 的博客文章:博客文章。
Surge
如果您尚未安装,可以通过运行 npm install -g surge
安装 Surge CLI。运行 surge
命令并登录或创建一个新账户。
当询问项目路径时,请确保指定 build
文件夹,例如
project path: /path/to/project/build
请注意,为了支持使用 HTML5 pushState
API 的路由器,您可能需要在部署到 Surge 之前,将构建文件夹中的 index.html
重命名为 200.html
。这样可以确保每个 URL 都回退到该文件。确保每个 URL 都回退到该文件。
高级配置
您可以通过在您的 shell 中设置环境变量或通过 .env 文件来调整各种开发和生产设置。
变量 | 开发 | 生产 | 用法 |
---|---|---|---|
BROWSER | :white_check_mark | :x | 默认情况下,Create React App 将使用默认系统浏览器打开,在 macOS 上优先使用 Chrome。指定一个 浏览器 来覆盖此行为,或将它设置为 none 以完全禁用它。如果您需要自定义浏览器启动的方式,可以指定一个 node 脚本。传递给 npm start 的任何参数也将传递给此脚本,而您的应用服务到的 URL 将是最后一个参数。您的脚本文件名必须具有 .js 扩展名。 |
HOST | :white_check_mark | :x | 默认情况下,开发 web 服务器绑定到 localhost 。您可以使用此变量指定不同的主机。 |
PORT | :white_check_mark | :x | 默认情况下,开发 web 服务器将尝试监听端口 3000 或提示您尝试下一个可用的端口。您可以使用此变量指定不同的端口。 |
HTTPS | :white_check_mark | :x | 当设置为 true 时,Create React App 将以 https 模式运行开发服务器。 |
PUBLIC_URL | :x | :white_check_mark | Create React App 假设您的应用托管在服务 web 服务器的根目录或 package.json 中的子路径(homepage )指定的路径。通常,Create React App 会忽略主机名。您可以使用此变量强制资源直接引用您提供的 URL(包括主机名)。当使用 CDN 托管您的应用时,这可能特别有用。 |
CI | :large_orange_diamond | :white_check_mark | 当设置为 true 时,Create React App 将构建中的警告视为失败。它还将测试运行器设置为非监视模式。大多数 CI 默认设置此标志。 |
REACT_EDITOR | :white_check_mark: | :x: | 当应用在开发中崩溃时,您将看到一个带有可点击堆栈跟踪的错误覆盖层。当您点击它时,Create React App 将尝试根据当前运行的进程确定您正在使用的编辑器,并打开相关的源文件。您可以 发送一个 pull 请求以检测您首选的编辑器。设置此环境变量将覆盖自动检测。如果您这样做,请确保您的系统的 [PATH](https://en.wikipedia.org/wiki/PATH) 环境变量指向您的编辑器 bin 文件夹。您也可以将其设置为 none 以完全禁用它。 | ||
CHOKIDAR_USEPOLLING | :white_check_mark | :x | 当设置为 true 时,监视器将在轮询模式下运行,在 VM 内部是必需的。如果 npm start 没有检测到更改,请使用此选项。 |
GENERATE_SOURCEMAP | :x | :white_check_mark | 当设置为 false 时,对于生产构建不生成源映射。这解决了某些较小机器上的 OOM 问题。 |
NODE_PATH | :white_check_mark | :white_check_mark | 与 Node.js 中的 NODE_PATH 相同,但只允许相对路径。设置 NODE_PATH=src 可以方便地模拟 monorepo 设置。 |
故障排除
npm start
没有检测到更改
当您在 npm start
运行时保存文件,浏览器应该使用更新后的代码刷新。
如果出现这种情况,请尝试以下解决方案之一
- 如果您的项目位于 Dropbox 文件夹中,请尝试将其移动出来。
- 如果监视器看不到名为
index.js
的文件,而您通过文件夹名称引用它,由于 Webpack 的一个错误,您需要重新启动监视器。[请参见此处](https://github.com/facebookincubator/create-react-app/issues/1164)。 - 一些编辑器(如 Vim 和 IntelliJ)具有“安全写入”功能,该功能目前会破坏监视器。您需要禁用它。请按照“调整您的文本编辑器”中的说明操作。
- 如果您的项目路径包含括号,请尝试将项目移动到没有括号的路径。这是由Webpack 监视器错误引起的。
- 在 Linux 和 macOS 上,您可能需要调整系统设置以允许更多监视器。
- 如果项目在虚拟机(如 Vagrant 配置的 VirtualBox)中运行,请创建一个
.env
文件在您的项目目录中(如果尚不存在),并添加CHOKIDAR_USEPOLLING=true
。这确保了下次您运行npm start
时,监视器使用轮询模式,这是在虚拟机中必需的。
如果上述所有解决方案都无法解决问题,请在此主题中留下评论。
npm test
在macOS Sierra上挂起
如果您运行 npm test
并且在打印 react-scripts test --env=jsdom
到控制台后控制台卡住,那么可能是您的Watchman 安装存在问题,如facebookincubator/create-react-app#713中所述。
我们建议删除项目中的 node_modules
并首先运行 npm install
(如果您使用的是 yarn
,则运行 yarn
)。如果不起作用,您可以尝试在这些问题中提到的众多解决方案之一。
据报道,安装 Watchman 4.7.0 或更高版本可以修复问题。如果您使用 Homebrew,可以运行以下命令来更新它
watchman shutdown-server
brew update
brew reinstall watchman
您可以在 Watchman 文档页面上找到其他安装方法。
如果这仍然不起作用,请尝试运行 launchctl unload -F ~/Library/LaunchAgents/com.github.facebook.watchman.plist
。
也有报道称卸载 Watchman 可以解决问题。因此,如果其他方法都无效,请从系统中删除它并再次尝试。
npm run build
提前退出
据报道,在内存有限且没有交换空间的机器上,例如在云环境中常见的机器上,npm run build
可能会失败。即使对于小型项目,此命令也可能使系统 RAM 使用量增加数百兆字节,因此如果您可用内存少于 1 GB,构建可能会失败并显示以下消息:
构建失败,因为进程退出得太早。这通常意味着系统耗尽了内存,或者有人对该进程调用了
kill -9
。
如果您完全确信您没有终止进程,请考虑在您正在构建的机器上添加一些交换空间,或者在本地上构建项目。
npm run build
在Heroku上失败
这可能是大小写敏感的文件名问题。请参阅本节。
Moment.js区域设置丢失
如果您使用Moment.js,您可能会注意到默认情况下只有英文区域设置可用。这是因为区域设置文件很大,您可能只需要Moment.js提供的所有区域设置的子集。
要添加特定的Moment.js区域设置到您的包中,您需要显式地导入它。
例如
import moment from 'moment';
import 'moment/locale/fr';
如果您以这种方式导入多个区域设置,您可以通过调用moment.locale()
并传递区域设置名称来稍后切换它们。
import moment from 'moment';
import 'moment/locale/fr';
import 'moment/locale/es';
// ...
moment.locale('fr');
这仅适用于先前已显式导入的区域设置。
npm run build
失败,无法压缩
一些第三方包在发布到npm之前没有将它们的代码编译为ES5。这通常会导致生态系统中出现问题,因为除了大多数现代版本之外,浏览器(以及一些当前的工具)不支持所有ES6功能。我们建议至少在未来几年内将代码作为ES5发布到npm。
为了解决这个问题
在依赖项的问题跟踪器上打开一个问题,并要求发布预编译的包。
- 注意:Create React App可以同时消耗CommonJS和ES模块。对于Node.js兼容性,建议主入口点为CommonJS。但是,它们可以可选地提供一个带有
package.json
中的module
字段的ES模块入口点。请注意,即使库提供了一个ES模块版本,如果它打算支持旧浏览器,它仍然需要将其他ES6功能预编译为ES5。
- 注意:Create React App可以同时消耗CommonJS和ES模块。对于Node.js兼容性,建议主入口点为CommonJS。但是,它们可以可选地提供一个带有
分叉该包并自行发布一个修正版本。
如果依赖项足够小,可以将其复制到您的
src/
文件夹,并将其视为应用程序代码。
将来,我们可能会开始自动编译不兼容的第三方模块,但目前这不被支持。这种方法也会减慢生产构建的速度。
退出替代方案
退出允许您自定义任何内容,但从那时起您必须自己维护配置和脚本。如果您有多个类似的项目,这可能令人望而生畏。在这种情况下,我们建议您而不是退出,而是分叉react-scripts
和您需要的任何其他包。这篇文章深入探讨了如何进行操作。您可以在这个问题中找到更多讨论。