Change current folder in Node.js - javascript

I have a file fetching some other files:
start.js
require("./users");
but the users.js file is not in the current folder but in model/.
I want to be able to run:
node start.js model
and it would assume that ./ is the same as model/ in start.js.
How do I do that?

All you need to do is to make Node.js recognize the folder model as a module.
In order to do that, you need to place a file called index.js inside the model folder.
// model/index.js
exports.users = require('./users'); // model/users.js
exports.posts = require('./posts'); // model/posts.js
// etc.
Now you can import the model module and access it's exports:
var models = require('./model');
models.users.create(); // some function exported in model/users.js
models.posts.list(); // this was exported in model/posts.js

You can add ./model dir to require.paths array:
require.paths.unshift("./model");
var
users = require("users"), // It works!
posts = require("posts");
But I want to ask you: why do you need this instead of using
var
users = require("./model/users"), // It works!
posts = require("./model/posts");
?

Related

NodeJS. How to access the directory name of the js file from a module which is being used in that js file?

I m creating an api.
Soo my API Structure is like
<myapi_folder>
|
---index.js
---package.json
---<utils_folder>
|
---load.js
Now let work.js is a file which is located somewhere on my system.
The code of
work.js
const myapp = require("myapi_folder");
The point is i want to know the directory location of work.js in load.js program.
Please help me.
Thanks in advance
How does work.js interact with load.js? I assume that worker.js require 'myapi_folder', and 'myapi_folder/index.js' called 'load.js'?
There are two possible ways.
1 - Explicitly pass __dirname of caller to callee. In your case:
// myapi_folder/index.js
function load(callerDir) {
require('./load').do(callerDir);
}
// worker.js
var api = require('myapi_folder');
api.load(__dirname);
2- Use callsite, this is hacky and not recommended for this case.
// myapi_folder/index.js
var callsite = require('callsite');
function load() {
var callerDir = callsite()[1].getFileName();
require('./load').do(callerDir);
}
We use the approot module and it works very well.
This is at the top of most of our node modules:
var appRoot = require('app-root-path');
var logger = require(appRoot + '/services/logger');
var cache = require(appRoot + '/services/cache');

How to export an object with methods and properties

I have two js files in Electron (which uses Nodejs) and I try to export from one and require in another.
app.js:
App = {
server: {
host: '192.168.0.5',
user: 'root',
}
ping: function() {
}
}
exports.App = App
I have tried every way possible of exporting, including module.exports = App, module.exports.App = App and so on.
ping.js first attempt:
var App = require('../app.js') // I have also tried adding .App to the end
console.log(App) // This returns an object which contains the App object
ping.js second attempt:
var App = require('../app.js')
App.x = 'y'
console.log(App) // this returns an object which contains the App object and the x property
It may appear that App contains another App object, but console.log(App.App) says it doesn't exist.
The first thing I'd to do solve this would be to make sure I'm using the full path to the required module, as in:
const Path = require('path')
const App = require(Path.join(__dirname,'../app')) // the .js isn't needed here.
Note that this assumes that the app.js file is in the immediate parent directory of the one in which the application runs.
If that doesn't work, I'd make sure the files are where you think they are, and that the process you're running is located within the file system where you think it is. You can determine this by adding this to the top of your main script file:
console.log("current working directory:",process.cwd())
Or in es6:
console.log(`current working directory: %s`, process.cwd())
If the printed directory doesn't match your assumptions, modify your require statement accordingly.
And for the record, the "correct" way to export your App map would be to:
const App = {
...
}
module.exports = App
Or using es7:
export default App = {
...
}
(See export for more on es7 modules.)
Either way, you'd then require the module as:
const App = require(PATH_TO_APP)

Sequelize and Node.js: Issue with Module.Exports and Table Models

I am working on installing multiple databases in one server. To start this process, I am assigning one database in the index.js export object such that I will be able to add another DB as I build up the system. Below is the description of the issue.
When I run the server.js file, the .sync function for the database db1 syncs Table1 and Table2 and then begins listening on its port. Its clear the server.js file is receiving the module.exports = db through the var db = require('./models'). However in the file models/Table1.js the server throws an error TypeError: Cannot read property 'Table1' of undefined. I did check the console output for db in the models/Table1.js and it's empty, so its clear module.exports = db is not being accessed in this model.
Can someone provide a solution to correct this issue?
The partial code for the Table1.js model and other files listed above is below:
models/Table1.js
var db = require('./.')
[...]
var new_instance = db.db1.Table1.build({...})
server.js
var db = `require('./models')`
[...]
db.db1.sync(function(err) {});
models/index.js
var sq = new Sequelize(dbname, user, password, config);
db['db1'] = {
Sequelize: Sequelize,
sequelize: sq,
Table1: sq.import(__dirname + '/...'),
Table2: sq.import(__dirname + '/...')
}
module.exports = db;
The module.exports = db is being accessed, but you have created a cyclic dependency between models/index.js and models/Table1.js due to the fact that in the Table1.js model you require index.js file and in the index.js file you perform sequelize.import() call which performs require(path) to include the model definition, so in your case it calls require('./Table1.js') - there comes the cyclic dependency.
You should consider putting the var new_instance = db.db1.Table1.build({...}) somewhere else in order to avoid this situation. Files with model definitions should be only used to create the Model definitions, try to avoid performing additional operations.
Take a look at this question - How to deal with cyclic dependencies in Node.js to find out how you can deal with this kind of situations.
EDIT
According to your comment let's consider simple example with below structure
- script.js
- models
- index.js
- Table1.js
In script.js
var db = require('./models');
var new_instance = db.db1.Table1.build({...});
It can be done if you would not require the script.js inside any of the files placed inside models directory.

How to make object references available in Node modules?

I have an Express.js web app. In the main app.js file, I require() a bunch of third party dependencies. Recently I've started extracting parts of my app.js code into separate modules, e.g.
// in app.js
var users = require('./modules/users');
// and then e.g.
// users.add(doc);
Inside my modules, I sometimes need to use objects that are available in my main app.js file and I'm wondering what's the best way to pass references to those object to my modules.
My current approach:
// in app.js
// pass needed object references in initialization step
users.init([db, logger]);
and
// in modules/users.js
var db, logger;
exports.init = function (deps) {
db = deps[0];
logger = deps[1];
};
Does this approach make sense? Is there a better way to perform this?
Sure, just use modules! :)
// db.js
// create db instance here rather than in app.js
module.exports = db;
And
// logger.js
// create logger instance here rather than in app.js
module.exports = logger;
Then
// app.js
var db = require('./db');
And
// lib/somewhere.js
var db = require('../db');
This way you're able to rely on the CommonJS dependency injection system rather than on doing the dependency injection all by yourself (passing references around instead of requireing a module into yours).
The reason why this works as expected is that modules are only interpreted once, so if you instantiate everything once as opposed to using a factory function, it just works.
You should just be able to require modules as normal:
// users.js
var db = require('./db');
exports.init = function() {
// use db in here
};
However, sometimes this isn't possible and you will need to explicitly pass in the module.
One way to do it is to pass in dependencies when you require the module:
// users.js
module.exports = function(db, logger) {
return {
init: function() { /* use db and logger in here */}
};
}
// app.js
var db = ...;
var logger = ...;
var users = require('./users')(db, logger);
users.init();
This is the pattern that I personally prefer, I think it's cleaner to pass dependencies into the require than into some init method like you have in your example.
You'll see this done in ExpressJS code quite a lot, for example when we have all our routes in another file and need to pass our app instance around:
require('./routes')(app);
If you need something to be initialized specifically in app.js rather than their own module you can export them from app.js and then require app.js:
// app.js
var db = require("db"),
logger = require("logger");
// do your initialization with db and logger
module.exports = { db: db, logger: logger };
and then:
// users.js
var db = require("./app").db,
logger = require("./app").logger;
// use db and logger
This works because as #Nico mentioned, modules are interpreted once and app.js will not be interpreted each time it is required from elsewhere.

How can I do my routing without having one long file of all the routes in nodejs?

Using this link as a reference https://github.com/visionmedia/express/tree/master/examples/route-separation to what "could be done"
I AM NOT USING EXPRESS. I AM USING THEM AS AN EXAMPLE.
I want to do something like this but "simpler" ...
How can I get away from declaring all my routes in one long, complex list all in one file? Can I define them by passing a router into my modules, and then including all the code in one directory ... ok, I'll suffer having one long document that only does "require" includes, like an index.js, for this one ~ at least that one my build scripts can rebuild for me, but preferably not in my primary file for every single route that I may add.
So for instance, they use this code:
// General
app.get('/', site.index);
// User
app.all('/users', user.list);
app.all('/user/:id/:op?', user.load);
app.get('/user/:id', user.view);
app.get('/user/:id/view', user.view);
app.get('/user/:id/edit', user.edit);
app.put('/user/:id/edit', user.update);
// Posts
app.get('/posts', post.list);
I want to avoid making a list like that in my app.js. I want instead to have each file know what the routes are for that file.
Here's what I'm wanting to do: (please don't critique the code, I'm making it very simple so I make sure that I am illustrating my code the way I want to do it)
//app.js
var router = require('./myRouter.js')
var includes = require('./routes/*.js').register(router)
// do some stuff here with an https server and start the server here
and
//./routes/user.js
var myRouter;
exports.register(router){
myRouter = router;
}
router.addRoute(/* here I do the magic associated with this route */)
Can I do it just that simply? What am I missing here?
I haven't written this code because I'm just ever so certain that I'm going about this the wrong way.
And if I am going to have to use something like an index.js in the /routes/ folder, can I use that same concept that I demonstrated I would like to use in my code of .register(router) appended so I can pass that information down recursively? Would that work?
I use an index.js file for this and use require("routes") which is a folder.
// app.js
route = require("./routes"),
...
route(app);
// routes/index.js
var index = require("./index-route"),
about = require("./about-route"),
posts = require("./posts-route");
module.exports = function(app) {
index(app);
about(app);
posts(app);
};
This works because if you require a folder it will load index.js by default.
If you have a lot of routes you might want to load them based on convention
var routes = [];
// read all files
fs.readdir("./", function(files) {
files.forEach(function(val) {
// require all non-index.js files.
if (val !== "index.js") {
routes.push(require(val));
}
});
});
module.exports = function(app) {
// for each route you required call it with app.
routes.forEach(val.bind(null, app));
}
This would load all .js files that are not "index.js", so any file in your /routes/ folder would be loaded and run when you route them.
Your solution looks vaguely like you wish to use the Visitor Patern, in which case I suggest you make ./roots/ require-able (see this question) and in index.js you include all the files you wish (as local's) and export a register module which calls the register module on each of the required files.
Or you could copy the code from the above answer directly into your main file.

Categories

Resources