Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将react应用程序的构建包含到Flask中的正确方法_Python_Python 3.x_Reactjs_Flask - Fatal编程技术网

Python 将react应用程序的构建包含到Flask中的正确方法

Python 将react应用程序的构建包含到Flask中的正确方法,python,python-3.x,reactjs,flask,Python,Python 3.x,Reactjs,Flask,我有一个网站开发完全使用烧瓶。它使用一个名为仪表板的蓝图,它承载一些视图以访问不同的可视化效果,即仪表板/ 我使用id、名称和它所属的组来存储仪表板,因此用户只能从他们所属的组访问可视化效果 (这是我解决这个问题的经验不足的方法,因此我也愿意接受更好的设计模式来实现这一点的建议。) 我的项目有点像这样 app ├── dashboards │   ├── __init__.py │   └── views.py ├── __init__.py ├── models │   ├── dashboa

我有一个网站开发完全使用烧瓶。它使用一个名为
仪表板
的蓝图,它承载一些视图以访问不同的可视化效果,即
仪表板/

我使用
id
名称和它所属的
组来存储仪表板,因此用户只能从他们所属的组访问可视化效果

(这是我解决这个问题的经验不足的方法,因此我也愿意接受更好的设计模式来实现这一点的建议。)

我的项目有点像这样

app
├── dashboards
│   ├── __init__.py
│   └── views.py
├── __init__.py
├── models
│   ├── dashboard.py
│   └── __init__.p
├── static
│   ├── css
│   │   ├── styles.css
│   └── js
│       └── scripts.js
└── templates
    ├── base.html
    └── dashboards
        ├── cat.html
        ├── clock.html
        ├── index.html
        ├── private.html
        └── public.html
仪表板蓝图的我的视图

# app/dashboards/views.py

from ..models.dashboard import Dashboard

@dashboards.route('/<string:name>')
def view_dashboard(name):
    # a dictionary with dashboards available to current_user
    dashboards = get_dashboards() 

    for dashboard in dashboards.values():
        for d in dashboard:
            if name == d.name:
                route = 'dashboards/{dashboard}.html'.format(dashboard = d.name)
                return render_template(route, dashboard=d)
    else:
        return render_template('404.html'), 404
# app/dashboards/__init__.py

from flask import Blueprint

dashboards = Blueprint('dashboards', __name__)

from . import views
bp = Blueprint(name='myblueprint', 
                    import_name=__name__,
                    static_folder='static/myblueprint',
                    template_folder='templates',
                    static_url_path='/static', # this is what myblueprint.static will point to
                    url_prefix='/myblueprint', 
                    subdomain=None,
                    url_defaults=None, 
                    root_path=None)
最后,我使用create_应用程序模式

# app/__init__.py

# some imports happening here

def create_app(config_name):
    app = Flask(__name__)

    from .dashboards import dashboards as dashboards_blueprint
    app.register_blueprint(dashboards_blueprint, url_prefix='/dashboards')

    return app
app
之上的一个级别,有一个
manage.py
调用
create\u app
方法,传递一些配置属性。我相信这是烧瓶中常见的图案。我也认为这与我的问题无关

特别是,如果使用create react app包部署react app,即使用
npm run build
,则输出是一个文件夹
/build
,其中包含运行该app所需的静态文件。例如,此文件夹具有以下结构

├── build
│   ├── asset-manifest.json
│   ├── favicon.ico
│   ├── index.html
│   ├── manifest.json
│   ├── service-worker.js
│   └── static
│       ├── css
│       │   ├── main.<some-hash-1>.css
│       │   └── main.<some-hash-1>.css.map
│       └── js
│           ├── main.<some-hash-2>.js
│           └── main.<some-hash-2>.js.map
other files here
├── 建造
│   ├── asset-manifest.json
│   ├── 图标文件
│   ├── index.html
│   ├── manifest.json
│   ├── service-worker.js
│   └── 静止的
│       ├── css
│       │   ├── main..css
│       │   └── main..css.map
│       └── js
│           ├── main..js
│           └── main..js.map
这里还有其他文件吗
现在,如果想使用Flask插入react应用程序,我现在要做的是将
/css
/js
中的
/build
文件移动到
/app
中的
/static
文件夹中,然后将
index.html
/build
重命名为“react dashboard.html”,并将其移动到
模板/仪表板

这是一种让基本应用程序正常工作的非常愚蠢的方法,但我不知道从
/build
将其他文件放在哪里,也不知道如何使用更好的设计模式

由此我可以调整蓝图定义,并将模板和静态文件夹移动到
app/dashboards
,但我仍然不知道其他文件(如
service worker.js
)和清单等)的位置


在Flask应用程序上“装载”部署的react应用程序的正确方法是什么?我知道从
/build
重新组织文件是不可取的。

我通过调整蓝图解决了这个问题

# app/dashboards/views.py

from ..models.dashboard import Dashboard

@dashboards.route('/<string:name>')
def view_dashboard(name):
    # a dictionary with dashboards available to current_user
    dashboards = get_dashboards() 

    for dashboard in dashboards.values():
        for d in dashboard:
            if name == d.name:
                route = 'dashboards/{dashboard}.html'.format(dashboard = d.name)
                return render_template(route, dashboard=d)
    else:
        return render_template('404.html'), 404
# app/dashboards/__init__.py

from flask import Blueprint

dashboards = Blueprint('dashboards', __name__)

from . import views
bp = Blueprint(name='myblueprint', 
                    import_name=__name__,
                    static_folder='static/myblueprint',
                    template_folder='templates',
                    static_url_path='/static', # this is what myblueprint.static will point to
                    url_prefix='/myblueprint', 
                    subdomain=None,
                    url_defaults=None, 
                    root_path=None)
这样,蓝图中的静态路径将指向
/myblueprint/static
,我需要修改
创建react app
构建文件夹

  • /build
    中每个*.css、*.js和.html中对
    static
    的调用替换为
    /myblueprint/static
  • 重新排列
    /build
    中的文件夹,以匹配我的blueprint
    静态文件夹。
    
    • /build/static
      移动到
      /blueprint/static
    • 在调用这些文件的
      /blueprint/templates/index.html
      中设置我自己的jinja模板。确保此文件指向
      /myblueprint/static
      中的静态资产,而不是
      /build/static
我已经创建了一个
gulpfile
,它将自动化这个过程

var gulp = require('gulp');
var replace = require('gulp-replace');
var rename = require('gulp-rename');

// script to deploy react build into flask blueprint directory
// it replaces values and folder names

// README
// how to use this:
// in the react app, run npm run build
// copy the resulting /build folder in /myblueprint
// create a template of a template in /templates/base as index.default.html

// install gulp, gulp-replace, gulp-rename
// run gulp from /myblueprint


// replace routes inside css files

gulp.task('othertemplates', function(){
  gulp.src(['./build/static/css/main.*.css'])
    .pipe(replace('url(/static/media/', 'url(/myblueprint/static/media/'))
    .pipe(gulp.dest('static/myblueprint/css/'));
});

// replace routes inside js files

gulp.task('jsthingtemplates', function(){
  gulp.src(['./build/static/js/main.*.js'])
    .pipe(replace('static/media/', 'myblueprint/static/media/'))
    .pipe(gulp.dest('static/myblueprint/js/'));
});

// move other files

gulp.task('mediastuff', function(){
  gulp.src(['./build/static/media/*'])
    .pipe(gulp.dest('static/myblueprint/media/'));

  gulp.src(['./build/asset-manifest.json'])
    .pipe(gulp.dest('static/myblueprint/'));
});

// replace hashes in assets in the jinja template

gulp.task('jinjareplace', function(){

  var fs = require('fs');
  var assets = JSON.parse(fs.readFileSync('./build/asset-manifest.json'));

  // extract hashes

  let jsHashNew = assets['main.js'].match('[a-z0-9]{8}')
  let cssHashNew = assets['main.css'].match('[a-z0-9]{8}')

  gulp.src(['./templates/myblueprint/base/index.default.html'])
    .pipe(replace('css/main.cssHash.css', `css/main.${cssHashNew}.css`))
    .pipe(replace('js/main.jsHash.js', `js/main.${jsHashNew}.js`))
    .pipe(rename('index.html'))
    .pipe(gulp.dest('templates/myblueprint/'));
});


gulp.task('default', ['othertemplates', 'jsthingtemplates', 'mediastuff', 'jinjareplace'])
有了它,您可以从与
gulpfile.js
相同的路径运行
gulp
,并且应该涵盖所有内容