Python 为使用create react app with Flask创建的前端提供服务

Python 为使用create react app with Flask创建的前端提供服务,python,reactjs,flask,create-react-app,Python,Reactjs,Flask,Create React App,我有一个带有API路由的Flask后端,由使用CreateReact应用程序创建的React单页应用程序访问。使用CreateReact应用程序开发服务器时,我的Flask后端工作正常 我想从我的Flask服务器上为构建的(使用npm run build)静态React应用程序提供服务。构建React应用程序将导致以下目录结构: - build - static - css - style.[crypto].css - style.[crypto].c

我有一个带有API路由的Flask后端,由使用CreateReact应用程序创建的React单页应用程序访问。使用CreateReact应用程序开发服务器时,我的Flask后端工作正常

我想从我的Flask服务器上为构建的(使用
npm run build
)静态React应用程序提供服务。构建React应用程序将导致以下目录结构:

- build
  - static
    - css
        - style.[crypto].css
        - style.[crypto].css.map
    - js
        - main.[crypto].js
        - main.[crypto].js.map
  - index.html
  - service-worker.js
  - [more meta files]
我所说的
[crypto]
,是指在构建时随机生成的字符串

收到
index.html
文件后,浏览器会发出以下请求:

- GET /static/css/main.[crypto].css
- GET /static/css/main.[crypto].css
- GET /service-worker.js
我应该如何提供这些文件?我想到了这个:

from flask import Blueprint, send_from_directory

static = Blueprint('static', __name__)

@static.route('/')
def serve_static_index():
    return send_from_directory('../client/build/', 'index.html')

@static.route('/static/<path:path>') # serve whatever the client requested in the static folder
def serve_static(path):
    return send_from_directory('../client/build/static/', path)

@static.route('/service-worker.js')
def serve_worker():
    return send_from_directory('../client/build/', 'service-worker.js')
从flask导入蓝图,从\u目录发送\u
静态=蓝图(“静态”,“名称”)
@static.route(“/”)
def SERVICE_static_index():
从_目录(“../client/build/”,“index.html”)返回发送_
@static.route('/static/')#为静态文件夹中客户端请求的任何内容提供服务
def SERVER_静态(路径):
从_目录(“../client/build/static/”,路径)返回发送_
@static.route('/service worker.js')
def SERVICE_worker():
从_目录(“../client/build/”,“service worker.js”)返回发送_
通过这种方式,可以成功地为静态资产提供服务

另一方面,我可以将其与内置的Flask静态实用程序结合起来。但我不明白如何配置这个

我的解决方案足够健壮吗?有没有办法使用内置的烧瓶功能来服务这些资产?是否有更好的方法使用create react应用程序?

导入操作系统
import os
from flask import Flask, send_from_directory

app = Flask(__name__, static_folder='react_app/build')

# Serve React App
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def serve(path):
    if path != "" and os.path.exists(app.static_folder + '/' + path):
        return send_from_directory(app.static_folder, path)
    else:
        return send_from_directory(app.static_folder, 'index.html')


if __name__ == '__main__':
    app.run(use_reloader=True, port=5000, threaded=True)
从flask导入flask,从\u目录发送\u app=Flask(\uuuuu name\uuuuuuuuu,static\u folder='react\u app/build') #服务反应应用程序 @app.route('/',默认值={'path':''}) @应用程序路径(“/”) def serve(路径): 如果路径!=“”和os.path.exists(app.static_folder+'/'+path): 从目录返回发送目录(app.static文件夹,路径) 其他: 从目录返回发送目录(app.static文件夹'index.html') 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': app.run(使用_reloader=True,port=5000,threaded=True)

这就是我的结局。因此,基本上捕获所有路由,测试路径是否为file=>sendfile=>else发送index.html。这样,您就可以从任意路线重新加载react应用程序,而且不会中断

首先执行
npm运行build
来构建您上面提到的静态生产文件

from flask import Flask, render_template

app = Flask(__name__, static_folder="build/static", template_folder="build")

@app.route("/")
def hello():
    return render_template('index.html')

print('Starting Flask!')

app.debug=True
app.run(host='0.0.0.0')


不幸的是,我认为开发热重新加载无法使其正常工作。

公认的答案对我不适用。我用过

导入操作系统
从flask导入flask,从\u目录发送\u,jsonify,呈现\u模板,请求
从server.landing导入landing作为landing\u bp
从server.api导入api作为api\u bp
app=Flask(\uuuuu name\uuuuu,static\u folder=“../client/build”)
应用程序注册蓝图(登陆地图,网址前缀=“/landing”)
应用程序注册蓝图(api\U bp,url\U前缀=“/api/v1”)
@附件路线(“/”)
def serve():
“”“服务反应应用程序”“”
从目录(app.static\u文件夹,“index.html”)返回send\u
@附件路线(“/”)
def静态_代理(路径):
“”“静态文件夹服务”“”
文件名=path.split(“/”[-1]
dir_name=os.path.join(app.static_文件夹“/”.join(path.split(“/”[:-1]))
从目录返回发送目录(目录名、文件名)
@app.errorhandler(404)
def手柄_404(e):
如果request.path.startswith(“/api/”):
返回jsonify(message=“Resource not found”),404
从目录(app.static\u文件夹,“index.html”)返回send\u
@app.errorhandler(405)
def手柄_405(e):
如果request.path.startswith(“/api/”):
返回jsonify(message=“method not allowed”),405
返回e
这里有一个有效的解决方案。 有没有想过为什么我们需要两个单独的文件夹来存放
静态
模板
。把混乱分开,对吗? 但是,这是生产构建的一个问题,因为它有一个文件夹用于存放
静态
模板
类型的文件,并且所有依赖项都是这样链接的

< > >代码>构建< /COD>文件夹,如果您认为两者都是“代码>静态< /代码>和<代码>模板< /代码> .< 用这样的东西

from flask import Flask, render_template

app = Flask(__name__, static_url_path='',
                  static_folder='build',
                  template_folder='build')

@app.route("/")
def hello():
    return render_template("index.html")


您的flask应用程序将正常运行。

我使用的flask服务器只有一个路由,它从Create react应用程序(CRA)的构建文件夹中读取index.html文件

以这种方式设置时,我遇到了一个错误,由于路径不匹配,静态文件无法正常提供服务,因此我使用的解决方案是

  • 在CRA的package.json中添加主页属性,并将其设置为“/static”
  • { “名称”:“应用程序名称”, “版本”:“, “依赖项”:{} “主页”:“/静态”,“其他键]}

  • 主页属性将在CRA的构建过程中使用,并用于index.html的%PUBLIC_URL%位置,并附加到其他静态资产URL路径中(您可以在构建过程后查看index.html代码进行验证)

  • 构建过程结束后,运行flask服务器,我们可以看到GET请求第一次随/一起出现,并且index.html将被提供,然后是对html文件中其他静态资产的/static/static/js/[[filename]]请求,并且一切正常


  • flask应该知道您的静态文件夹,而无需执行任何操作(只要文件夹名为static并且位于flask入口点旁边)。。。ie
    cp-rf/build/static/static
    作为构建脚本的一部分…您还可以使用nginx来提供静态文件,这通常是推荐的via(nginx非常适合静态文件)我在这个解决方案中遇到mime类型错误:-(
    脚本有不支持的mime类型('text/html'))./service-worker.js未能加载资源:net::ERR_unsecure_RESPONSE registerServiceWorker.js:71服务工作者注册期间出错:DomeException:未能注册服务工作者:脚本具有不受支持的MIME类型(“text/html”)。
    @user3216673
    from flask import Flask
    app = Flask(__name__)
    app.static_folder =  '../build'
    
    @app.route('/')
    def index():
        fref = open(r'../build/index.html')
        html_text = fref.read()
        fref.close()
        return html_text
    
    app.run()
    
     Add **homepage** key parallel to the **dependencies** key in the package.json file