部署
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
等网址,请阅读下一部分。
使用客户端路由服务于应用程序
如果你使用在底层使用 HTML5 pushState
history API 的路由(例如,React Router 使用 browserHistory
),许多静态文件服务器将失败。例如,如果你使用带有 /todos/42
路由的 React 路由器,开发服务器将正确响应 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 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 worker时,将通过提供 index.html
的缓存副本自动处理所有导航请求,例如 /todos/42
。 可以通过 eject
ing 然后修改SWPreachePlugin
配置 中的 navigateFallback
和 navigateFallbackWhitelist
选项来配置或禁用此service worker 导航路由。
当用户将你的应用安装到其设备的主屏幕时,默认配置将成为 /index.html
的快捷方式。 这可能不适用于希望从/提供应用程序的客户端路由器。 编辑 public/manifest.json
中的Web应用程序 manifest ,并更改 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
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 .env.staging npm run build" } }
现在,你可以运行 npm run build:staging
来使用演示环境配置进行构建。你可以以相同的方式指定其他环境。
.env.production
中的变量将用作后备,因为 NODE_ENV
将始终设置为 production
以进行构建。
Azure
请参阅 此博客文章,了解如何将 React 应用程序部署到 Microsoft Azure 上。
有关使用自动部署到 Azure App Service 的方法,请参阅 此博客文章 或 此 repo 。
Firebase
如果你还没有 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 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 缓存头,否则你将无法在首次部署后看到更改 (issue #2440) 。它应该添加到 "hosting"
key 中,如下所示:
{
"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 Hosting。
GitHub Pages
注意:此功能适用于
react-scripts@0.2.0
及更高版本。
homepage
添加到 package.json
第1步:将 以下步骤很重要!
如果你跳过它,你的应用将无法正确部署。
打开你的 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
中
第2步:安装 现在,无论何时运行 npm run build
,你都会看到一个备忘单,其中包含有关如何部署到 GitHub 页面的说明。
要在 https://myusername.github.io/my-app 上发布它,请运行:
npm install --save gh-pages
或者你可以使用 yarn
:
yarn add gh-pages
在 package.json
的 "scripts"
中添加以下内容:
"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",
npm run deploy
来部署站点
第3步:通过运行 然后运行:
npm run deploy
gh-pages
第4步:确保项目的设置使用 最后,确保 GitHub 项目设置中的 GitHub Pages 选项设置为使用 gh-pages
分支:
第5步:(可选)配置域名
你可以通过向 public/
文件夹添加 CNAME
文件来使用 GitHub 页面配置自定义域名。
你的 CNAME 文件应如下所示:
mywebsite.com
客户端路由的注意事项
GitHub Pages 不支持底层使用 HTML5 pushState
history API 的路由(例如,使用 browserHistory
的 React Router )。这是因为当像 http://user.github.io/todomvc/todos/42
这样的网址有新的页面加载时,其中 /todos/42
是前端路由,GitHub Pages 服务器返回 404,因为它不知道 /todos/42
。如果要将路由添加到 GitHub 页面上托管的项目中,可以使用以下几种解决方案:
- 你可以从使用 HTML5 history API 切换到使用哈希值进行路由。如果你使用 React Router,你可以切换到
hashHistory
以获得此效果,但 URL 会更长且更冗长(例如,http://user.github.io/todomvc/#/todos/42?_k=yknaj
) 。阅读有关 React Router 中不同历史实现的更多信息 。 - 或者,你可以在 GitHub Pages 使用一些小技巧,通过使用特殊的重定向参数重定向到你的
index.html
页面来处理 404 。在部署项目之前,你需要在构建文件夹中添加带有重定向代码的404.html
文件,并且需要将处理重定向参数的代码添加到index.html
。你可以在 本指南 中找到有关此技术的详细说明。
故障排除
"/dev/tty: No such a device or address"
如果在部署时,你得到 /dev/tty: No such a device or address
或类似的错误,请尝试以下操作:
- 创建一个新的 Personal Access 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 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"
在这种情况下,请确保文件中包含正确的lettercase,并且在本地 .gitignore
或 ~/.gitignore_global
中不会忽略该文件。
Netlify
要手动部署到 Netlify 的 CDN :
npm install netlify-cli -g
netlify deploy
选择 build
作为部署路径。
要设置持续部署:
通过此设置,当你推送 git 或打开 pull 请求时,Netlify 将构建和部署:
- 启动一个新的 netlify 项目
- 选择你的 Git 托管服务并选择你的仓库
- 单击
Build your site
支持客户端路由:
要支持 pushState
,请确保创建 public/_redirects
文件,使用以下内容重写规则:
/* /index.html 200
在构建项目时,Create React App 会将 public
文件夹内容放入构建输出中。
Now
Now 提供零配置单命令部署。 你可以使用 now
免费部署你的应用。
通过推荐的 desktop tool 或通过 Node
npm install -g now
安装now
命令行工具。通过运行
npm run build
来构建你的应用程序。通过运行
cd build
进入构建目录。在 build 目录中运行
now --name your-project-name
。 你会在输出中看到一个 now.sh URL ,如下所示:> Ready! https://your-project-name-tpspyhtdtk.now.sh (copied to clipboard)
在构建完成后将该 URL 粘贴到浏览器中,你将看到已部署的应用程序。
这篇文章 提供了详细信息。
S3 和 CloudFront
请参阅 这篇博客文章,了解如何将React 应用程序部署到 Amazon Web Services S3 和 CloudFront。
Surge
如果还没有安装 Surge ,请运行 npm install -g surge
来安装 Surge CLI。 运行 surge
命令并登录或创建一个新帐户。
当询问项目路径时,请确保指定 build
文件夹,例如:
project path: /path/to/project/build
请注意,为了支持使用 HTML5 pushState
API 的路由,你可能需要在部署到 Surge 之前将 build. 目录中的 index.html
重命名为 200.html
。 这可 确保每个 URL 都回退到该文件。
将组件发布到 npm
Create React App 不提供任何内置功能来将组件发布到 npm 。 如果你准备从项目中提取组件以便其他人可以使用它,我们建议将其移动到项目之外的单独目录中,然后使用像 nwb 这样的工具来发布。