All we need is an easy explanation of the problem, so here it is.
I have created angular 4 app and I can run it using ng serve --open
and it runs on localhost:4200
,
what I want is I have also created api using nodejs
in same angular project now I want to run that API at localhost:4200/api
so I have tried something like this
my angular 4 and nodejs srtucture look like this
/dist
/server
/routes
/server
/src
app.js
package.json
in app.js I used
app.use(express.static(path.join(__dirname, 'dist')));
app.use('/app/api', apiRoutes);
const port = process.env.PORT || '3000';
server.listen(port, () => console.log(`API running on localhost:${port}`));
Once I run using nodemon app.js
and go at localhost:3000
it run my angular app and it’s fine and than I go at localhost:3000/app/api
it’s also work fine and good ,
But when I change in angular app it’s not auto refresh my app because it’s running node app currently for refresh it I need to run ng build
and than it will effect my new changes on angular app
So, What I want is to run ng serve --open
it will run angular app but not node js api so want to run both and once i change in any from angular app or node js app it must be auto refresh.
How to solve :
I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.
Method 1
You can’t have two different applications running on the same port. Angular-cli uses a nodejs server (technically it’s webpack-dev-server) behind the scenes when you run ng serve
, which means that port is already in use.
There are two possible solutions.
-
Use your node application to serve the static frontend files. Then you can’t really use
ng serve
(this is probably what you’d do when running live). -
Use nodejs with a different port, and use Angular’s proxy config, to have Angular think the api port is actually 4200 (this is probably best during development).
This is primarily a concern during development I reckon, since you most likely wont (and shouldn’t) be using ng serve
live, so option 2 would be my best recommendation.
To configure a proxy, you create a file in your angular application root directory called proxy.config.json
with the following content:
{
"/api/*": {
"target": "http://localhost:3000",
"secure": false,
"changeOrigin": true
}
}
Then when you run ng serve
, you run it with ng serve --proxy-config proxy.config.json
instead.
Here’s a link to the documentation
Here’s an alternative when building for production (solution 1 above):
To build in production you use ng build --prod
to create a production ready Angular build and then (assuming you use Express on your node server), use something like app.use(express.static('dist/'))
as explained in the Express documentation. I’m not using node myself (I’m using .NET Core) so I’m afraid I can’t provide much more in terms of details.
Method 2
There is one awesome blog on medium by Daniel Kagan which explain all, here the link.
Hot deploy its explain about client hot deployment i added some more code to make client and server hot deployment.
This answer is purely for development hot reload
Step one.
Install concurrently and nodemon
npm i concurrently
npm i nodemon
You can install globally as well with -g flag
Step Two.
Open your servers package.json file,
and add following four line to it. Note i have my angular code inside client folder so i did cd client
"buildclient": "cd client && ng build",
"runclient": "cd client && npm start",
"devstart": "nodemon --inspect ./bin/www",
"dev": "npm run buildclient & concurrently --kill-others \"npm run runclient\" \"npm run devstart\""
If you don’t want inspect node app then remove --inspect
flag.
Step Three.
Go to your angular folder and create file proxy.conf.json add following line to file.
{
"/api/*": {
"target": "http://localhost:3000",
"secure": false,
"changeOrigin": true
}
}
Step Four.
Add following command inside angular’s package.json file
"start": "ng serve --proxy-config proxy.conf.json"
Step Five.
Make angular build output directory inside public folder of server. To do this go to angular.json change build outputPath to ../public
following is JSON snippet.
"options": {
"outputPath": "../public",
"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.css"
],
"scripts": []
},
Step Six.
Make sure your node express server app.js file read static files from public folder.
app.use(express.static(path.join(__dirname, 'public')));
Step Seven.
npm run dev
Done goto http://localhost:4200 you can see you app there 🙂 all call to /api will get to node express server.
Any changes to server or client will be hot deployed automatically.
NOTE I used Express application generator to create my server and Angular CLI to create angular application. If you did it some other way then some files might not be present
Method 3
1.first build you angular 6 app
run ng build –watch
2.from nodejs app
write this middle ware
app.use(express.static(path.join(__dirname, './client/dist/client')));
as the folder pointing to client/dist/client is build folder of angular 6 app.
then run nodemon –inspect app.js
make sure to have a hirearchy of folders like this
/myproject
/client
/dist
/client
/....
/index.html
/app.js
/.....
listen to the port you want to run from app.js
and run localhost:portno
hope this helps
Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0