2

I am trying to connect a flask server to a react app created with create-react-app, and using webpack to bundle it. I am largely following things I have learned working through this project and this accompanying video, except that I am using the default create-react-app as a starting point.

Here is my directory structure

-SimpleApp
--server
----server.py
----__init__.py
--static
----dist
------bundle.js
------styles.css
----node-modules
----src
----package.json
----package-lock.json
----webpack.config.js
----index.html
----__init__.py
--venv

basically my "static" folder is the default react-app, plus an index.html, a config file, and an empty init.py.

My server.py is simple, and in it I set my static_folder and template_folder

server.py

from flask import Flask, render_template, jsonify

app = Flask(__name__, static_folder='..static/dist', template_folder='../static')

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

if __name__ == '__main__':
    app.run()

it calls my index.html which looks like

index.html

<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
    <link rel="stylesheet" href="dist/styles.css">
    <title>simple app</title>
   </head>
 <body>
    <div id="root" />
    <div>Hello</div>
    <script src="dist/bundle.js" type="text/javascript"></script>
   </body>
</html>

my webpack.config.js is

webpack.config.js

const webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

const config = {
    entry:  __dirname + '/src/index.js',
    output: {
        path: path.join(__dirname + '/dist'),
        filename: 'bundle.js',
    },
    resolve: {
        extensions: [".js", ".jsx", ".css"]
    },
    module: {
        rules: [
            {
                test: /\.jsx?/,
                exclude: /node_modules/,
                use: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader',
                })
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin('styles.css'),
    ]
};

module.exports = config;

and

package.json

{
  "name": "simpleapp",
  "version": "1.0.0",
  "description": "Fullstack Template",
  "main": "index.js",
  "scripts": {
    "build": "webpack -p --progress --config webpack.config.js",
    "dev-build": "webpack --progress -d --config webpack.config.js",
    "test": "echo \"Error: no test specified\" && exit 1",
    "watch": "webpack --progress -d --config webpack.config.js --watch"
  },
  "babel": {
    "presets": [
      "es2015",
      "react"
    ]
  },
  "devDependencies": {
    "babel-core": "^6.25.0",
    "babel-loader": "^7.0.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "css-loader": "^0.28.4",
    "extract-text-webpack-plugin": "^2.1.2",
    "file-loader": "^0.11.2",
    "jquery": "^3.2.1",
    "react": "^15.6.1",
    "react-bootstrap": "^0.31.0",
    "react-dom": "^15.6.1",
    "style-loader": "^0.18.2",
    "webpack": "^3.12.0",
    "webpack-cli": "^3.2.1"
  }
}

I run npm run watch and python server.py and I get

"GET /dist/styles.css HTTP/1.1" 404 -
"GET /dist/bundle.js HTTP/1.1" 404 

It seems like this traces back to index.html. I don't think my config or package files have anything to do with it, but I am new to writing these and don't want to misunderstand.

The not-found files are in my app's static_folder, why would it not be able to find them?

I may be missing some fundamental concepts. If so please point me in the right direction

Thanks in advance!

1 Answer 1

2
app = Flask(__name__, static_folder='..static/dist', template_folder='../static')

The above is probably confusing things, and ..static is not the same as ../static

EDIT: Just had a look at the tutorial you linked. I'll leave the answer I wrote previousy below, but fixing the above typo to static_folder='../static/dist may be a quicker fix for your issue.


Personally, I'd simplify this by doing the following:

  • Note that your server.py sits in the server directory
  • Create 2 subdirectories in this server directory: templates and static
  • Move index.html to server/templates
  • Move all the static files, including the dist subdirectory to server/static

Now the directory structure should look more like:

SimpleApp
└── server
    ├── __init__.py
    ├── server.py
    ├── static
    │   └── dist
    │       ├── bundle.js
    │       └── styles.css
    └── templates
        └── index.html

Then just initialize the app with:

app = Flask(__name__)

No need to define the static & template directories here, as you've laid it out in the default structure which Flask expects.

Try to hit: http://localhost:5000/static/dist/bundle.js in the browser and confirm this loads correctly.

Then update the template to load these files from the correct location, using url_for in the template:

<link rel="stylesheet"
 href="{{ url_for('static', filename='dist/styles.css') }}"
>

and

<script type="text/javascript"
 src="{{ url_for('static', filename='dist/bundle.js') }}"
>

If you regenerate bundle.js at a later point, you may need to also tweak the webpack config to place it in the new location.

Sign up to request clarification or add additional context in comments.

6 Comments

Awesome thanks, that was exactly what I needed. I feel silly having had to ask a question about a simple typo, but I'm glad to have also gotten feedback on directory organization. It can be a surprisingly odd thing to figure out.
Yeah I found flask slightly tricky to get started with because there's so many different ways to arrange the code, and fundementals often get missed when following tutorials because everyone has a slightly different application layout.
I am going to jump back on this post because now I'm having an error with the same project. I did as you first suggested, changing static_folder="../static/dist", and it worked. I decided to rebuild the project formatted to your suggestion, when I ran "npm run watch" I get
npm ERR! [email protected] watch: webpack --progress -d --config webpack.config.js --watch npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the [email protected] watch script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.```
Never mind, I figured this one out. In my config file I need to change "path: path.join(__dirname + '/dist')," to just "path: __dirname + '/dist',". I don't know why the path.join function breaks one app but not the other, but at least it works.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.