AngularJS - module dependencies, naming clash - javascript

I have two third-party modules, both defining a factory with the same name. Obviously, I don't have any control over the naming of those modules without resorting to a kludge.
Additionally, I have two further, internal modules, each using a different one of the two third-party modules as a dependency (as below). I was sure that I was unable to access components from a module not listed in current module's dependencies, but it turned out I was wrong.
Here even if own1 depends on thirdParty1 (which has hello defined as hello world) it's getting hi there (from thirdParty2) in controller. The same is for the other modules' pair.
Is there any way to "isolate" modules so I can only use stuff that I explicitly depend on? If not, what's the point of having modules if I can reach anything at any time (assuming main app module has it as its dependency)? Also if I have two modules with components named hello how can I tell which is gonna be used?
Here is jsbin for that http://jsbin.com/vapuye/3/edit?html,js,output
angular.module('app', ['own1', 'own2']);
//third-party modules
angular.module('thirdParty1', []).factory('hello', function () {
return 'hello world';
});
angular.module('thirdParty2', []).factory('hello', function () {
return 'hi there';
});
// "own" modules
angular.module('own1', ['thirdParty1']).controller('Own1Ctrl', function(hello) {
this.greet = hello;
});
angular.module('own2', ['thirdParty2']).controller('Own2Ctrl', function(hello) {
this.greet = hello;
});
And the result of:
<body ng-app="app">
<div ng-controller="Own1Ctrl as own1">
Own1: {{ own1.greet }}
</div>
<div ng-controller="Own2Ctrl as own2">
Own2: {{ own2.greet }}
</div>
</body>
Is :
Own1: hi there
Own2: hi there

You can request a factory of a certain module explicitly (without dependency injection):
var injector = angular.injector(['thirdParty1']);
var hello1 = injector.get('hello');
var injector = angular.injector(['thirdParty2']);
var hello2 = injector.get('hello');
You can also use this, to wrap the third party factories into own factories:
angular.module('own1', ['thirdParty1']).factory('hello1', function () {
var injector = angular.injector(['thirdParty1']);
var hello = injector.get('hello');
return hello;
});
angular.module('own2', ['thirdParty2']).factory('hello2', function () {
var injector = angular.injector(['thirdParty2']);
var hello = injector.get('hello');
return hello;
});
This allows you to use hello1 and hello2 in all other parts of your application.

Since there is no built-in name spacing of modules (or components of modules) the best way to achieve your goal is to use a unique naming convention for your modules. Most libraries for angular do this, and then you should be good to go.
Besides encapsulating your applications behavior, modules help testing and mocking your application.
I dont think it is possible for angular to differentiate between two components that are named the same (I think this changes with angular 2). And I might argue that two components that are named the same might do the same and you should look why you need both?

Related

Use javascript module inside an object

I'm asking a question:
Imagine I have a javascript module (using revealing module pattern) and I want to use it inside some prototype methods of an object. What will be the best way on your opinion to do it?
I have currently two ideas in mind:
- Pass the global module to the constructor of the object and keep it in an object property (this.myModule...)
- Use the module from the prototype method directly as global variable
Let me explain you the situation with a small example:
I have file1.js containing the module :
var myModule = (function(){
function doSomething(){...}
return {doSomething: doSomething};
})()
To use this module, which of the two options is the best for you? Or maybe you have a better option to propose?
I can't use requirejs nor any libraries to ease the modularity and dependency management of my application. Also, I can't change the existing architecture.
// Option 1
function myObject(myModule){
...
this._myModule = myModule;
}
myObject.prototype.doAnotherThing = function(){
...
this._myModule.doSomething();
}
var test = new myObject(myModule);
// Option 2
function myObject(){
...
}
myObject.prototype.doAnotherThing = function(){
...
myModule.doSomething();
}
var test = new myObject();
I'm really interested by having your point of view.
Thanks a lot in advance,
Remi

What happens when using "require()" in Node.js?

Sorry if this is a dumb question but I'm new to JavaScript/Node.js. This code below eludes me and I've done a fair bit of research... My questions below are more specifically related to instantiation.
I don't understand this:
var myApp = require('express');
var myCode = myApp();
How I see that it should be for instantiation:
var myApp = new Express();
var myCode = myApp.insideExpress();
How anonymous function expressions are:
var myApp = function();
var myCode = myApp();
If the word "require" acts as a sort of anonymous function expression, then how are things instantiated in the background? This is very important for making proper patterns, no?
My questions are:
What's happening in the background for the first example, is JavaScript/Node.js instantiating/constructing or not at all?
Are people who do this just creating bad patterns? Why should I use this pattern?
If no instantiation, then why not?
Thanks in advance
const myVar = require("someModule") loads a module from the file system, runs the module initialization code and assigns the module exports to your variable. The module loading sub-system maintains a cache so if it was previously loaded, it is not loaded or run again, the module's exports are just retrieved from the cache and assigned to your variable.
So, when you do this:
var myApp = require('express'); // load express module, assigns exports to myApp
var myCode = myApp(); // calls myApp() function and assigns result to myCode
The first line loads the express module and assigns the exports from that module to your myApp variable. In this particular case (it varies from module to module), the exports from the Express module is a function. So, after that first line of code, myApp contains a function which happens to be a factory function for creating new Express app objects.
The second line of code calls that factory function which returns a new Express app object.
A module can export anything it wants. In the case above, it exported a function, but it's also common to export an object that has a whole bunch of properties which you can then access. You can also export a constructor in which case the caller would then use new with the constructor to create a new object from it.
In the Express module, it did not export a constructor (which is why you don't use new with it). Instead, it decided to export a factory function that, when called, creates and returns a new object. This is just a design decision that can go either way depending upon the needs of the module and the whims of the code writer.
I can't really tell what you're asking here with this code:
var myApp = new Express(); // the express module does not export a constructor
var myCode = myApp.insideExpress();
This would work only if Express was a constructor function. The express module itself does not choose to export a constructor function so this is not how you use the express module. It could have been designed this way, but it was not. They simply made a different design decision when designing it.
For this other case you show:
var myApp = function();
var myCode = myApp();
That first line of code doesn't make any sense. Perhaps you meant for it to have a body to the function:
var myApp = function() { some code here };
var myCode = myApp();
In that case, myApp is being assigned a function expression (which is just one of several ways to declare a function). It's similar, though not exactly the same as:
function myApp() { some code here }
If the word "require" acts as a sort of anonymous function expression, then how are things instantiated in the background? This is very important for making proper patterns, no?
require('someModule) loads a module and returns the exports from the module which can be any Javascript data type. It doesn't act as an anonymous function in any way. require() is an actual function and you are just calling it and getting back its return value. Remember that in Javascript, you can return any data type from a function, include return another function (which is what the express module does).
What's happening in the background for the first example, is JavaScript/Node.js instantiating/constructing or not at all?
No instantiating or constructing. It's just loading a module, running its initialization code and return its exports. Some objects are created by the module loading system that are used for its own housekeeping, but the module itself is just initializing itself and then deciding what it wants to export.
Are people who do this just creating bad patterns? Why should I use this pattern?
Modules are highly useful in node.js development and it is considered good design to use proper module design. There are many, many advantages to good module design such as easier code maintenance, easier code testing, easier code reuse, easier code sharing, no need to create globals in order to share code, etc...
If no instantiation, then why not?
A module decides what it wants to export. It can, in its initialization code, create an instance of an object and export it. It can export a factory function that creates an instance of an object when called. It can export a constructor directly that lets the caller use new with it to create an instance of an object. It can export a utility function that just carries out some function and doesn't create any objects. It can export just data. It can export a plain object with multiple properties on it that have all sorts of possible uses. The possibilities are endless and it entirely depends upon what the purpose is of the module and what it wishes to share with the other module that loaded it.
It's just loading a library or a module into your script. It is not instantiating a new object. It's just making the loaded module's functions etc available to your current script. Here is a good writeup that I found,
http://fredkschott.com/post/2014/06/require-and-the-module-system/
I hope that helps answer your question.

Difference between javascript modularisation and dependency Injection

What 's the difference with the modularisation of a javascript code (with browserify by example) and the dependency injection?
Are they synonymes? Are the two going together? Or Am I missing some point?
Modularisation refers to breaking code into individual, independent "packages".
Dependency injection refers to not hardcoding references to other modules.
As a practical example, you can write modules which are not using dependency injection:
import { Foo } from 'foo';
export function Bar() {
return Foo.baz();
}
Here you have two modules, but this module imports a specific other hardcoded module.
The same module written using dependency injection:
export function Bar(foo) {
return foo.baz();
}
Then somebody else can use this as:
import { Foo } from 'foo';
import { Bar } from 'bar';
Bar(Foo());
You inject the Foo dependency at call time, instead of hardcoding the dependency.
You can refer this article:
Modules are code fragments that implement certain functionality and
are written by using specific techniques. There is no out-of-the box
modularization scheme in the JavaScript language. The upcoming
ECMAScript 6 specification tends to resolve this by introducing the
module concept in the JavaScript language itself. This is the future.
and Dependency injection in JavaScript
The goal
Let's say that we have two modules. The first one is a service which
makes Ajax requests and the second one is a router.
var service = function() {
return { name: 'Service' };
}
var router = function() {
return { name: 'Router' };
}
We have another function which needs these modules.
var doSomething = function(other) {
var s = service();
var r = router();
};
And to make the things a little bit more interesting the function
needs to accept one more parameter. Sure, we could use the above code,
but that's not really flexible. What if we want to use ServiceXML or
ServiceJSON. Or what if we want to mockup some of the modules for
testing purposes. We can't just edit the body of the function. The
first thing which we all come up with is to pass the dependencies as
parameters to the function. I.e.:
var doSomething = function(service, router, other) {
var s = service();
var r = router();
};
By doing this we are passing the exact implementation of the module
which we want. However this brings a new problem. Imagine if we have
doSomething all over our code. What will happen if we need a third
dependency. We can't edit all the function's calls. So, we need an
instrument which will do that for us. That's what dependency injectors
are trying to solve. Let's write down few goals which we want to
achieve:
we should be able to register dependencies
the injector should accept a function and should return a function which somehow gets the needed resources
we should not write a lot, we need short and nice syntax
the injector should keep the scope of the passed function
the passed function should be able to accept custom arguments, not only the described dependencies
A nice list isn't it. Let's dive in.

Combining Angular Services with NodeJS Modules

Supposing I have a library written in Javascript to be used in a MEAN stack application.
I wish to use my library both from NodeJS and within Angular.
To remain idiomatic I would like the library to appear as a Module inside node and as a Service within Angular.
the only way I can think to do this is to do something like:
var myLibrary = function(){
var myLib = {};
myLib.myFunc1 = function() {
//Do some cool stuff
};
return myLib;
};
if (typeof module !== 'undefined') {
module.exports = myLibrary();
} else{
var app = angular.module('myApp.services', []);
app.factory('myLibrary',myLibrary);
}
This will work, but it has at least two significant limitations:
The namespace is polluted with the variable "myLibrary"
If within the library I want to use other node modules or Angular services then I can't
I would like to know if anyone knows of a better solution, or if I should give up on using Angular services and use one of the libraries that allows client side Node module functionality.
Having done a bit of searching about this looks like the best solution:
https://gist.github.com/sevcsik/9207267

How should I think about my JavaScript application namespaces?

I'm building an app that has a single global namespace like so:
var myApp = {};
I then have a bunch of different reusable "modules" comprised of models, views and controllers.
//Bar chart module code
org.example.chart.bar.module
org.example.chart.bar.model
org.example.chart.bar.view
org.example.chart.bar.controller
I also have a big dataSource singleton and a dataManager for loading data to the dataSource:
org.example.data.dataSource
org.example.data.dataManager //populates the dataSource with CSV data
And finally translation strings and settings that should be available across the app:
org.example.static.translations
org.example.static.settings
How would you (re-)organize this so that I have easy access to the application level singletons (such as dataSource, dataManager, translations etc.) and can easily instantiate reusable modules that get scoped under the current application instance?
(Would you for example, already from the beginning, use the same namespace for your "classes" and your app? Or would you perhaps make references like so: myApp.translations = org.example.static.translations?)
No we don't namespace. We write modular code and we use module loaders.
Example of a module loader would be require.js or browserify or seajs.
And an example module would be something like:
(function () {
var jQuery = require("jQuery");
var chart = require("chart");
...
define("moduleName", moduleObject);
})();
There is nothing stopping you adding another name to the class. For example.
org.ds = org.example.data.dataSource;
then you can call
org.ds.getDatasource();
instead of
org.example.data.dataSource.getDatasource();
but both will still work.
EDIT: You could also create other simpler functions that call it taking it out of the oo structure
var dataSource = function () { return org.example.data.dataSource.getDatasource(); };
Consider using something like RequireJS for organizing your modules.
Some excellent resources from Addy Osmani :
http://addyosmani.com/largescalejavascript/
http://addyosmani.com/blog/large-scale-jquery/
http://addyosmani.com/resources/essentialjsdesignpatterns/book/

Categories

Resources