部署
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 的许多内部设置一样,可以使用 -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。
build
文件夹下的静态 assets 是 Create React App 生成的唯一输出。
但是,这对于使用客户端路由来说还远远不够。阅读下一章节,以了解如何在你的单页面应用中支持像 /todos/42
之类的 URLs。
通过客户端路由提供服务
如果你使用基于 HTML5 pushState
history API 构建的路由(例如搭配 browserHistory
的 React Router),许多静态服务器都将报错。如果你混用 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'));
});
如果你使用的是 Apache 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
的请求在开发和生产环境中都会得到正确的处理。
在生产环境构建版本中,当你选择开启 PWA 时,service worker 将会自动处理所有导航请求,像 /todos/42
这种就会提供一个 index.html
的缓存拷贝。service worker 导航路由可以进行相关配置,或通过 eject
ing 禁用,然后修改 SWPrecachePlugin
配置项中的 navigateFallback
和 navigateFallbackWhitelist
。
当用户将你的应用安装至设备主屏幕时,默认配置将会提供一个 /index.html
快捷方式。对于希望通过 /
来提供应用的客户端路由来说可能会导致失效。在 public/manifest.json
上修改 web 应用清单,并修改 start_url
以匹配所需的 URL scheme,例如:
"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
history API 或根本没有使用客户端路由,则无需指定解析应用的 URL。作为代替,你可以将其放在 package.json
中:
"homepage": ".",
这将确保所有 asset 路径都是相对于 index.html
的。你可以在不重新构建将应用程序从 http://mywebsite.com
移动到 http://mywebsite.com/relativepath
,甚至是 http://mywebsite.com/relative/path
。
为任意构建环境定制环境变量
你可以通过创建自定义 .env
文件来创建一个定制构建环境,并使用 env-cmd 对其进行加载。
例如,要为 staging 环境创建构建环境:
- 创建一个名为
.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
以使用 staging 环境配置进行构建。
你可以用相同的方式指定其他环境。
.env.production
中的变量将用作后备选项,因为构建时 NODE_ENV
将始终被设定为 production
。
AWS Amplify
AWS Amplify 控制台通过 serverless backends 为现代 Web 应用(单页应用和静态网站生成器)提供持续性部署与托管。Amplify Console 提供了全球可用的 CDNS,自定义域名设置,功能分支部署以及密码保护。
- 从这里登入 Amplify 控制台
- 连接你的 Create React App 仓库并选择一个分支。如果你在寻找 Create React App + Amplify 的入门选择,请尝试create-react-app-auth-amplify 入门程序,它演示了如何在 10 分支内使用 Create React App 设置身份验证。
- Amplify Console 自动检测构建设置,点击下一步。
- 选择 保存并部署。
如果构建成功,该应用会被部署并托管至拥有 amplifyapp.com 域名的全局 CDN 上。现在,你可以将更改持续部署至你的前端或后端。持续部署允许开发人员在每次修改代码并提交至 Git 仓库时,将更新自动部署至前端与后端。
Azure
查阅这篇博文以了解如何将 React 应用部署至 Microsoft Azure。
查阅这篇博文或这个仓库,以了解自动部署至 Azure App Service 的方法。
Firebase
如果尚未安装 Firebase 命令行工具,请执行 npm install -g firebase-tools
。注册一个 Firebase 账户并创建一个新项目。运行 firebase login
并使用你先前创建的 Firebase 账户登入。
随后在项目的根目录下执行 firebase init
命令。你需要选择 Hosting: Configure and deploy Firebase Hosting sites,然后选择上一步创建的 Firebase 项目。你需要统一创建的 database.rules.json
,选择 build
作为公共目录,并选择 y
以同意 Configure as a single-page app。
=== 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!
重要提示:你需要在 firebase.json
文件中为 service-worker.js
设置正确的 HTTP 缓存报头,否则你无法在第一次以后的部署中看到更改(issue #2440)。应该如下所示将其添加到 host
中:
{
"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 Pages
注意:该功能仅支持
react-scripts@0.2.0
及以上版本。
步骤 1:将 homepage
添加到 package.json
以下步骤非常重要!
如果你跳过它,你的应用可能无法被正常部署。
打开你的 package.json
文件,并为你的项目添加 homepage
字段:
"homepage": "https://myusername.github.io/my-app",
或 Github user 页面:
"homepage": "https://myusername.github.io",
或自定义域名页面:
"homepage": "https://mywebsite.com",
Crete React App 使用 homepage
字段来确定被构建的 HTML 文件的根 URL。
步骤 2:安装 gh-pages
并将 deploy
与 scripts
添加至 package.json
中
现在,每当你执行 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 user 页面,而不是项目页面,则需要添加一个额外修改:
- 调整你的
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:配置域名(可选)
你可以通过将 CNAME
文件添加至 public/
文件夹中为 GitHub Pages 配置自定义域名。
你的 CNAME 文件应该如下所示:
mywebsite.com
有关客户端路由的说明
Github Pages 不支持使用基于 HTML5 pushState
history API 的路由(例如,使用 browserHistory
的 React Router)。这是因为当通过类似于 http://user.github.io/todomvc/todos/42
这样的 url 访问新页面时,/todo/42
是前端路由,Github Pages 服务器会返回 404,因为它完全不了解 /todos/42
的相关信息。如果要为托管在 GitHub Pages 上的项目添加路由的话,有以下两种解决方案:
你可以从调用 HTML5 history 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
中添加处理重定向参数的代码。你可以在这篇指南中找到有关此技巧的详细说明。
故障排除
"/dev/tty: No such a device or address"
如果在部署时看到 /dev/tty: No such a device or address
或与之类似的错误,请尝试以下操作:
- 创建一个新的个人访问 Token
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
使用为 Create React App 定制的 Heroku 构建工具
你可以在零配置部署 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”作为部署路径。
要配置持续部署:
按照以下步骤执行,以使 Netlify 在你推送到 git 或开启 pull request 时自动构建并部署:
- 开启一个新的 netlify 项目
- 选择你的 Git 托管服务,然后选择你的仓库
- 点击
Build your site
客户端路由支持:
为了支持 pushState
,请确保使用以下重写规则创建 public/_redirects
文件:
/* /index.html 200
在构建项目时,Create React App 将把 public
文件夹内容置入构建输出中。
ZEIT Now
ZEIT Now 是一个针对网站和 serverless APIs 的云平台,可用于将你的 Create React App 项目部署个人域名(或免费的 .now.sh
后缀 URL)。
该指南将像你展示快速入门的相关步骤:
步骤 1:安装 Now 命令行工具
要使用 npm 安装命令行工具,请执行以下命令:
npm i -g now
步骤 2:部署
你可以通过在项目目录的根路径下执行以下命令来部署应用程序:
now
或者,你也可以使用他们的 GitHub 或 GitLab 集成。
这样就可以了!
现在将会部署你的站点,同时你将会收到类似以下内容的链接:https://react.now-examples.now.sh
开箱即用,同时你已经自动配置了客户端路由兼容与适当的默认缓存头部。这种行为可以被这样覆盖。
Render
Render 提供免费静态站点托管,该托管具备 SSL,全局 CDM 以及来自 GitHub 的持续自动部署。
遵循 Create React App 开发指南,短时间内即可完成你的应用部署。
使用邀请码 cra
进行注册或使用该链接。
S3 和 CloudFront
有关如何将 React 应用部署至 Amazon Web Service S3 和 CloudFront 的相关信息,请查阅这篇博文。如果你要添加自定义域名、HTTPS 和持续部署,请参阅这篇博文。
Surge
如果尚未安装 Surge 命令行工具,请执行 npm install -g surge
。运行 surge
命令以登入或创建一个新账户。
当询问有关项目路径的信息时,请确保指定 build
文件夹,像这样:
project path: /path/to/project/build
请注意,为了兼容基于 HTML5 pushState
API 的路由,你可能需要在部署到 Surge 前将 build 文件夹中的 index.html
文件重命名为 200.html
。这样能确保每个 URL 都能回退到该文件。
将组件发布至 npm
Create React App 不提供任何将组件发布至 npm 的内置功能。如果你准备从项目中提取组件,以便其他人可以使用它,我们建议将其移动到项目外部的单个文件夹中,然后使用 nwb 这样的工具进行发布前准备。