Difference between javascript modularisation and dependency Injection - javascript

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.

Related

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.

How to migrate legacy JS app to modules

I have a large (~15k LoC) JS app (namely a NetSuite app) written in old-style all-global way. App consists of 26 files and dependencies between them are totally unclear.
The goal is to gracefully refactor the app to smaller modules. By gracefully I mean not breaking\locking the app for long time, but doing refactoring in smaller chunks, while after completing each chunk app remains usable.
An idea I have here is to concat all the JS files we have now into single-file bundle. After that some code could be extracted into modules. And the legacy code could start importing it. The modules & imports should be transpiled with webpack\whatever, while legacy code remains all-globals style. Finally all this is packed into single JS file and deployed.
My questions are
is there a better approach maybe? This sounds like a typical problem
are there any tools available to support my approach?
I gave webpack a try and I haven't managed to get what I want out of it. The export-loader and resolve-loader are no options because of amount of methods\vars that needs to be imported\exported.
Examples
Now code looks like
function someGlobalFunction() {
...
}
var myVar = 'something';
// and other 15k lines in 26 files like this
What I would ideally like to achieve is
function define(...) { /* function to define a module */ }
function require(moduleName) { /* function to import a module */ }
// block with my refactored out module definitions
define('module1', function () {
// extracted modularised code goes here
});
define('module2', function () {
// extracted modularised code goes here
});
// further down goes legacy code, which can import new modules
var myModule = require('myNewModule');
function myGlobalLegacyFunction() {
// use myModule
}
I'm following an approach similar to that outlined here: https://zirho.github.io/2016/08/13/webpack-to-legacy/
In brief:
Assuming that you can configure webpack to turn something like
export function myFunction(){...}
into a file bundle.js that a browser understands. In webpack's entry point, you can import everything from your module, and assign it to the window object:
// using namespace import to get all exported things from the file
import * as Utils from './utils'
// injecting every function exported from utils.js into global scope(window)
Object.assign(window, Utils).
Then, in your html, make sure to include the webpack output before the existing code:
<script type="text/javascript" src="bundle.js"></script>
<script type="text/javascript" src="legacy.js"></script>
Your IDE should be able to help identify clients of a method as you bring them into a module. As you move a function from legacy.js to myNiceModule.js, check to see if it still has clients that are aware of it globally - if it doesn't, then it doesn't need to be globally available.
No good answer here so far, and it would be great if the person asking the question would come back. I will pose a challenging answer saying that it cannot be done.
All module techniques end up breaking the sequential nature of execution of scripts in the document header.
All dynamically added scripts are loaded in parallel and they do not wait for one another. Since you can be certain that almost all such horrible legacy javascript code is dependent on the sequential execution, where the second script can depend on the first previous one, as soon as you load those dynamically, it can break.
If you use some module approach (either ES7 2018 modules or require.js or you own) you need to execute the code that depends on the loading having occurred in a call-back or Promise/then function block. This destroys the implicit global context, so all these spaghetti coils of global functions and var's we find in legacy javascript code files will not be defined in the global scope any more.
I have determined that only two tricks could allow a smooth transition:
Either some way to pause continuation of a script block until the import Promise is resolved.
const promise = require("dep1.js", "dep2.js", "dep3.js");
await promise;
// legacy stuff follows
or some way to revert the scope of a block inside a function explicitly into the global scope.
with(window) {
function foo() { return 123; }
var bar = 543;
}
But neither wish was granted by the javascript fairy.
In fact, I read that even the await keyword essentially just packs the rest of the statements into function to call when promise is resolved:
async function() {
... aaa makes promise ...
await promise;
... bbb ...
}
is just, I suppose, no different from
async function() {
... aaa makes promise ...
promise.then(r => {
... bbb ...
});
}
So this means, the only way to fix this is by putting legacy javascript statically in the head/script elements, and slowly moving things into modules, but continue to load them statically.
I am tinkering with my own module style:
(function(scope = {}) {
var v1 = ...;
function fn1() { ... }
var v2 = ...;
function fn2() { ... }
return ['v1', 'fn1', 'v2', 'fn2']
.reduce((r, n) => {
r[n] = eval(n);
return r;
}, scope);
})(window)
by calling this "module" function with the window object, the exported items would be put on there just as legacy code would do.
I gleaned a lot of this by using knockout.js and working with the source readable file that has everything together but in such module function calls, ultimately all features are on the "ko" object.
I hate using frameworks and "compilation" so generating the sequence of HTML tags to load them in the correct order by the topologically sorted dependency tree, while I could write myself such a thing quickly, I won't do this, because I do not want to have any "compilation" step, not even my own.
UPDATE: https://stackoverflow.com/a/33670019/7666635 gives the idea that we can just Object.assign(window, module) which is somewhat similar to my trick passing the window object into the "module" function.

AngularJS - module dependencies, naming clash

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?

How to use `require` and dependency injection, service location in JS (browser-side)?

So I've been playing with JS and browserify to allow to split my JS into smaller file chunks. It works great, however, I'm still lost on how to properly use the require function.
For me, it acts as a the Service Locator, because it looks for the proper "file" to load, and return an object. (For example in PHP, require somewhat load the file in the memory but doesn't construct).
Example:
var Foo = function() {
console.log("I'm the Foo object");
};
module.exports = Foo;
Then, to use it I'll do:
var Foo = require('foo');
and
var foo = new Foo();
Note, that the exported function is NOT constructed.
I could have done:
var foo = require('foo')();
None of those methods seems right to me (I may are wrong).
1) Is it common to do it like this? Or should exported the executed function?
Anyway, this introduction is to understand how I should play with the require function.
For example if I've a Foo object, which is depends of Bar, I've two way to do:
Service Location:
var Foo = function() {
var Bar = require('bar')();
Bar.doSomethingAwesome();
};
module.exports = Foo;
or I can do:
Dependency Injection
var Foo = function(bar) {
bar.doSomethingAwesome();
};
module.exports = Foo;
// And at a latter time
var foo = require('foo')(require('bar')); /// eurk
I obviously know that that's two different things and serve different purposes.
2) But I'm wondering what is the common/right way to do in JS, is there any commonly admitted rules?
Browserify allows you to program with modules, there's not much more to it. It's not really a DI container or service locator per se, although you can probably make it work like one.
So doing this is perfectly fine:
var Foo = require('foo');
var foo = new Foo();
In that case, it makes sense to simply place all require calls at the top of your file, similar like you would do with using in C# or import in Java. I personally wouldn't scatter require calls since don't help much with readability.
You can also export an instance which doesn't have to be newed up anymore, as long as that is appropriate for what you want to do (in that case module.exports = Foo() would lead to a singleton).
Also see this related question:
Dependency Injection with RequireJS
The rewire library provides module injection for Node.js.
A couple of solutions have been discussed and presented in this Github issue to support browserify.
Usage example from the project README:
var myModule = rewire("../lib/myModule.js");
myModule.__set__("fs", fsMock); // set private variable
Use Browserify so you can require npm packages from your browser just like node. Then you can use Weather.js or require it, then inject it in any way you like.

Closures in Typescript (Dependency Injection)

I'm getting my butt kicked trying to use TypeScript in a functional style with dependencies. Let's say I want to make a module that depends on another module.
If I wasn't using Dependency Injection it would look like this (in node).
SomeOtherModule = require("SomeOtherModule")
exports.doSomething = function() {
SomeOtherModule.blah()
}
This is how I do it with Dependency Injection
module.exports = function(SomeOtherModule) {
function doSomething() {
SomeOtherModule.blah()
}
return {doSomething: doSomething};
}
In typescript if you define a concrete class or module you can just type the functions as you export them or include them in the class. It's all right next to each other.
But since I can't define a module inside the DI function, the only way to do this that I can see would be to define an interface for the object I'm returning separately, which is annoying, because I want to have the type annotations in line with the definitions.
What's a better way to do this?
This will probably give you a good start: http://blorkfish.wordpress.com/2012/10/23/typescript-organizing-your-code-with-amd-modules-and-require-js/
I don't know if this is the best way to set it up. But I got it to work.
I ended up dropping AMD on my project, since I'm also using AngularJS and they step on each other's toes. I did keep using that same DI pattern through, so it looks like this in the end.
I'm pretty happy with it. I experimenting uses classes instead (you can get really close if you keep your module stateless and have the constructor be the injector function), but I didn't like having to use this for all the dependencies.
Also, classes don't actually buy me anything, because if I were coding to an interface I'd have to define the types twice anyway.
interface IMyService {
doSomething();
}
module.exports = function(SomeOtherModule) {
return {doSomething: doSomething}
function doSomething() {
SomeOtherModule.blah()
}
}

Categories

Resources