2017-05-26 18 views
12

我有一個使用create-react-app樣板創建的React單頁應用程序訪問的API路徑的瓶頸。當使用create-react-app內置的開發服務器時,我的Flask後端工作正常,沒有問題。使用Flask提供create-react-app

現在,我想爲我的Flask服務器構建(使用npm run build)靜態反應應用程序。構建應用程序的反應導致了以下的目錄結構:

- 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] 

通過[密碼]我的意思是在構建時所產生的隨機生成的字符串。

已經收到了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') 

這樣,靜態資產成功服務。但它不是一個非常優雅的解決方案。

另一方面,我可以將它與內置的燒瓶靜態工具結合起來。但我不明白如何配置這個。

我真的不知道如何處理這個問題,因爲它使我重新考慮使用create-react-app,因爲它迫使我以一種非常特別的不方便的方式構建我的靜態文件夾:我無法改變應用程序向服務器請求靜態內容的方式。

總體而言:我的解決方案足夠強大嗎?有沒有辦法使用內置的瓶子功能來提供這些資源?有沒有更好的方式來使用create-react-app?任何輸入讚賞。如果需要,我可以提供更多信息。

感謝您的閱讀!

+3

燒瓶應該知道你的靜態文件夾,而不必做任何事情(只要該文件夾命名爲靜態並且位於燒瓶入口點旁邊)......即'cp -rf/build/static。/ static' as你的構建腳本的一部分... –

+1

你也可以使用nginx來爲你的靜態文件提供服務,這通常是推薦使用的(nginx對於靜態文件來說是超級好的) – patrick

回答

9
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 == ""): 
     return send_from_directory('react_app/build', 'index.html') 
    else: 
     if(os.path.exists("react_app/build/" + path)): 
      return send_from_directory('react_app/build', path) 
     else: 
      return send_from_directory('react_app/build', 'index.html') 


if __name__ == '__main__': 
    app.run(use_reloader=True, port=5000, threaded=True) 

那就是我最終的結果。因此bascially捕獲所有路由,測試路徑是否爲文件=>發送文件=>否則發送index.html。這樣你就可以從你想要的任何路線上重新加載反應應用程序,並且不會中斷。

+0

這是有效的。謝謝Jodo。 –

+0

我得到這個解決方案的MIME類型錯誤:-( '該腳本具有不受支持的MIME類型('文本/ HTML')/service-worker.js 無法加載資源:net :: ERR_INSECURE_RESPONSE registerServiceWorker。 js:71 服務工作者註冊期間出錯:DOMException:註冊ServiceWorker失敗:腳本具有不受支持的MIME類型('text/html')。' – user3216673