'Angular-cli with any other server
I'm relatively new to Angular 2, and I'm trying to build an app using the angular-cli system. This works and I can ng-serve and the application comes up. However, it seems like a huge pain in the ass to try and serve the application with anything other than the ng-serve system. In particular I'm trying to serve the application built with angular-cli with a Python Flask app. The amount of hoops I'm seemingly having to jump through trying to get this to work is making me crazy! I want to do this because I want to serve a REST API with the Python/Flask app that will respond to the HTTP services requests from the Angular 2 application.
Here are the relevant versions I'm using:
node - 6.2.2
npm - 2.9.5
angular 2 - rc.4
angular-cli - 1.0.0-beta.9
python - 2.7.5
flask - 0.10.1
How can I serve an Angular app while using Flask?
Solution 1:[1]
I've actually sort of solved the problem. I have a directory named "smoke" (short for smoke and mirrors ), and inside there I ran the angular-cli command:
ng new static
This created the angular-cli start out application in the static directory. Then I created this (simplified) Python Flask application:
import os
from flask import Flask, send_from_directory, redirect
from flask.ext.restful import Api
from gevent import monkey, pywsgi
monkey.patch_all()
def create_app():
app = Flask("press_controller")
# map the root folder to index.html
@app.route("/")
def home():
return redirect("/index.html")
@app.route("/<path:path>")
def root(path):
"""
This is the cheesy way I figured out to serve the Angular2 app created
by the angular-cli system. It essentially serves everything from
static/dist (the distribution directory created by angular-cli)
"""
return send_from_directory(os.path.join(os.getcwd(), "static/dist"), path)
return app
if __name__ == "__main__":
app = create_app()
server = pywsgi.WSGIServer(("0.0.0.0", 5000), app)
server.serve_forever()
else:
app = create_app()
This way I can navigate to http://localhost:5000 and the application will serve up the Angular app just like "ng serve" does. Now I can add in my REST API endpoints as I wanted and have Angular services access them to populate the application.
Solution 2:[2]
There's no requirement that Flask serves the frontend application.
Really all Flask would be doing with an Angular app is serving static files, something that is better handled by a web server like Nginx in production, or the framework's tools like ng-serve in development.
Meanwhile, Flask would act as the backend api server that your frontend app communicates with. Use request.get_json()
and return jsonify(...)
to get and respond with JSON data.
Run the two separately, they work together over HTTP only. This also simplifies working with backend vs. frontend developers: all they need to know about is the api to communicate between the two. However, since the frontend is being served on a different port than the backend, you'll need to set up Flask appropriately to allow CORS requests, for example with Flask-CORS.
Solution 3:[3]
Old question but I came across it when setting up my new project. I'm using a a more recent version of angular cli (7.3.1) and Flask (1.0.2) but the setup is pretty similar to yours. I should note that this is by no means the cleanest setup, and I'm sure the same could be achieved with webpack only, but I felt this way was a bit easier to follow (I've found webpack config can be a nightmare). My directory structure is as follows (after building):
client // this is my angular project
src
angular.json
server // this is my flask server
templates
index.html // generated from ng build
static
vendor.js // generated from ng build
pollyfills.js
...
Makefile
In angular.json, you'll want to point the build path to your flask server:
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "../server/static",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": [],
"es5BrowserSupport": true
},
...
In my server, configure the static url:
app = Flask(__name__, static_url_path='')
And finally in the makefile, execute the build command, and copy the template file into the templates folder:
all:
cd client && ng build --prod;
mv server/static/index.html server/templates/ ;
.PHONY : all
Again, not the most elegant solution but pretty straight forward to get rolling with the angular cli (rather than getting the hands dirty with webpack).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | halfer |
Solution 2 | |
Solution 3 | spencer |