How to set up references and import external modules as top-level objects in Typescript in Node.js - node.js

So this is a Typescript file structure and naming question. I'm just starting to learn about Typescript classes and modules and I have a few questions on how to structure model logic across multiple files.
Say I have a small rest api written in node.js with User and Photo models, and it's a simple api that lets users register and upload a photo.
Assuming this file structure:
-app
-models
-user.js
-photo.js
-controller.js
In my controller is it better to use a reference path declaration or external modules when referencing models? Does this overlap with just using a standard node.js require statement?
If I use an import statement to load the models as an external module, can I change the below example to move the export to the top-level so that I can just new up a User() rather than models.User().
for example, the models, and anotherModel seems a bit redundant - and I don't want to combine all the models into one file.
controller.js
import models = require('./models/user');
import anotherModel = require('./models/photo');
var newUser = new models.User();
var newMoment = new anotherModel.Moment();
user.js
export class User {
name:string
}
photo.js
export class Photo {
url:string
}

You can create a model / index.ts and re-export all the models from that file for easier consumption. This is conventional node.js paradigm.

Related

How to organize large-scale node apps

Scenario:
I want to keep a clean structure, something like
/org/myapp/events/Events.js
/org/myapp/events/EventDispatcher.js
/org/myapp/game/Game.js
/org/myapp/characters/Worker.js
/org/myapp/characters/Warrior.js
/org/myapp/characters/Elite.js
etc etc
Currently I'm using require, and module.exports. It works but I'm curious as to what the community is doing outside of what I've been reading.
Question:
What is a good way to organize a medium to large scale js application (30+ classes) while keeping a good handle on performance as well as overall organization?
Current Implementation
Based on my example above I would be doing
Events.js
class Events {
...
}
module.exports = Events;
Then for every class that uses Events
const Events = require("/org/myapp/events/Events.js");
What you're doing works fine, but personally I prefer to have each directory (e.g. /org/myapp/events) have an index.js file which exports the classes within the folder, like so:
// /org/myapp/events/index.js
module.exports = {
EventDispatcher: require('./event-dispatcher.js')
}
Then consuming code can require the whole directory once and then access the parts as needed:
const events = require('./events');
const dispatcher = new events.EventDispatcher();

Mongoose - add global method to all models

Simple question:
How can I add static methods to my models in Mongoose, that applies to every model instead of just one?
So you have one static method that (eg) your User, Blog, Comment, and Alert models all share without any differences in implementation?
The de facto way to apply behavior to multiple different models in Mongoose is through plugins, and you can do a global plugin. I'll stick to traditional syntax, but if you want to use ES6 imports and exports feel free.
// ./models/plugins/echo.js
module.exports = function echoPlugin(schema, options) {
schema.statics.echo = function(){ console.log('Echo'); }
}
That defines a plugin which could be applied to a single schema like so:
userSchema.plugin(require('./plugins/echo'));
Or alternatively to all models in your project like so:
// somewhere in your app startup code
var mongoose = require('mongoose');
var echoPlugin = require('./models/plugins/echo');
mongoose.plugin(echoPlugin);

Node.js - What's the scope of the require()d modules?

I am trying to organize a Node.js application developed with Express 4 and am confused about the scope of modules which are imported with require().
Imagine that I use require('./services/user') to import a service in a module such as routes/user.js:
var userService = require('./services/user');
Then I do the same require('./services/user') in another module routes/department.js.
My question is: is userService the same instance in user.js and department.js or each of them has it's own userService object? That is to say, once you've exported some element through module.exports = XXX if you require the same file, will you get always the same instance? Could you show me where in the Node.js docs that's specified?
If I understand your question correctly, you have theses files:
.
|_. app.js
|_. routes/
|_. user.js
|_. department.js
|_. services/
|_. user
And your code do this:
app.js call user.js
user.js call user
app.js call department.js
department.js
In that case, at the first time user is required, it is put on cache in require.cache.
Then the second time it is called, the caller get require.cache['./service/user'], where is stored your object.
As such, you do have the same object in both department.js and user.js.
Source:
http://nodejs.org/docs/latest/api/modules.html#modules_caching
http://nodejs.org/docs/latest/api/modules.html#modules_cycles (helped me understand)
Understanding Node.js modules: multiple requires return the same object?
Self modifying code in node.js, would cluster work? (about require.cache)
EDIT:
Other helpful links:
node.js require() cache - possible to invalidate?

Custom modules using Spotify require()

The Spotify documentation states that you can define custom modules, but I can't find any documentation on how to write them. I'm assuming it's some combination of changes in the manifest.json file and writing an AMD module (like with RequireJS)
You can create your own modules using the following approach.
Create a module that exports certain variables or functions that you want to make accessible. For instance, you can have a js/myModule.js file exporting an init function:
exports.init = function() { ... };
Then, in another file, you can require it using the require function that you normally use to include modules from the Spotify API:
var sp = getSpotifyApi(),
models = sp.require("$api/models"),
views = sp.require("$api/views"),
myModule = sp.require("/js/myModule");
myModule.init();

nodejs module does not export function

I ran into an issue with my Nodejs application.
I have two different apps that are using shared library, which is located so that it is found one level up in node_modules. So i have this structure ./app1/app.js, ./app2/app.js and ./node_modules/shared.libs/index.js.
shared.libs in its turn has some other modules installed, like mongoose, redis etc. Plus some mogoose models with additional functions in them. All are exported from index.js like this:
exports.async = require('async');
exports.config = require('./config');
exports.utils = require('./lib/utils');
And then in apps i import them like this:
var libs = require('shared.libs');
var config = libs.config;
So after this code i can use config which is coming from that shared library.
This part was and is working just fine. But now i need to put additional layer on top of this library (read: provide more unified interface for both apps).
What i tried to do is to add some functions into index.js of shared library and then export the whole object with these functions. But whenever i try to call previously imported (by var libs = require('shared.libs');) object it says that libs is not defined.
What am i doing wrong here?
I generally want to keep other code the same, so i won't need to go over replacing require part everywhere, but at the same time provide additional functionality from shared library which will be available from that imported libs object.
this should definitely work:
module.exports = {
async: require('async'),
config: require('./config'),
utils: require('./lib/utils'),
foo: function () {
return 'bar';
}
};
reference like:
var libs = require('shared.libs');
console.log(libs.async);
console.log(libs.config);
console.log(libs.utils);
console.log(libs.foo);
console.log(libs.foo());
What makes me wonder is one of your comments above, that you get an error libs is not defined. That looks like you should have other unnoticed errors before.. during the the initialization of your shared.libs module..

Resources