create-react-app 线上生成环境部署

🌙
手机阅读
本文目录结构
axihe

部署

npm run build 创建一个 build 目录,用于存放应用程序的生成版本。

使用 HTTP 服务器,以便为你的站点的访问者提供 index.html ,并且对 /static/js/main.<hash>.js 等静态路径的请求与 /static/js/main.<hash>.js 文件的内容一起提供。

有关更多信息,请参阅 npm run build 部分。

没有 HTML5 history 的项目部署

如果你就一个页面,没有使用 HTML5 pushState history API 的路由,这种的是部署就是部署一个文件

静态服务器

对于使用 Node 环境,最简单的方法是安装 serve 或者 http-server 并让它处理剩下的事情:

serve

npm install -g serve
serve -s build

上面显示的最后一个命令将为端口 5000 上的静态站点提供服务。与许多 serve 的内部设置一样,可以使用 -p--port 标志调整端口。

运行此命令以获取可用选项的完整列表:

serve -h

http-server

npm install http-server -g
http-server [path] [options]

serve 或者 http-server 都差不多的,都是本地起一个静态服务器。

Express

你不一定需要静态服务器才能在生产中运行 Create React App 项目。 它可以很好地集成到现有的动态服务器中。

这是使用 Node 和 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 完全与平台无关,因此无需显式使用 Node 。

具有静态资产的 build 文件夹是 Create React App 生成的唯一输出。

但是,如果使用客户端路由,这还不够。 如果你想在单页应用中支持 /todos/42 等网址,请阅读下一部分。

含有 HTML5 history 的项目部署(如React Router)

如果你使用在底层使用 HTML5 pushState history API 的路由,比如,你是基于 React Router 使用 browserHistory的项目;

如果是这种模式,上面的方法将会不能满足,这种项目需要所有的路径的请求都由index.html来处理。

默认的静态文件服务器的方式是,如果你使用带有 /todos/42 路由的 React 路由器,开发服务器将正确响应 localhost:3000/todos/42,当 /todos/42 有新的页面加载时,服务器会查找文件 build/todos/42 并且找不到它,这就会导致错误了。

解决核心:需要配置服务器以通过提供index.html 来响应对 /todos/42 的请求,如果是404的情况,这时候的处理也是前端路由处理

Express

例如,我们可以修改上面的 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

如果你使用的是 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。 可以通过 ejecting 然后修改 SWPreachePlugin 配置 中的 navigateFallbacknavigateFallbackWhitelist 选项来配置或禁用此 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 及更高版本。

第 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 。

第 2 步:安装 gh-pages 并将 deploy 添加到 package.json 的 scripts 中

现在,无论何时运行 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",
    
    

第 3 步:通过运行 npm run deploy 来部署站点

然后运行:

npm run deploy

第 4 步:确保项目的设置使用 gh-pages

最后,确保 GitHub 项目设置中的 GitHub Pages 选项设置为使用 gh-pages 分支:

gh-pages branch setting

第 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://:@github.com//.
  • 再次尝试 npm run deploy

“Cannot read property ‘email’ of null”

如果在部署时,你得到 Cannot read property 'email' of null,请尝试以下操作:

  • git config –global user.name ‘
  • git config –global user.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 这样的工具来发布。

axihe

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili 和抖音。

关注我: Github / 知乎

如果你加我的私人微信,麻烦写上您的 称呼,所在地区,职业,方便我备注,谢谢


本站的微信公众号

阿西河前端教程

Anbang

安邦的私人微信

微信号: yaolushan

Anbang

Bilibili(B站)

朱安邦

Anbang