I made 1 project that is divided into frontend
and backend
, the frontend part is made in angularjs 1.x and the backend part is made in nodejs express.
Currently the backend part I tested with simple html that is not incorporated with angular.
To run the frontend part I do it with gulp:
gulp.task('web-server', function () {
gulp.src('.')
.pipe(server({
livereload: false,
directoryListing: false,
open: true,
log: 'debug',
clientConsole: false,
port: 8080,
host: 'localhost',
middleware: function (connect, opt) {return [historyApiFallback()];}
}));
});
And for the backend part:
app.listen(3000);
In other words, the two projects listen to ports 8080 and 3000 respectively, my question is , how can I make the 2 projects run with a single command? I think they should both listen to the same port.
Note: the project is here: https://github.com/x-rw/decisionTree/tree/master/node_app
The structure of my project is:
I'm too confused by the structure, should there be two files package.json
and two folders node_modules
?
Well, the answer, as in almost all cases, is: it depends . Every application has a structure that is defined when we design the application architecture. For example, when the backend has no communication other than responding to clients, it is often encapsulated in an API. On the contrary, if sessions and any type of communication are maintained where a state is maintained , it is convenient to carry out a single application.
In your case, what you have to do is define the functionalities of each part. When using frameworks/libraries like angularjs , reactjs , vue.js and related, communication with the backend is based on AJAX requests, which do not maintain any kind of state. In these cases, we generally talk about consuming APIs and the system is separated into client types . For example, if the idea is to have desktop, web and mobile clients, it is convenient to separate them into particular applications where all the clients have specific functionalities and communicate with the API to carry out the operations they need.
Going to your specific case, if there will be no more clients, I see no problem in putting it all together. The first point is that you're using a
dev server
with Gulp: don't do this , it's not useful in production. As a second point, structure your application well .Application structure
An application with a standard structure, in general, is the following:
In this way you encapsulate the frontend part in a single directory and your bundler will operate on it, ignoring the rest of the directories that belong to the backend.
Bundle generation
In this step, the bundler of your choice will be used to generate the compiled JavaScript file. Note that this is only necessary if you use ES6+ as usual in React, otherwise you don't need a bundler like Gulp or Webpack.
The previous Gulp task will go through the entire directory
src/ui
and generate a bundle that is nothing more than all the code together and minified ready to use. Inindex.html
it you only have to refer to the bundle:Execution
An angularjs app is usually a SPA . That said, this type of application is characterized by having a single entry point in which the JavaScript code will be injected to have the client-side routes. What you need is to put a global route that is foreign to the backend routes:
It is important that the wildcard always comes after the backend routes , otherwise you will always get the HTML.
Deployment
In case you want to run your application indefinitely, you can create a daemon and run it. For this you can rely on PM2 . This utility allows you to create daemons and make them run indefinitely, you can stop or restart them as well as put them in listening mode, useful if you use git and update your application through
git pull
.The PM2 configuration file is a JSON like the following:
To create the daemon you just have to run:
You can see the available commands and configuration in the PM2 documentation .
The solution to your problem is very simple. Express has static resource serving middleware that you can use to put your application on the same server as your API.
For that, it is recommended that you first do one
build
that will depend a lot on how you created your project but that basically consists of concatenating and minifying your script files, styles and converting your templates to javascript code. You already use gulp and in your project there is a task that comes configured for that. You can runnpm run build
orgulp build
After you have all the files
html
,js
andcss
properly generated, create a folder on your server and copy them there with exactly the same structure with which they were generated.In your api startup code you write something like this
I used
app
as the name of the folder from which to serve the client application but the name of this can be anything.The other alternative that you can use is to configure a reverse proxy , serving both applications separately and forwarding all requests to the corresponding one, but this solution is too broad and complex, so I only recommend that you try it after you have achieved the first option. . This one could help you to test your application even in development mode without doing it
build
.As a side note, a node application can have many
package.json
. It all depends on its purpose since it is usually used to signal stand-alone modules or applications. Frameworks such aslerna
are used to maintain monorepos that use independent filespackage.json
(generally with their correspondingnode_modules
) to manage each independent module within the same project. It is important that you understand that the way to organize the structure of your project is independentthe way you serve it on the web. The latter is the one that will determine the number of servers and/or ports that you should use for a single purpose. Having many servers is not bad because it helps you scale your application. I think that in your case it is a human error because from the looks of it it seems that the client code was copied into the server as it was without doing abuild
.