Modular structure for Express 4 backend in a MEAN app - node.js

I'm newbie developing MEAN apps, i'm coming from a Laravel structure to develop web applications, what i don't like about Laravel is that is not so modular, everything is separated, especially Models, Views, and Controllers, to navigate through the folders you have to scroll a lot of times when building large apps...
My question is all about Express under the MEAN stack, what i'm looking for is a structure where i create modules for every entity of an app, for example:
I have three modules: users, questions, and answers; each module will contain the routes, the model, and the controller for that specific module, for example:
├── node_modules
├── src
│ ├── client
│ │ └── ... //Frontend things managed by angular (like views, etc...)
│ └── server
│ ├── modules //By module i mean an entity
| | ├── users
| | | ├── users.model.js
| | | ├── users.controller.js
| | | ├── users.routes.js
| | | └── index.js
| | ├── questions
| | └── answers
| ├── config
| └── etc... //Suggestions please...
|
├── package.json
└── server.js
How could i set up that structure?, so far i've found this tutorial about modularizing an Express app, but i would like to extend it, so that i keep it DRY, and make use of the LIFT principle described by John Papa in his Angular Style Guide but under the backend.
Why am i asking this? Simple, i don't like to scroll through large folders to get open a file and then scroll again to open another file that are related, i want to work with a structure easy to maintain, easy to understand, etc...
If possible could someone explain an example of how to setup an application using this structure and upload it to github?

Place one node_modules at the top level.
Give each module a package.json
Now write a script in your bootstrap that finds all unique node_modules required from the package.json.
There, node_modules solved. Make sure it identifies the variances of versions too.
Build a universal run script file that reads a universal configuration file that points to all of the other modules.
Angular 2..4..5 whatever is a great modularized file structure to model after.

Related

Node.js protobuf includes

We are trying to implement a grpc service in Node.
We have a common.proto-file where we describe common messages, that we can reuse across different services.
Up until now, we have only implemented services in Go, and consumed them in either Go or PHP. This all works fine.
Now that we want to implement one service in Node, we have generated the pb.js-files, both from common.proto, and lets call it service.proto.
The problem is, that in service_pb.js it generates the following code: require("../common_pb.js")
This is of course not valid, as the path to common_pb.js is node_modules/#company/common-node/common_pb.js, while now it looks for it in node_modules/#company/common-node/common_pb.js.
I still have not been able to figure out how we can make this work correctly for Node, so if anyone has a solution that would be great.
Here is what we came up with as a solution:
The tree of the project looks like this:
root/
├─ common/
│ ├─ common.proto
├─ some-service/
│ ├─ some-service.proto
├─ other-service/
│ ├─ other-service.proto
If we in some-service.proto needed a message definition from common.proto we had import "common.proto"; and when running the project we included the common dir.
We changed this, so that we in the some-service.proto file wrote common/common.proto, and when running protoc just included . which is the root dir as shown in the tree above. That way the includes came out as require('../common/common_pb.js'); instead of require('../common_pb.js');.

Running NodeJS worker in Docker image

I have an application that looks like this one:
https://github.com/heroku-examples/node-workers-example
In short, I have 2 processes:
Server: it server US, handles requests and adds them to Redis
Worker: it pulls requests from Redis and works on them
Should I use only one Docker image for both processes or should I have 2 docker images (one for the server and the second for the worker)? What is the best practice?
I personally think, it's better to have 2 images. In this case, can my project structure be like this one:
Project Folder
-node_modules
-utils
-server.js
-package.json
-Dockerfile
-docker-compose.yml
-/worker
-/worker/index.js
-/worker/Dockerfile
Is there any advice?
Thanks a lot.
Disclaimer: this is very opinionated response, but author is asking for an opinion.
You can do one or two but it all depends on how you wanna schedule it.
If you want to stay flexible in the amount of processes you want for each I would go with two docker images otherwise you'll need to each time spin a fixed amount of each or you'll need to tweak that setting via env variables or via other means...
Hence one for the frontend part and one for the background process.
As you are having two different images, I usually prefer to separate that in two distincts projects but that's a matter of taste. Even though because of how NodeJS manages dependencies (node_modules) it's easier to have 2 distincts folders when the dependencies are very different.
I would go with following:
.
├── docker-compose.yml
├── front
│   ├── Dockerfile
│   ├── node_modules
│   ├── package.json
│   └── src
│   └── main.js
└── worker
├── Dockerfile
├── node_modules
├── package.json
└── src
└── main.js

Flask url_for 'static' in templates folder?

Maybe there's a better way to do this, but I'm trying to organize my Flask application so that both static Javascript and HTML templates sit in the same folder (similar to components)
This is just for organization purposes, I won't be rendering the statics in jinja2
So, instead of this :
├── templates/
│ ├── login.html
├── static/
│ ├── login.js
I'm looking for this (just an idea):
├── components/
│ ├── login/
│ │ ├── login.html
│ │ └── login.js
Or maybe this, so I can make a wrapper that renders a component just by its folder name, ex: return render_component('login')
├── components/
│ ├── login/
│ │ ├── template.html
│ │ └── login.js
The concept is that inside login.html template it adds a script tag with url_for to login.js
I'm also open to different ideas/ways to achieve this component structure
I'm sure there are other ways to achieve this but one way is to use blueprint structure and contain all static files for that specific blueprint inside the blueprint folder.
app
|- collections
| - blueprint_one
| - configs
| - static
| - css
| - js
| js_file_one.js
| - templates
| - blueprint_one
| html_file_one.html
| blue_print_one_view_file_one.py
| __init__.py
| - blueprint_two
| - blueprint_three
|- static
| - js
| - css
|- templates
__init__.py
Above folder structure allows you to separate out not only the static files but also the Flask view files.
Below are examples of activating/importing files:
1) app/init.py
app = Flask(__name__, static_folder='static')
app.config.from_pyfile('app_config.py')
# Do all your db set up and etcs..
# Import blueprints below set ups to prevent circular import
app.collections.blueprint_one import blueprint_one
app.collections.blueprint_two import blueprint_two
# Now register blueprints that you've imported
app.register_blueprint(blueprint_one, url_prefix='/blueprint_one')
app.register_blueprint(blueprint_two, url_prefix='/blueprint_two')
2) blueprint_one/init.py
# Create a blueprint
from flask import Blueprint
blueprint_one = Blueprint('blueprint_one_name', __name__, template_folder='templates', static_folder='static')
# Import required views to use
from . import blue_print_one_view_file_one.py
3) blueprint_one/blue_print_one_view_file_one.py
# Import blueprint
from app.collections.blueprint_one import blueprint_one
# Any view functions using above blueprint
#blueprint_one.route('/login/, methods=['GET'])
def login():
return render_template('blueprint_one/html_file_one.html')
4) blueprint_one/templates/blueprint_one/html_file_one.html
// Note: instead of .static, you can use blueprint_one.static.
<script type="text/javascript" src="{{ url_for('.static', filename = 'js/js_file_one.js') }}"></script>
5) app/static and app/templates still can be used as you are using it currently.
This solution doesn't solve the problem of putting js and html into same folder but at least you can divide each feature into component like blueprint for more modularized project structure.
There isn't a best way to do this so I like to suggest that you review the way flask projects are supposed to be set up.
http://flask.pocoo.org/docs/1.0/tutorial/layout/
Also I think this question may have an answer that solves your problem here.
Flask url_for URLs in Javascript
Now here's a few thoughts.
To me it sounds like you want to use Templating in files that are in your static folder. This is not what the static folder is intended for. Static means unchanging, so the files in your static folder should not change. Templates are intended to be dynamic which usually means that they change. If you plan to render templates from files in your static directory you will encounter numerous issues and possibly even not be able to do it. One of the most prominent issues I can see you possibly encountering is that browsers will not want to grab the new javascript files if it thinks they're in your static directory. Browsers may assume they haven't changed. Also Flask does some magic behind the scenes. When a url for a file in your static directory is processed from a client who has already requested the file flask returns HTTP CODE 304 which essentially means "File hasn't changed".
I could go on and on about why you shouldn't do this. Instead, if none of information above solves your question, I would like to suggest that you put your javascript templates in a sub-directory of your template directory. Then use the following code to return them.
#app.route('/js/<file_name>',methods=['GET'])
def get_js_templates(file_name):
return render_template('js/'+file_name)
I am by no means an expert in any capacity but I have done full stack development using the flask web framework. If you have more questions leave a comment on this post.

Accessing files inside the folder, which is inside config folder in sails js(node js framework)

I have to access a file , which is inside a folder which is inside the config folder(/config/schemas/userSchemas.js). How to access this file from anywhere else like from my controllers or services. How to do this?
I have tried sails.config.schemas.userSchemas. But it didn't work. What else I can try?
Let's say you have following directory structure
myapp
├── app.js
├── _config
│ ├── _schemas
| |
| ├── userSchemas.js
| ├── otherSchemas.js
|
├── _controller
│ ├── _module1
| | |
| | ├── userController.js
| | ├── otherController.js
| ├── otherController.js
In app.js, you may access as
require('./config/schemas/userSchemas.js');
In otherController.js, you may access as
require('../config/schemas/userSchemas.js');
In userController.js, you may access as
require('../../config/schemas/userSchemas.js');
Conclude: .. is used to go to parent directory(one directory back) while . is used for current directory
I hope this will help you directory structure in node.js
It is really not recommended that you require configuration files directly. Sails will require them for you, and merge the contents into sails.config, ignoring your directory structure completely. So if, for example, your config/schemas/userSchemas.js file contains:
module.exports.userSchemas = {
foo: "bar"
}
Then you'll be able to access that config in your app as sails.config.userSchemas. Note the first line very carefully: if you just do module.exports = {...} then the object will be merged into sails.config, not sails.config.userSchemas -- as I said before, configuration is merged in without regard to directory structure.
If you have files that you need to load in which you don't want to be part of sails.config, simply place them in a different folder in your project (e.g. schemas) and use require as specified in the other answers.
I would suggest to define a global variable for path.
Consider you have following directory structure (as mentioned in #arif's answer).
myapp
├── app.js
├── _config
│ ├── _schemas
| |
| ├── userSchemas.js
| ├── otherSchemas.js
|
├── _controller
│ ├── _module1
| | |
| | ├── userController.js
| | ├── otherController.js
| ├── otherController.js
Now in you app.js write the first line as follow.
global.__base = __dirname + '/';
Note : now global.__base points to /path-to-your-myapp-directory/myapp/
Now you can access userSchema.js or any other file like this.
In all the files (app.js, otherController.js, userController.js), you can require userSchemas.js like this
require(global.__base + 'config/schemas/userSchemas.js');

Express.js Project Structure

I found that Express has an application generator, however the documentation does not explain the purpose of each directory and file. If someone could just give me a short explanation of which files I should be putting where, that would be much appreciated. Here's the generated app structure:
├── app.js
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes
│ ├── index.js
│ └── users.js
└── views
├── error.jade
├── index.jade
└── layout.jade
7 directories, 9 files
The app.js file is the entry-point of your application.
The package.json file contains all of your dependencies and various details regarding your project.
The bin folder should contain the various configuration startup scripts for your application.
For example, instead of applying all the Express middleware in the app.js file, you module.exports = {} them from their own configuration file and require them in app.js. [additional info LINK]
The views folder contains all of your server-side views.
The public folder contains all of your front-end code.
The routes folder contains all the routes that you have created for your application.
As stated in the official documentation, be aware that this is just one way to organize your code.
You should test it out and see if it fits your project.
This thread gives a deeper answer about the www file specifically: What does "./bin/www" do in Express 4.x?
Basically, running your app from the www file (which calls app.js) allows you to start your app with different configurations. You might have a "www" file representing the way the app should be run when on the web, a "dev" file that you, as the developer, would run, a "test" file you would run when running tests, etc. Read the thread linked above for more detail!
This structure is a standard organization for web-app
public contains all client static files (css, client javascript (ex. jQuery), images, fonts...)
routes contains the main back-end code (server side), which compute data before calling a template engine (see below) or respond to the client (via json of xml).
views contains each page template, see jade template. These files are used by scripts in "route"
app.js contains the express core, such as uri parser, modules, database...
package.json is the project descriptor file (used by npm for dependencies and sharing)
If the application generator provide a full example, don't hesitate to open each file (starting from app.js) to understand the project's organization.

Resources