Building a Javascript utility library with AMD compatibility - javascript

My goal is to build a set of javascript tools for functional programming, to be used by our company's web developers. I've tried giving a look at the Underscore annotated source but I'm new with RequireJS and AMD, so it's a lot confusing for me.
To start I just want to have a variable that gets available when my library is imported.
In this case booleans is a module that has functions returning boolean values. For example: _myLib.booleans.isDefined(var) - returns true is var is a defined variable.
No I have RequireJS setup, but how do I make a variable available for usage?
My main.js:
requirejs(['app/booleans'], function (booleans) {
var _myLib = {};
_myLib.booleans = booleans;
return _myLib;
});
Of course _myLib is undefined, I suppose it's because it is not assigned to any scope.
Can anyone give me some lights on building this library?
Thanks in advance.

If you want to produce a proper AMD library, you need to set it so that it calls define to define itself as an AMD module.
define(['app/booleans'], function (booleans) {
var _myLib = {};
_myLib.booleans = booleans;
return _myLib;
});
If you called your file myLib.js and provided a good configuration to RequireJS for it to find it, then, when you want to use it, you can do:
require(["myLib"], function (myLib) {
myLib.booleans.isDefined("moo");
});
Or in another module:
define(["myLib"], function (myLib) {
myLib.booleans.isDefined("blah");
});

Related

Include an object defined outside Angular ecosystem into a factory

We're having an argument, which I hope you guys will help resolve.
Say I have a simple factory defined like this:
angular.module('myModule', [])
.factory('Fact', function() {
var Fact = function() {
var that = {};
that.var1 = [];
that.var2 = [];
return that;
};
var fact = {
get: function() {
return Fact();
}
};
return fact;
});
I found out that this code will be working if I write it like this:
angular.module('myModule', [])
.factory('Fact', function() {
var fact = {
get: function() {
return Fact();
}
};
return fact;
});
var Fact = function() {
var that = {};
that.var1 = [];
that.var2 = [];
return that;
};
Namely, I can take this code of the object Fact and put it in some other plain .js file, include it before the Angular one (in index.html file) and this "would work".
However, I'm trying to resolve an argument that this approach is not good (well, not an Angular approach at that) because then this Fact is "laying around on the global scope", which is not good.
In which circumstances would you say that this is/isn't a good solution?
Is there a way to include a "nonAngular" code (simple JavaScript code written in some .js file) into the Angular factory?
Between factories, services, providers, constants and values, there's not really a good reason to have any code outside of Angular's constructs unless it's third party code.
If it is, you won't have control over the way that the library, framework, etc registers itself. It might use the global scope, alternatively, it might provide a module export.
Where possible, the cleanest and safest way to include third party code inside Angular is with a build-step using a module bundler.
For instance, I want to use the hypothetical package foojs from inside Angular using browserify:
Install the package with npm
npm install --save foojs
Then use it like this.
var foojs = require('foojs');
var app = angular.app('myapp')
app.service('myservice', function() {
// here we can use foojs safely
});
You can also achieve similar things with WebPack.
The reason this is safer is because after the build step, all the modules will be wrapped inside a function that protects the global scope.
If you aren't able to use a module bundler, then the only option is to use the global scope and allow the third party code to bind onto the window object.

How to use multi-function modules with requireJS

I'm a Java programmer who's trying to convert some Applets into JavaScript. I have a case with lots of small Java classes, which have a cohesive design that I'd like to keep if possible in JavaScript. RequireJS seems like a great way to keep it modular.
However, all the tutorials for requireJS I've seen treat a module as only having a single function, which only works for a couple of my Java classes. For example, this tutorial defines the module purchase.js as having a single function purchaseProduct():
define(["credits","products"], function(credits,products) {
console.log("Function : purchaseProduct");
return {
purchaseProduct: function() {
var credit = credits.getCredits();
if(credit > 0){
products.reserveProduct();
return true;
}
return false;
}
}
});
Is there a way to allow more than one function per module in this way? In my head, a module is not necessarily just one function.
Or is RequireJS the wrong tree to be barking up for preserving my modular design from Java?
Edit
I found a much more useful set of examples for transitioning from Java to JS with requireJS at https://gist.github.com/jonnyreeves/2474026 and https://github.com/volojs/create-template
Yes, there's a way and it's very simple.
See, what you're returning (the module) is simply an object. In your code, this object has 1 property (purchaseProduct), but it can have as many as you'd like. And they don't all have to be functions either:
return {
purchaseProduct: function () {/*...*/},
returnProduct: function () {/*...*/},
discountLevel: 0.25
};
Just add more functions to the object you return:
return {
purchaseProduct: function() {
// ...
},
somethingElse: function () {
// ...
}
}
If you return this as the value of your module, you'll have a module that exports two functions purchaseProduct and somethingElse.

Sharing JS files across application

We're developing a mobile application and we're trying to figure out the best approach to share javascript functions across the application.
At the moment we have individual files that simply have:
var LIB = {
URL: "http://localhost/service",
connect: function() {
// connect to server
$.ajax({ url: this.URL }); // etc etc
// call a private function?
this._somethingElse();
},
_somethingElse: function() {
// do something else
}
};
Then we simply call things like:
LIB.connect(); or LIB.disconnect();
across any file.
This also gives us access to LIB.URL as well.
My question is whether this approach is the best?
I've seen people use the following approach as well, but to what benefit?
var LIB = function () {
this.URL = "http://localhost/service";
this.connect = function () {
var myself = this;
// connect to server
$.ajax({ url: this.URL }); // etc etc
// call a private function?
myself._somethingElse(); // best way to invoke a private function?
};
this._somethingElse = function () {
// do something else
};
};
This requires the following:
var lib = new LIB();
lib.connect();
EDIT:
I've also seen the following:
window.lib = (function () {
function Library () {
}
var lib = {
connect: function () {
// connect to server
}
};
return lib;
}());
I'm slightly confused with all these options.
It just depends on which you like better. I (on a personal level) prefer the former, but to each his own. The latter does have the disadvantage of requiring to either remember to declare the new before using it, or having to keep track of a already created one.
Additionally, on a technical level the first one should get slightly (as in, barely noticeable) performance, as you don't have to compute a new function.
Edit Yes, the first way is definitely the fastest.
I highly recommend going with a module system. Until ES6 comes along (http://wiki.ecmascript.org/doku.php?id=harmony:modules), you will have to use a 3rd party library in order to do this.
Each object/class/util/etc is a module.
A module exports a public api, whereas consuming modules import other modules by declaring their dependencies.
Two "standards" that exist: AMD and CommonJS. In the browser, a library like RequireJS, which uses the AMD standard, is very popular. I recommend checking out their site first: http://requirejs.org/ and see their examples.
The main advantage here is that you only expose the public api, which allows you to create a sandbox of your functionality. It's also more explicit as it's really easy to see what your module depends on, instead of relying on global objects.
There are several different approaches to structuring JavaScript code for re-usability. You can research these and decide which is best. Me personally, I have used the second approach that you've outlined. However, I separate my code into sections and actually adhere to an MVVM structure. So for instance, I have a name space called models and view models. Each of my js files begins with:
window.[APP NAME].Models.[CLASS/MODULE NAME] or window.[APP NAME].Models.[CLASS/MODULE NAME]
So, let's say I have a namespace called mynamespace and I have a module/class called myclass. My js file would begin with:
window.MYNAMESPACE = window.MYNAMESPACE || {};
window.MYNAMESPACE.ViewModels = window.MYNAMESPACE.ViewModels || {};
window.MYNAMESPACE.ViewModels.MyClass = function () {
// a public function
this.func1 = function () {
};
// a private function
function func2() {
}
};
I would then consume that class by calling:
var myClassModel = new window.MYNAMESPACE.ViewModels.MyClass();
myClassModel.func1();
This gives you some nice encapsulation of your code. Some of the other patterns you can research/google are: Prototype Pattern, Module Pattern, Revealing Module Pattern, and the Revealing Prototype Pattern.
I hope that helps but if you have any questions on what I've just said, feel free to comment on this post.

NodeJS - How to reference function in one require() file from another require() file?

This is my second weekend playing with Node, so this is a bit newbie.
I have a js file full of common utilities that provide stuff that JavaScript doesn't. Severely clipped, it looks like this:
module.exports = {
Round: function(num, dec) {
return Math.round(num * Math.pow(10,dec)) / Math.pow(10,dec);
}
};
Many other custom code modules - also included via require() statements - need to call the utility functions. They make calls like this:
module.exports = {
Init: function(pie) {
// does lots of other stuff, but now needs to round a number
// using the custom rounding fn provided in the common util code
console.log(util.Round(pie, 2)); // ReferenceError: util is not defined
}
};
The node.js file that is actually run is very simple (well, for this example). It just require()'s in the code and kicks off the custom code's Init() fn, like this:
var util = require("./utilities.js");
var customCode = require("./programCode.js");
customCode.Init(Math.PI);
Well, this doesn't work, I get a "ReferenceError: util is not defined" coming from the customCode. I know everything in each required file is "private" and this is why the error is occuring, but I also know that the variable holding the utility code object has GOT to be stored somewhere, perhaps hanging off of global?
I searched through global but didn't see any reference to utils in there. I was thinking of using something like global.utils.Round in the custom code.
So the question is, given that the utility code could be referred to as anything really (var u, util, or utility), how in heck can I organize this so that other code modules can see these utilities?
There are at least two ways to solve this:
If you need something from another module in a file, just require it. That's the easy one.
Provide something which actually builds the module for you. I will explain this in a second.
However, your current approach won't work as the node.js module system doesn't provide globals as you might expect them from other languages. Except for the things exported with module.exports you get nothing from the required module, and the required module doesn't know anything of the requiree's environment.
Just require it
To avoid the gap mentioned above, you need to require the other module beforehand:
// -- file: ./programCode.js
var util = require(...);
module.exports = {
Init: function(pie) {
console.log(util.Round(pie, 2));
}
};
requires are cached, so don't think too much about performance at this point.
Keep it flexible
In this case you don't directly export the contents of your module. Instead, you provide a constructor that will create the actual content. This enables you to give some additional arguments, for example another version of your utility library:
// -- file: ./programCode.js
module.exports = {
create: function(util){
return {
Init: function(pie) {
console.log(util.Round(pie, 2));
}
}
}
};
// --- other file
var util = require(...);
var myModule = require('./module').create(util);
As you can see this will create a new object when you call create. As such it will consume more memory as the first approach. Thus I recommend you to just require() things.

How can a Javascript module defined with AMD be extended?

First a bit of history, we have an engine which is made up of many javascript files which are essentially modules. These modules return a single class that are assigned to the global scope, although under a specified namespace.
The engine itself is used to display eLearning content, with each different eLearning course requiring slightly different needs, which is where we include javascript files into the page based on the necessary functionality. (There is only one entry page).
I've been trying to weigh up if it's worth changing to AMD, require.js and r.js or if it's better to stay with our current system which includes everything required on the page and minimises it into one script.
One of my biggest problems with going to AMD would be that it seems to be harder to extend a class easily. For example, sometimes we have to adjust the behaviour of the original class slightly. So we add another script include on the page that extends the original class by copying the original prototype, execute the original function that's being overridden with apply and then do whatever additional code is required.
Can you extend an AMD module without adapting the original file? Or am I missing the point and we're best staying with what we're doing at the moment?
I recently started a project using RequireJS, and the method I use to extend underscore boils down to something like this:
Relevant Directory Structure:
/scripts
/scripts/underscore.js
/scripts/base/underscore.js
The real underscore library goes to /scripts/base/underscore.js.
My extensions go in /scripts/underscore.js.
The code in /scripts/underscore.js looks like this:
define(['./base/underscore'], function (_) {
'use strict';
var exports = {};
// add new underscore methods to exports
_.mixin(exports); // underscore's method for adding methods to itself
return _; // return the same object as returned from the underscore module
});
For a normal extension, it could look more like this:
define(['underscore', './base/SomeClass'], function (_, SomeClass) {
'use strict';
_.extend(SomeClass.prototype, {
someMethod: function (someValue) {
return this.somethingOrOther(someValue * 5);
}
});
return SomeClass;
});
Note on underscore: Elsewhere I used the RequireJS shim-config to get underscore to load as an AMD module, but that should have no effect on this process with non-shimmed AMD modules.
You can have modules that contain your constructor functions. when these modules get included, they are ready for use. then you can create objects out of them afterwards.
example in require:
//construction.js
define(function(){
//expose a constructor function
return function(){
this....
}
});
//then in foo.js
define([construction],function(Construction){
var newObj = new Construction; //one object using constructor
});
//then in bar.js
define([construction],function(Construction){
//play with Construction's prototype here then use it
var newObj = new Construction;
});

Categories