Does express.js have the concept of a home directory? - node.js

I have an express project where I have a directory structure like so,
my-app
routes
index.js
views
public
components
toolbar
test
components
toolbar
Now let's say from my routes I want to require the component toolbar I do it like this
toolbar = require(__dirname + '/../components/toolbar')
Now when I run my test for routes I need to require routes. When I do this I get an error at runtime that toolbar file could not be found.
Is there some global available like say __express_home that I could use in my require so that I would not run into this issue? I would then use it as so,
toolbar = require(__express_home + '/components/toolbar')

You can just do:
toolbar = require('../components/toolbar')
Here is an example from express's github repo.
var express = require('../..')
, app = express()
, site = require('./site')
, post = require('./post')
, user = require('./user');

just use a relative path from wherever you are require() it.
./routes/index.js
./config.js
from ./routes/index.js
var cfg = require('../config');

Related

Nodjs swagger auto gen integration

I need to develop an API using NodeJS and also need to develop documentation for API also. I integrated with swagger auto-gen for swagger.json creation. But the swagger.json not generating properly if I used routes.js as below
var express = require('express');
module.exports = function(app) {
var userController = require('../controller/userController');
var apiRouter = express.Router();
var routerV1 = express.Router();
var routerV2 = express.Router();
app.use('/admin', apiRouter);
apiRouter.use("/v1", routerV1);
apiRouter.use("/v2", routerV2);
routerV1.route('/users').get(userController.getUsersV1);
routerV2.route('/users').get(userController.getUsersV2);
}
and also mapped these routes.js in swagger.js
Please suggest the best way to generate swagger.js
Do we need to create routes file for all controller?
Version 2 of swagger-autogen added this feature. Previous versions don't recognize routes. In your case, the best way to generate the file swagger.js is:
file: swagger.js
const swaggerAutogen = require('swagger-autogen')();
const outputFile = './swagger_output.json';
const endpointsFiles = ['./routes.js']; // root file where the route starts.
swaggerAutogen(outputFile, endpointsFiles).then(() => {
require('./index.js'); // Your project's root file
})
Update your module to the latest version.
And run your project with: node swagger.js
And about the routes file for all controller, you don't need to implement it for each one, but it also depends on the structure of your code. If you have a root route file like the example, this is enough for all sub-routes to be scanned. I hope it helps you. Take a look at this example if you need to:
swagger-autogen using router

Understrap 'require is not defined'

I'm using the Understrap theme for my Wordpress project. I created a simple custom .js file to add to my project but I'm getting a 'require is not defined' error.
custom .js file
var express = require('express');
var moment = require('moment');
var app = express();
var m = moment();
app.get('/', function (req, res) {
m.set({'year': 2017, 'month': 5, 'day': 29});
//res.send(moment().format('YYYY/M/D'));
var today = document.getElementById('today');
today.innerHTML = moment().format('YYYY/M/D');
})
Nodejs is a server side language, you cannot use require in browser side unless you use browserify or webpack. And also you cannot use express in browser because it's a server side framework, as you are using a theme for wordpress, I don't think you need to use nodejs at all, just write the plain js.

Express js modular REST framework

I am planning to develop only rest api using express js, I looked into lot of boilerplate projects. None of them provide modularity. Modularity I mean all code related to articles module need to be in article folder then I can drag and drop that.
I saw MEAN somewhat close to that but it has client side (angular related) code in that. I need pure rest api framework.
To me it doesn't sound like you want to use a MEN stack, I do not see a reason to use MongoDB in your question. You can write modular express apps e.g. like this:
Assuming you have three modules in three different folders moduleA, moduleB and moduleC. Each folder contains its respective logic and provides some RESTful routes to the outside world. In express you would create one separate Router for each module like this:
ModuleA:
/* moduleA/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleA
module.exports = router;
ModuleB:
/* moduleB/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleB
module.exports = router;
ModuleC:
/* moduleC/routes.js */
var express = require('express');
var router = express.Router();
... // add all routes of moduleC
module.exports = router;
And then you would have one main app.js file in your root folder where you enable and disble the single modules by mounting them into the main express app:
/* app.js */
var express = require('express');
var moduleA = require('./moduleA/routes');
var moduleB = require('./moduleB/routes');
var moduleC = require('./moduleC/routes');
var app = express();
... // add your main app's middlewares
app.use('/moduleA', moduleA);
app.use('/moduleB', moduleB);
// app.use('/moduleC', moduleC);
app.listen(3000);
In this example the modules moduleA and moduleB are enabled and are reached by the routes /moduleA/* and /moduleB/* respectively. The module moduleC is disabled as we commented it out.
If you have questions please leave a comment.
It sounds like you want to use a "MEN" stack, which is MongoDB (for backend), Express, and Node.JS.
Here's a tutorial on how to build a project with a "MEN" stack: https://github.com/maslennikov/node-tutorial-men or this one: https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4

Can I pass variable to required file?

In express, I'm trying to move my minification to a requierd file:
app.js:
var app = express();
var minify = require("./minify.js");
In that file I try to set my template engine.
minify.js:
var app = express();
app.engine('html', mustacheExpress());
Later when I try to use to use the rendering engine in app.js, I get the error that no template-engine is set. It works if I run it all in the same file. I think the problem is that I declare the app-variable twice. How can I pass the app-variable into minify.js?
The problem is that you define new app variable, and you currently instantiate brand new express instance by calling express().
What you need to do is start using functions so that you can pass params (there are other methods too, but this is one that will work for you):
// app.js
var app = express();
var minify = require('./minify'); // don't include .js!
minify(app); // CALL the function that minify.js exports, passing params
// minify.js
module.exports = function(app) {
// because app comes as a parameter, it's the very same you've created in app.js
app.engine('html', mustacheExpress());
}
Again, there are many different methods and maybe proper approaches, depending on what you want to do, but this will do the job in your case. Read more about NodeJS and it's require system.
You can pass 'app' from app.js to your minify by using function in your module like Andrey said. You can do it like this too for example :
minify.js
module.exports = {
setAppEngine : function(app) {
app.engine( [...] );
}
}
And calling it like this in your app.js:
app.js
var app = express();
var minify = require("./minify.js").setAppEngine(app);
This solution is very useful because you can set and call others methods in minify.js. For example, you can do with the same code in minify.js:
app.js
var app = express();
var minify = require("./minify.js");
minify.setAppEngine(app);

Express js Where do the settings go?

In the express docs, there is a section called settings:
http://expressjs.com/api.html#app-settings
But I can't figure out where exactly the should go (to some function? as a dictionary in the use middleware? or somewhere else?)
P.S. How would I go about figure theses things out - do I need to look at source?
There are many ways to manage configuration, but here's a blog post I wrote about it:
http://www.chovy.com/node-js/managing-config-variables-inside-a-node-js-application/
The basic premise is you have a file for each environment (ie config.development.js, config.production.js) and one for everything else called config.global.js the development and production files would simply overwrite whatever you set in the global based on the needs of that environment.
Here’s the basic config/index.js file, this will load the config.test.js file assuming your NODE_ENV=test (we will default to ‘development’ if NODE_ENV is not defined):
var env = process.env.NODE_ENV || 'development'
, cfg = require('./config.'+env);
module.exports = cfg;
Next comes the config.test.js which will include config.global.js and then overwrite it’s json objects as needed:
config.test.js:
var config = require('./config.global');
config.env = 'test';
config.hostname = 'test.example';
config.mongo.db = 'example_test';
module.exports = config;
And the config.global.js which defines all the defaults:
var config = module.exports = {};
config.env = 'development';
config.hostname = 'dev.example.com';
//mongo database
config.mongo = {};
config.mongo.uri = process.env.MONGO_URI || 'localhost';
config.mongo.db = 'example_dev';
Now we wrap it all together and use it in our code…for example in a model, you might do something like this in ./models/user.js:
var mongoose = require('mongoose')
, cfg = require('../config')
, db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);
And that’s all there is to it.
You have to use app.set:
app.set('name of setting', 'value');
You usually put them into a specific configuration block:
app.configure(function () {
// ...
});
You can even use named blocks for having different configurations.
Let express create an application for you and have a look at it. For that simply run
$ express --help
at the command prompt and see what it offers.
PS: This answers both of your questions ;-)

Resources