Can I pass variable to required file? - node.js

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);

Related

Instantiating express

I have an issue where I need to load express like this:
var express = require('express');
var app = express();
In order to get .static to work:
app.use(express.static(__dirname+'views'));
Any reason why I can't use shorthand:
var app = require('express')();
When I try the short hand it says express.static is undefined and my script won't run. Is this just a feature that's not supported by express?
Any reason why I can't use shorthand:
var app = require('express')();
If you considered this statement from your script,
app.use(express.static(__dirname+'views'));
you are using static method of express.In order to use this method,you must import express first and store it in some variables like u did
var express = require('express');
From express#express.js
exports.static = require('serve-static');
static defined at class level.
then instantiate it
like this
var app = express();
to get the access to object level(prototype) method and properties like
app#use app#engine etc.
From express#application //line no 78
EDIT :
but then why can't I use app.static if I did var app = require('express')();
As I said,.static is the class level method and not the instance/object(prototype) level.
So,by var app = require('express')()
you will get express instance / object (prototype) which dont have app.static method.So,you can't use.
Read more javascript-class-method-vs-class-prototype-method
This will work: const app = (() => require('express'))()();
But you still need express itself, so there literally is no real point to requiring twice.

Express---routes and "app"?

I have the following Express code in the initial routes file of my MVC setup. This is the entire file. What I am trying to determine is whether the app after the require statement is able to reference the var app = express() declaration in my main server.js file?
module.exports = function(app){
require('./main')(app);
};

Cannot set express.static from another module

This works
var express = require('express');
var app = express();
var request = require('request');
// initialize session, redis server will be used if it's running otherwise will store in memory
require('./config/session.js')(app, function () {
// configurations
require('./config/bodyparser.js')(app);
require('./config/cookieparser.js')(app);
require('./config/compression.js')(app);
//require('./config/other.js')(app, express);
app.use(express.static('./public', { /*maxAge: 86400000*/}));
app.listen(3000, function () { console.log('running...'); });
});
But if I uncomment require other.js and comment app.use it doesn't. Here is the other.js file.
module.exports = function (app, express)
{
app.use(express.static('../public', { /*maxAge: 86400000*/}));
return app;
}
Tried different relatives paths but all failed. Here is the project structure
-config
--other.js
-public
-app.js
The error I get is
Cannot GET /index.html
on my browser, no error in console.
The issue here is that when you require the other.js file, the relative path is using the cwd of app.js. The best way to avoid this (and avoid the hassle with relative paths) is to use path.resolve and the __dirname variable.
__dirname is a special Node.js variable that always equals the current working directory of the file it's in. So combined with path.resolve you can always be sure that no matter where the file is being require'd it uses the correct path.
In other.js:
var path = require('path');
....
app.use(express.static(path.resolve(__dirname, '../public')));
Or you could simply update other.js to use ./public but I believe the above is better practice as if you move the app.js or require other.js in a different folder it won't resolve correctly
Info on path.resolve here

Hierarchical routing with plain Express.js

I’m implementing a RESTful API using Node and Express. When it comes to routing, currently it looks like this:
var cat = new CatModel();
var dog = new DogModel();
app.route('/cats').get(cat.index);
app.route('/cats/:id').get(cat.show).post(cat.new).put(cat.update);
app.route('/dogs').get(dog.index);
app.route('/dogs/:id').get(dog.show).post(dog.new).put(dog.update);
I don’t like this for two reasons:
Both cat and dog models are instantiated whether I need them or not.
I have to repeat /cats and /dogs for every path schema
I’d love to have something like this (not working, of course):
app.route('/cats', function(req, res)
{
var cat = new CatModel();
this.route('/').get(cat.index);
this.route('/:id').get(cat.show).post(cat.new).put(cat.update);
});
app.route('/dogs', function(req, res)
{
var dog = new DogModel();
this.route('/').get(dog.index);
this.route('/:id').get(dog.show).post(dog.new).put(dog.update);
});
Is there a clean way in modern Express without any further modules (like express-namespace)? I could go for separate routers for each model and assigning them with app.use('/cats', catRouter). However, what if I have more than one hierarchy level like '/tools/hammers/:id'? I would then have routers within routers within routers, which seems like overkill to me.
I would then have routers within routers within routers, which seems like overkill to me.
Perhaps, but that is the built-in method of prefixing -- to app.use() a Router().
var cats = express.Router();
app.use('/cats', cats);
cats.route('/').get(cat.index);
cats.route('/:id').get(cat.show).post(cat.new).put(cat.update);
// ...
And, to have one Router .use() another to define multiple depths:
var tools = express.Router();
app.use('/tools', tools);
var hammers = express.Router();
tools.use('/hammers', hammers);
// effectively: '/tools/hammers/:id'
hammers.route('/:id').get(...);
Though, to be closer to your 2nd snippet, you can define a custom method:
var express = require('express');
express.application.prefix = express.Router.prefix = function (path, configure) {
var router = express.Router();
this.use(path, router);
configure(router);
return router;
};
var app = express();
app.prefix('/cats', function (cats) {
cats.route('/').get(cat.index);
cats.route('/:id').get(cat.show).post(cat.new).put(cat.update);
});
app.prefix('/dogs', ...);
app.prefix('/tools', function (tools) {
tools.prefix('/hammers', function (hammers) {
hammers.route('/:id').get(...);
});
});
Check out the new Router in Express 4. It sounds exactly what you're looking for.

Extend View class in Express on Node.js

I'd like to override the View class in the Express framework, used in Node.js. I want to augment the lookup method, but I can't see a way to do this without altering the Express and App modules. I'd favour deriving from the Express framework, but I can't figure out a neat way to do this.
Any ideas?
Thanks
It seems to me you should be able to:
var View = require('express/lib/view');
// Keep reference to original lookup method
var _lookup = View.prototype.lookup;
// Override lookup method
View.prototype.lookup = function (path) {
// Your implementation here
};
Update:
Run this as a demonstration:
var View = require('express/lib/view');
var _lookup = View.prototype.lookup;
var express = require('express');
View.prototype.lookup = function (path) {
console.log('LOOKUP!!! ' + path);
return _lookup.call(this, path);
};
var app = express();
app.get('/', function (req, res) {
res.render('foo.jade');
});
app.listen(3000);
Run
node app & sleep 1 && curl localhost:3000
I hope this will demonstrate the viability of this way of overriding a method.
It depends on which version of Express you are using.
You can easily augment the view lookup code only if your app is using Express prior to version 3
Since Express 3.0 that's not doable anymore.
You can check one of my old related answers for sample code:
Multiple View paths on Node.js + Express

Resources