部署
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
上面显示的最后一个命令将在端口 3000 上为你的静态站点提供服务。 与 serve 的许多内部设置一样,可以使用 -l
或 --listen
标志调整端口:
serve -s build -l 4000
运行此命令以获取可用选项的完整列表:
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.js。
带有静态资产的 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
但没有找到。 服务器需要配置为通过服务 index.html
来响应对 /todos/42
的请求。 例如,我们可以修改上面的 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'));
});
如果你使用的是 HTTP 服务器,则需要在 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
的请求将在开发和生产中得到正确处理。
在生产版本中,当你拥有 opted-in 时,服务工作线程 将通过提供 index.html
的缓存副本来自动处理所有导航请求,例如 /todos/42
。 这个service worker导航路由可以通过eject
ing配置或者禁用,然后修改SWPrecachePlugin
配置的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
属性来 root <Link>
。
更多信息 here。
例如:
<BrowserRouter basename="/calendar"/>
<Link to="/today"/> // renders <a href="/calendar/today">
从不同的路径提供相同的构建
注意:
react-scripts@0.9.0
及更高版本提供此功能。
如果你不使用 HTML5 pushState
history API 或根本不使用客户端路由,则无需指定将从中提供你的应用程序的 URL。 相反,你可以将其放入你的 package.json
:
"homepage": ".",
这将确保所有资产路径都与 index.html
相关。 然后,你将能够将你的应用程序从 http://mywebsite.com
移动到 http://mywebsite.com/relativepath
甚至 http://mywebsite.com/relative/path
,而无需重新构建它。
为任意构建环境自定义环境变量
你可以通过创建自定义 .env
文件并使用 env-cmd 加载它来创建任意构建环境。
例如,要为暂存环境创建构建环境:
- 创建一个名为
.env.staging
的文件 - 像设置任何其他
.env
文件(例如REACT_APP_API_URL=http://api-staging.example.com
)一样设置环境变量 - 安装 env-cmd
$ npm install env-cmd --save
$ # or
$ yarn add env-cmd - 将新脚本添加到你的
package.json
,使用你的新环境进行构建:{
"scripts": {
"build:staging": "env-cmd -f .env.staging npm run build"
}
}
现在你可以运行 npm run build:staging
以使用暂存环境配置进行构建。
你可以以相同的方式指定其他环境。
.env.production
中的变量将用作回退,因为 NODE_ENV
将始终设置为 production
以进行构建。
AWS 放大
AWS Amplify 控制台为具有无服务器后端的现代 Web 应用程序(单页应用程序和静态站点生成器)提供持续部署和托管。 Amplify 控制台提供全球可用的 CDN、自定义域设置、功能分支部署和密码保护。
- 登录到 Amplify 控制台 here。
- 连接你的 Create React App 存储库并选择一个分支。 如果你正在寻找 Create React App+Amplify 启动器,请尝试演示使用 Create React App 在 10 分钟内设置身份验证的 create-react-app-auth-amplify 启动器。
- Amplify 控制台会自动检测构建设置。 选择下一步。
- 选择保存并部署。
如果构建成功,应用程序将部署并托管在具有 amplifyapp.com 域的全球 CDN 上。 你现在可以持续将更改部署到你的前端或后端。 持续部署允许开发人员在每次代码提交到他们的 Git 存储库时将更新部署到他们的前端和后端。
Azure
Azure 静态 Web 应用程序为由 GitHub Actions 提供支持的 React 应用程序创建一个自动构建和部署管道。 默认情况下,应用程序是地理分布的,具有多个存在点。 PR 是为暂存环境预览自动构建的。
- 创建一个新的静态 Web 应用程序 here。
- 添加详细信息并连接到你的 GitHub 存储库。
- 确保在 "build" 选项卡上正确设置构建文件夹并创建资源。
Azure 静态 Web 应用程序将自动在你的存储库中配置 GitHub 操作并开始部署。
有关路由、API、身份验证和授权、自定义域等的更多信息,请参阅 Azure 静态 Web 应用文档。
Firebase
如果你还没有通过运行 npm install -g firebase-tools
安装 Firebase CLI。 注册 Firebase 账户 并创建一个新项目。 运行 firebase login
并使用你之前创建的 Firebase 账户登录。
然后从项目的根目录运行 firebase init
命令。 你需要选择 Hosting: Configure and deploy Firebase Hosting sites 并选择你在上一步中创建的 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 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 你需要为 firebase.json
文件中的 service-worker.js
文件设置正确的 HTTP 缓存标头,否则你将无法在首次部署 (issue #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 托管。
GitHub 页面
注意:
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",
或自定义域页面:
"homepage": "https://mywebsite.com",
Create React App 使用 homepage
字段来确定构建的 HTML 文件中的根 URL。
第二步:安装 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 用户页面而不是项目页面,你需要进行一项额外的修改:
- 调整你的
package.json
脚本以将部署推送到 main:
"scripts": {
"predeploy": "npm run build",
- "deploy": "gh-pages -d build",
+ "deploy": "gh-pages -b main -d build",
第 3 步:通过运行 npm run deploy
部署站点
然后运行:
npm run deploy
第 4 步:对于项目页面,确保项目的设置使用 gh-pages
最后,确保 GitHub 项目设置中的 GitHub Pages 选项设置为使用 gh-pages
分支:

第 5 步:(可选)配置域
你可以通过将 CNAME
文件添加到 public/
文件夹来使用 GitHub Pages 配置自定义域。
你的 CNAME 文件应如下所示:
mywebsite.com
客户端路由注意事项
GitHub Pages 不支持在后台使用 HTML5 pushState
历史记录 API 的路由(例如,使用 browserHistory
的 React Router)。 这是因为当像 http://user.github.io/todomvc/todos/42
这样的 url 有新的页面加载时,其中 /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 处理 404,方法是使用自定义重定向参数重定向到你的
index.html
页面。 在部署项目之前,你需要将带有重定向代码的404.html
文件添加到build
文件夹,并且你需要将处理重定向参数的代码添加到index.html
。 你可以找到此技术的详细说明 in this guide。
故障排除
"/dev/tty: No such a device or address"
如果在部署时出现 /dev/tty: No such a device or address
或类似错误,请尝试以下操作:
- 创建一个新的 个人访问令牌
git remote set-url origin https://<user>:<token>@github.com/<user>/<repo>
。- 再试试
npm run deploy
"Cannot read property 'email' of null"
如果在部署时获得 Cannot read property 'email' of null
,请尝试以下操作:
git config --global user.name '<your_name>'
git config --global user.email '<your_email>'
- 再试试
npm run deploy
Heroku
使用 用于创建 React 应用程序的 Heroku Buildpack。
你可以在 零配置部署 React 中找到说明。
解决 Heroku 部署错误
有时 npm run build
在本地工作,但在通过 Heroku 部署期间失败。 以下是最常见的情况。
"Module not found: Error: Cannot resolve 'file' or 'directory'"
如果你得到这样的东西:
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
语句。
"Could not find a required file."
如果你从包中排除或忽略必要的文件,你将看到类似以下的错误:
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
作为部署路径。
设置持续交付:
使用此设置,当你推送到 git 或打开拉取请求时,Netlify 将构建和部署:
- 开始一个新的 netlify 项目
- 选择你的 Git 托管服务并选择你的存储库
- 点击
Build your site
支持客户端路由:
要支持 pushState
,请确保创建具有以下重写规则的 public/_redirects
文件:
/* /index.html 200
当你构建项目时,Create React App 会将 public
文件夹内容放入构建输出中。
Vercel
Vercel 是一个云平台,使开发人员能够托管 Jamstack 网站和 Web 服务,这些网站和 Web 服务可即时部署、自动扩展且无需监督,所有这些均采用零配置。 它们提供全球边缘网络、SSL 加密、资产压缩、缓存失效等。
第 1 步:将 React 项目部署到 Vercel
要使用 用于 Git 集成的 Vercel 部署 React 项目,请确保它已被推送到 Git 存储库。
使用 导入流程 将项目导入 Vercel。 在导入过程中,你会发现所有相关的 options 都已为你预先配置,并且可以根据需要进行更改。
导入项目后,所有后续的分支推送都会生成 预览部署,对 生产分支(通常为 "master" 或 "main")所做的所有更改都会生成 生产部署。
部署后,你将获得一个 URL 以实时查看你的应用程序,例如: https://create-react-app-example.vercel.app/ .
第 2 步(可选):使用自定义域
如果你想在 Vercel 部署中使用自定义域,你可以通过 Vercel 账户域设置。 添加或转移你的域
要将你的域添加到你的项目,请从 Vercel 仪表板导航到你的 项目。 选择项目后,单击 "设置" 选项卡,然后选择 Domains 菜单项。 在你的项目 Domain 页面中,输入你希望添加到项目中的域。
添加域后,你将看到不同的配置方法。
部署一个新的 React 项目
你可以部署一个新的 React 项目,为你设置一个 Git 存储库,使用以下部署按钮:
Vercel 参考资料:
渲染
Render 提供免费的 static site 托管,具有完全托管的 SSL、全球 CDN 和来自 GitHub 的持续自动部署。
按照 创建 React App 部署指南 在几分钟内部署你的应用程序。
使用邀请码 cra
注册或使用 this link。
S3 和 CloudFront
请参阅此 blog post,了解如何将 React 应用程序部署到 Amazon Web Services S3 和 CloudFront。 如果你希望添加自定义域、HTTPS 和持续部署,请参阅此 blog post。
Surge
如果你还没有通过运行 npm install -g surge
安装 Surge CLI。 运行 surge
命令并登录你或创建一个新账户。
当询问项目路径时,确保指定 build
文件夹,例如:
project path: /path/to/project/build
请注意,为了支持使用 HTML5 pushState
API 的路由,你可能需要在部署到 Surge 之前将构建文件夹中的 index.html
重命名为 200.html
。 这个确保每个 URL 回退到该文件。
发布组件到 npm
Create React App 不提供任何将组件发布到 npm 的内置功能。 如果你准备好从你的项目中提取一个组件以便其他人可以使用它,我们建议你将它移动到你项目之外的一个单独的目录,然后使用像 nwb 这样的工具来准备发布。