nodejs how to execute other js file from index.js? - javascript

I want to create web app with nodejs but with structure like this
- modules
| - module1
| - module1.js
| - module2
| - module2.js
- index.js
- settings.js
First, i never use nodejs from scratch
Second, i know you will suggest using any other framework, sorry guys here i want to understand how nodejs and may be other nodejs framework works.
Third, this is for educational purpose
in modules/module1/module1.js :
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('Hello World aw!')
honestly i dont know how to code it properly, what i really want is i wanna execute that code and response to browser Hello World aw! from index.js :
router.get('/', function (req, res) {
//in here i call modules/module1/module1.js, and execute the code
})
and how to do that properly? so it can run well

to load any script or module in nodejs you need to use require
like this
var module1 = require(__dirname + 'modules/module1/module1.js');
and then you can use module1 anywhere in your code
BTW for express you should create routes and then attach that routes to your app. See example below.
users.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
server.js
var express = require('express');
var app = express();
var users = require('./routes/users');
....
app.use('/users', users);

Every time with node when you need to have a module in a particular page you need to require this module.
example: you want to get the library express so at the top of your file who you want this library you do something like that.
var express = require('express');
Now you can use express in all the file. When this is a node library you just need to require the name.
this is the same thing with a file you create and you want inside a other one
var myfile = require('./../myfile');
with that you can use the word myfile inside all the file. But you need to figure out the path to this one.
A good links for read about this

Related

how to access express module for other js file , express module is already included in app.js

Let Me explain what I am working on .
I have included the express module in app.js .
Here I want to access this module in index.js , admin.js , gallery.js.
but I dont want to write the same code again in all over js file .
let me show you my scenario.
app.js has
var express = require('express');
index.js has
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
gallery.js has
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.render('gallery', { title: 'Gallery' });
});
module.exports = router;
Here var express = require('express'); is already present in app.js .
I want to reuse it from app.js instead of including in every file .
What I have tried so far
I made global in app.js , so that I can access it all over
global.express = require('express');
this code is working for me .
Is this the correct approach or any other way to do or including express module in all the js file is fine ?
You can export your files (not app.js assuming this is your entry point) as a function and pass your express module into those files
gallery.js
module.exports = function(app) {
/* GET users listing. */
app.get('/', function(req, res, next) {
res.render('gallery', { title: 'Gallery' });
});
}
app.js
var express = require('express')
var app = express();
var galleryRoute = require('./gallery');
// Routes
galleryRoute(app);
I have read some where to avoid using Global Variables because there are some cons of it here are few of them:
The first reason is that when you create a global variable, it exists
throughout the lifetime of the application. When a variable persists
through the lifetime of the app it means that it is there, in memory,
occupying resources while the app is running.
Second, traditionally using global variables can cause concurrency
issues. If multiple threads can access the same variable and there
are no access modifiers or failsafes in place, it can lead to some
serious issues of two threads attempting to access and use the same
variable. However, while this is the case in other languages, it is
not necessarily the case for Node.js as it is strictly a
single-threaded environment. While it is possible to cluster Node
processes, there is no native way to communicate between them.
The last reason I am going to talk about is that using globals can
cause implicit coupling between files or variables. Coupling is not a
good thing when it comes to writing great code. When writing code, we
want to make sure that it is as modular and reusable as possible,
while also making sure it is easy to use and understand. Coupling
pieces of your code together can lead to some major headaches down
the road when you are trying to debug why something isn't working.
As for your question you can export the express from app.js or index and use it everywhere.
It is discouraged to use additional global variables as application already has 'export' and 'require' global variables. (exports/require are not keywords, but global variables.)
If you need to export the 'app' for other files, you can do something like below.
in index.js:
var express_app = module.exports = express();
now index.js can be required to bring app into any file.
in any.js file:
var express_app = require('./index');

How to app.use() a file that has some other app.use() within nodeJS

So maybe it sounds pretty tricky at a first look.I'll explain what I actually want to do :
I'm working with NodeJS & expressJS and I'm trying to modularize the project,here is what I want to do:
Let's say I have the in the main server .js file the router.get / post / put / delete etc splitted in some other files for every type :
Ex :
...
app.use(require('./routes/account_method1.js'));
app.use(require('./routes/account_method2.js'));
app.use(require('./routes/games_method1.js'));
app.use(require('./routes/games_method3.js'));
app.use(require('./routes/emails_method5.js'));
...
I performed that pretty easy : I just used the code mentioned above in the main .js file and in the required files I've just put :
module.exports = router;
And that's pretty much it.But the problem is :
Now I want do to something like :
...
app.use(require('./routes/account/panel.js'));
app.use(require('./routes/games/panel.js'));
app.use(require('./routes/emails/panel.js'));
...
And in every ./routes/x/panel.js file to have the specific .js files required withing , for just an example in ./routes/account.panel.js I would like to have and work :
app.use(require('./account_method1.js'));
app.use(require('./account_method2.js'));
Assuming account_method1.js and account_method2.js are in the same directory with the specific panel.js file.And then,require these panel.js files in the main server .js file.
So if now I have :
Server ---> ./routes/account_method1.js
---> ./routes/account_method2.js
I would want to make it :
Server ---> ./routes/account/panel.js ---> ./routes/account_method1.js
./routes/account_method2.js
I won't paste here any code because it's just a problem about a way of importing files and I've already mentioned how I require my .js files on the main server.
Soo...what do you think?
EDIT :
I think will show you where is the problem :
./routes/test.js ( this file have to add to app another file,register.js)
const express = require('express');
const router = express.Router();
console.log("BEFORE ROUTER.USE");
router.use(require('./register.js'));
console.log("AFTER ROUTER.USE");
module.exports = router;
./app.js (the main .js server file)
....
var test = require('./routes/test.js');
app.use(test);
....
./routes/register.js
const express = require('express');
const router = express.Router();
...
//some router.post / get / delete
...
module.exports = router;
And when I try to access the URLs from that register.js file they aren't working
Better way is using router:
eg: controller/api.js
const express = require('express')
const router = express.Router()
router.get('/', function(req, res) {
//console.log(res.apiData);
res.json({message:'ok'});
});
module.exports = router;
and later
app.use('/api', require('controller/api'))
Router can be imported to another router. I'm use this:
main.js:
app.use(require('./controller'));
controller/index.js:
const express = require('express')
const router = express.Router()
const isAuth = require('../middlewares/is-auth')
const isValidApiKey = require('../middlewares/is-api-key')
const isAdmin = require('../middlewares/is-admin')
router.use('/auth', require('./auth'));
router.use('/profile', isAuth, require('./profile'));
router.use('/api', isValidApiKey, require('./api'));
router.use('/admin', isAuth, isAdmin, require('./admin'))
If the request service code is long, you can also move it to a separate file, but I think it's better to divide it into smaller, reusable parts and use it as middleware, eg:
route.all('/:orderId(\\d+)', fileOrderMiddleware, fileAltMiddleware, hasTransferMiddleware, orderServeMiddleware);

I want to do basic express routing. But it return -> Error: Route.get() requires a callback function but got a [object Undefined]

Motive: basic express routing. since there are many files in one directory, i want this directory path handled by variable. But the other file handled sparately. So when i code the path, it will require file name only. This will make easy coding off course.
Lets see i have main file app.js located on "./ "
and here i code:
var next = require('./routes');
app.get('/', next.index);
The path is handled by variable next. I also have file index.js located on "./routes "
and here i code:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
Instead of doing respond, it return error as ->
Error: Route.get() requires a callback function but got a [object Undefined]
But when i replace next variable as follow from app.js:
var next = require('./routes/index');
app.get('/', next);
It work. So where do i need to change?
Simple..
In Node.js, when your use require, you aim to load a module
If you print (with console.log) the result of require('./routes') you will see that this module is not exposing index whatsoever
When you use require('./routes/index') you are loading a different module which contains the functionality you need
This code causes an error because when you use require it will automatically require the index.js file of the directory. So these 2 lines of code are the same.
var next = require('./routes');
var next = require('./routes/index');
So when you do this code it will cause an error because next.index does not exist.
var next = require('./routes');
app.get('/', next.index); // This will cause an error
The proper way to do this is:
var next = require('./routes');
app.get('/', next);

Express Serving a Static File: Server and Client in Different Locations

I'm trying to get my express to serve up static files that are in another location:
This is the current directory I have:
|__client
| |__thumbnails.html
|
|__server
|__app.js
I tried to just use app.use(express.static(path.join(__dirname, '..', 'client')));, but it wouldn't serve the file at all. However, when I used the same path.join for a get request on '/' it will send the file.
Here it the code I have at the moment. It's working, thank God, but I want to see if there is a way for me to serve it without actually sending the file.
const express = require('express');
const path = require('path');
const similar = require('./routes/similar');
const image = require('./routes/images');
const app = express();
app.use(express.static(path.join(__dirname, '..', 'client')));
app.use('/item', similar);
app.use('/thumbnail', image);
app.get('/', (req, res) => res.status(200).sendFile(path.join(__dirname, '..', 'client', 'thumbnail.html')));
module.exports = app;
You can make the file anything you want, through configuration of the serve-static module:
https://expressjs.com/en/resources/middleware/serve-static.html
From that page:
var express = require('express')
var serveStatic = require('serve-static')
var app = express()
app.use(serveStatic('public/ftp', {'index': ['default.html', 'default.htm']}))
app.listen(3000)
now anything that you put in the 'index' array will be looked at, in the order you defined.
Otherwise, you would still be able to get to your html file if you put the actual filename in the url.
Okay I think I figured it out. So apparently you have to have the html saved as index. Express is looking for that, but since I don't have an index.html it skips my thumbnails.html.
So renaming my html to index.html fixed the issue.
UPDATE:
So reading through the documentation, you can set the what the default is by passing in an options. I passed in { index: 'thumbnails.html' } as the second argument for static and it serves my html.

What's the best way to access the express 'app' object from inside a separate route file?

In Express 4, by default, routes are loaded from a separate file:
app.use('/', routes);
Would load routes/index.js.
I have a third-party library that attaches to app itself. Is there a preferred way to access app from inside routes/index.js?
I've thought about dependency injection ie, routes/index.js does
module.exports = function(app){
(routes go here)
}
and then:
app.use('/', routes(app))
But I wonder if there's a better way. What's the best way to access the express 'app' object from inside a separate route file?
You can simply access app by req.app in your route handlers
I looked at a number of app generators and everyone does it differently.
Mostly though I've seen it work the opposite from what you are asking. The route modules do not get the app passed in, they just return themselves and are attached to the app.
I like to use the following pattern:
routers/hello.js:
var express = require('express');
var router = express.Router();
router.get('/hello', function (req, res) {
res.send('Hello, World!');
});
module.exports = router;
app.js:
var express = require('express');
var app = express();
app.use('/sample', require('./routers/hello'));
// other routers are attached
module.exports = app;
server.js:
var http = require('http');
var app = require('app');
var server = http.createServer(app);
server.listen(3000):
So the modules in routers/ return an Express Router object that are then attached to the app on their respective paths (routes).
This is inspired on the Express Application generator, but uses Routes instead of Routers. My advice, use the linked generator and start from there.

Categories