创建 React + Flask 前后端分离项目

4,702 阅读2分钟

这是我参与更文挑战的第 6 天,活动详情查看: 更文挑战

该教程将指引创建一个简单的,但功能齐全的 React-Flask 项目。

前置依赖

请在继续教程之前,按照说明安装这三个包。

  • node.js:JavaScript 运行时间,将用于运行前端项目。
  • yarn:node.js 应用程序的包管理程序。
  • Python:运行 Flask 后端。

创建 React 项目

我们使用Create React App 生成器创建一个简单的项目。

$ npx create-react-app react-flask-app
$ cd react-flask-app

创建 Flask API 后端

我们希望将前端和后端组合成一个项目,故进入项目目录,添加一个 api 目录,Flask 项目将在那里实现。

$ cd react-flask-app
$ mkdir api
$ cd api

为了不依赖和影响全局包,我们创建一个名为 _venv _的虚拟环境,并在该环境中运行 python。

$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ _

对于这个简单的例子,我只需要两个 Python 包,Flask 和 python-dotenv。

(venv) $ pip install flask python-dotenv

本着保持简单的精神,我们将创建一个小的、单一的文件和单个端点应用程序。在 api 目录下,创建一个单一的文件 app.py:

# api/app.py
import time
from flask import Flask

app = Flask(__name__)

@app.route('/time')
def get_current_time():
    return {'time': time.time()}

这个 API 会以 JSON 的形式响应对应的 URL,当访问 /time 时,它可能返回以下内容。

{"time":1624328277.5134633}

发现我们没有看到 Flask 对函数的调用,原因时在最近版本的 Flask 中,视图功能可以返回字典,该字典会自动由 Flask 进行 JSON 化。

Flask 从环境变量指示的位置导入应用程序。如果 python-dotenv 已安装,那么运行 flask 会根据 .env.flaskenv 中配置来设置环境变量。这样可以在每次打开终端后,避免手动设置 FLASK_APP 和其他类似使用环境变量进行配置的服务部署工作。这里我们新建 .flaskenv 文件,并写入环境变量。

# api/.flaskenv
FLASK_APP=app.py
FLASK_ENV=development

现在可以启动 Flask 应用了。

(venv) $ flask run
 * Serving Flask app 'app.py' (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 541-013-389

访问 http://127.0.0.1:5000/time 会看到我们的 API 已经生效了。 现在,项目的 Flask 部分已完成,让我们离开 _api _子目录,回到根目录。

(venv) $ cd ..

React 配置更改

package.json 文件中需要进行一些更改,以改善 React 和 Flask 之间的集成。

设置代理

第一个更改是设置从 React 到 Flask 的代理重定向。React 项目在端口 3000 上运行 Web 服务器,而 Flask 在端口 5000 上运行自己的服务器。但是,在大多数部署中,前端文件和 API 端点都来自同一域和端口,以此来避免跨域问题,使一切无缝工作。可配置 React 项目,将其在其端口 3000 上收到的任何请求重定向到其他服务器。为此我们修改 package.json 文件,加入下面一行。

// package.json
{
  ... 其他内容 ...
  "proxy": "http://localhost:5000"
}

集合前后端启动命令

为了方便起见,用 yarn 管理 flask 的启动,在 scripts 中添加以下一行命令。

// package.json
{
  ... 其他内容 ...
 "scripts": {
    "start": "react-scripts start",
    "start-api": "cd api && venv/bin/flask run --no-debugger",
    ... 其他内容 ...
  }  
}

运行联合项目

现在让我们运行应用程序。需要使用两个终端窗口,一个用于前端服务器,另一个用于后端服务器。 在第一个终端上,启动前端:

$ yarn start

这将需要几秒钟,然后浏览器窗口将打开,从 http://localhost:3000_ 加载 React 示例应用程序。 切换到第二个终端,并在 http://localhost:5000 _启动 Flask 后端:

$ yarn start-api

现在前端和后端都在运行,前端将将其不识别的任何请求重定向到后端。两者都在监视其源代码文件,并在更改后重新启动。

从 React 调用 Flask API

现在我们让 Flask 侧定义的 API 在 React 项目中显示,更改 src/app.js 文件。

// src/app.js
import React, { useState, useEffect } from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  const [currentTime, setCurrentTime] = useState(0);

  useEffect(async () => {
    const response = await fetch('/time');
    if (!response.ok) {
      throw new Error(response.status);
    }
    const res = response.json();
    res.then(data => setCurrentTime(data.time));
  }, []);

  return (
    <div className="App">
      <header className="App-header">
         {/* ... 其他内容 ... */}
        <p>Current Time: {currentTime}</p>
      </header>
    </div>
  );
}

export default App;

现在打开浏览器,就可以发现当前 Unix 时间已经显示成功了。 image.png

结论

现在我们知道如何创建一个将 React 和 Flask 相结合的项目了。