Javascript modularity - javascript

I am studying the possibility of building Javascript applications in the Java / OSGi modularity style. I am sure I will not manage to actually reach the kind of flexibility that OSGi provides, but I would need to get to at least the following list:
split javascript code as modules, each module would lay in its own git repository
ideally, as little as possible dependencies between modules and definitely no circular dependencies between modules
have 2 or more "main" javascript applications that will use the modules described above
If I will manage to setup the above then I will probably want to be able to organize modules as layers like: core layer with several modules, ui layer, applications layer.
Are there any javascript libraries that help building the above setup? Is something like this possible in javascript?
Note: When I say javascript, I don't actually mean plain javascript. I am going to use a library like ExtJS or jQuery for the UI part at least.

Checkout RequireJS an implementation of Asynchronous Module Definition

Since this question was answered javascript now has native implementaitons of classes and modules that can give you what you need without having to use a 3rd party library.
js modules alow you to have a module or code and import methods (or everything) from it (a bit like in python and ruby)
// utilities.js
function something () {
// some great code
}
export function util() {
something();
}
//import a method
import {util} from "utilities.js";
// or import everything
import "utilities.js";
you can find more on es6 modules here
js classes are syntax suger over prototypal structure in js and can be used the same way as in more trandtional OOP languages
class MyClass {
constructor() {
// constructor code
}
add() {
// some method
}
}
var myObject = new MyClass();
You can find out more about es6 classes here

Related

Can I use Laravel's "Service Container pattern" in JavaScript?

So, let's say that I am building a single-page app in JavaScript. For now I do not have a persistence layer in my app but I still need to write the code.
class App {
handleClick(event) {
User.saveToFile(event.target.value);
}
render() {
return 'Some template...';
}
}
So, I create my concrete user class. But for now just save it to the local storage.
class User {
constructor(localStorageHelper) {
this.localStorageHelper = localStorageHelper;
}
save(name) {
this.localStorageHelper.users.save({
name
});
}
}
When the database is ready, I need to switch to the database. If I was in an object-oriented language I can simply create an interface and use polymorphism or repository pattern to solve this problem.
I was wondering what if I create an app container to contain all of the concrete implementations. For example I can create a bindings.js file like the following:
import UserPersister from './Repos/Db/User'
import PostPersister from './Repos/File/Post'
const Bindings = {
'UserPersister': UserPersister,
'PostPersister': PostPersister
};
So now in my App.js file. I can do something like:
let User = Container.make('UserPersister');
class App {
handleClick(event) {
User.saveToFile(event.target.value);
}
render() {
return 'Some template...';
}
}
Now I can easily switch between different implementations by just changing them in bindings.js. If you've worked a little bit with Laravel this should seem familiar (except for the service providers of course).
This sounds OK to me but I am not sure if it is ACTUALLY OK to do this sort of thing in JavaScript. What advice would you give based on your experience with JavaScript?
If you want to reproduce laravel's pattern - that can be hard - but I can suggest you two technologies that can helps you with it. When you combained them you can easily implement quite similar code conception.
1 TypeScript
In fact you're using it in above code. It's a kind of JavaScript wrapper in which you can write a code similar to Java solutions. You have access here to polymorphism, inheritance and encapsulation like in typical PHP OOP. This can speed up your work a bit and it's pure and it's uses ECMAScript 2015.
2 AngularJS
The large JS Framework which is very strong and have big community. This one privides you for example injection service (like Laravel's IoC) which will automaticcly resolve all your dependencies. You can create easily repositories using $resources which is ajax wrapper for REST API requests. There are service providers that works greate on application load. And the best is that - yo can build one-page-application with Angular. It have many other advanteges. There is stable version 1 and unstable verison 2 which is developed in TypeScript.
With these two tools you can build awesome stuff for the frontend (client side). If you want more tools here it is:
PuppetJS - server side generating client side JS scripts (one implementation fort both sides!).
React - great library based on components

Building AMD code for Node and browser

I have been searching around various repositories and blogs around the web and can't seem to find what I am looking for.
The Problem
When building code via AMD using something like RequireJS you can expect to set up your modules like so:
Module one:
define(['a'], function () {
return {
methodOne: function () {
return 'something';
}
}
});
Module two:
define(['b'], function () {
return {
methodTwo: function () {
return 'something';
}
}
});
This helps a lot with building a project. It helps separates concerns out into multiple files rather than having one large one.
But how do you optimize this into one file? I would assume that you would use some sort of build tool and come out with something like:
define(function () {
return {
/* other dependency functions */
methodOne: function () {
return 'something';
},
methodTwo: function () {
return 'something';
}
}
});
For AMD environments. This essentially would just combine all of the modules together into one file.
So I have a few questions:
How would I optimize my AMD code correctly in a build like I've
mentioned above? Is this even the best approach?
How do I make my code portable for AMD, Node and the browser??
What I've Tried/Found
It looks like RequireJS has it's own build tool (http://requirejs.org/docs/optimization.html) to do something like this. After going through the documentation and trying out the build tool for myself, I've found that it just combines all of the defines into one file. Am I missing something here? This isn't very useful.
The UMD pattern seems to be what normalizes your code to work with AMD, Node and the browser (http://know.cujojs.com/tutorials/modules/authoring-umd-modules, https://github.com/umdjs/umd). Does this mean that every AMD file I am using I have to convert to UMD? This seems like a headache.
I have stumbled upon uRequire (http://urequire.org/) which seems like it's the answer I am looking for. Being able to build code into UMD from AMD or CommonJS pattern.
This is an issue that has been eluding me. UMD looks cool, but it seems like the hangup there is making your code available for the browser easily.
Any help with this would be much appreciated.
Regarding the RequireJS optimizer usefulness, I use the RequireJS rjs optimizer for over a year to create bundles of modules that have to come together (and synchronously).
This is being very helpful because I am saving on the number of requests and also on the asynchronous overhead where require has to figure out all the dependency tree, because that simply doesn't need to happen.
For instance, if you think in terms of broader modules, a.k.a. sub-applications or even features, you can just give another lecture to your app where instead of loading 40+ requirejs modules you would then be loading just 5 sub-apps/features, and each block of them would come altogether and synchronously.
Regarding UMD and uRequire, I suggest having a look also on https://github.com/systemjs/systemjs - it seems to be a clever approach. Yet uRequire seems to be very nice as well.

What javascript module api does duojs use?

I'm using duojs, which is a front-end webdevelopment tool not unlike browserify or component. It allows you to import css and js straight from the file itself, without any external package manifests.
I'm trying to understand how to write my js so it works well with duojs, but am not sure what kind of architecture it uses for its module definitions. I've looked for it in the documentation, but couldn't find it there. From what I can tell it looks like the duojs compiler wraps all components in commonjs style wrappers:
See for example this compiled js file on their repo (below is a snippet):
/**
* Return newest require.
*/
return require;
})({
1: [function(require, module, exports) {
/**
* Module Dependencies
*/
var Highlight = require('segmentio/highlight');
/**
* Code highlighting.
*/
new Highlight()
.use(require('segmentio/highlight-javascript'))
.use(require('segmentio/highlight-xml'))
.use(require('segmentio/highlight-css'))
.use(require('segmentio/highlight-json'))
.all();
Can anyone tell from the code what kind of js module api is being used here? To me this looks like a commonjs style module definition, but I'm not sure, it might be node as well.
Duo uses duo-pack to build it's javascript. duo-pack's javascript packer is very similar to browserify's browser-pack. duo-pack differs in that it also supports packing CSS.
It's packed in such a way that the entry file will get executed immediately when the script is included.
As I understand it, and from what I've found, it doesn't use another API structure. Check out https://github.com/duojs/duo/blob/master/docs/api.md for information about how-to use the DuoJS API.
To my eye, it appears that it is entirely built from scratch, but I'm not an expert in any form of JavaScript.

Import existing library with JavaScript ES6 Modules

How can an existing library be loaded and run using JavaScript's ES6 Modules?
For example, suppose I need to load an existing polyfill:
import {poly} from "thirdParty/poly";
How can I run the imported poly script and load its properties into the current namespace without changing the source?
Here are two practical problems to help clarify the problem I'm trying to solve:
I have a script called rafPolyfill.js which is a polyfill for window.requestAnimationFrame. I need to import it into the global scope and run it immediately as soon as it loads. This is easy to do with a <script> tag:
It runs and loads itself into the global scope. How is can this be done using ES6 modules?
I have another script called Font.js which is a pre-loader for fonts. It let's you create new font object like this:
var font = new Font();
I used Font.js by loading it with a script tag, like this:
<script src="Font.js"><script>
Without accessing, changing, or understanding the source code of this script, how is it possible to use ES6 modules to load and use the in the same way that I would with a <script> tag? I just need these scripts to run when they're loaded and take care of themselves.
A possible solution might be using the module Loader API:
http://wiki.ecmascript.org/doku.php?id=harmony:module_loaders
This document describes global binding of the System loader, but I'm afraid I don't have the vocabulary to fully understand what it's trying to explain. Any help in decoding this document would be greatly appreciated!
This answer is: "No, based on the ES6 spec it's not possible to load and run a global script the same way you can with a script tag."
But there is a solution: SystemJS
https://github.com/systemjs/systemjs
It's a universal module loader for ES6 modules, AMD modules, and global scripts (anything you load with the <script> tag)
Does this or something close to this work for you?
var stuffFromPoly = import "thirdParty/poly"
Then you would call methods off of the object stored in stuffFromPoly.
If that's not quite it, could you expand your question a bit, I'm trying to guess at exactly what you mean and I may be a bit off.
Quick note post-'your update':
Are you opposed to using https://www.npmjs.org/package/es6-module-loader ? Or does that not quite solve the problem?
From the readme:
The new ES6 module specification defines a module system in JavaScript using import and export syntax. For dynamically loading modules, a dynamic module loader factory is also included in the specification (new Loader).
A separate browser specification defines a dynamic ES6 module loader loader for the browser, window.System, as well as a tag for using modules.
This polyfill implements the Loader and Module globals, exactly as specified in the 2013-12-02 ES6 Module Specification Draft and the System browser loader exactly as suggested in the sample implementation.

Approaches to modular client-side Javascript without namespace pollution

I'm writing client-side code and would like to write multiple, modular JS files that can interact while preventing global namespace pollution.
index.html
<script src="util.js"></script>
<script src="index.js"></script>
util.js
(function() {
var helper() {
// Performs some useful utility operation
}
});
index.js
(function () {
console.log("Loaded index.js script");
helper();
console.log("Done with execution.");
})
This code nicely keeps utility functions in a separate file and does not pollute the global namespace. However, the helper utility function will not be executed because 'helper' exists inside a separate anonymous function namespace.
One alternative approach involves placing all JS code inside one file or using a single variable in the global namespace like so:
var util_ns = {
helper: function() {
// Performs some useful utility operation.
},
etc.
}
Both these approaches have cons in terms of modularity and clean namespacing.
I'm used to working (server-side) in Node.js land where I can 'require' one Javascript file inside another, effectively injecting the util.js bindings into the index.js namespace.
I'd like to do something similar here (but client-side) that would allow code to be written in separate modular files while not creating any variables in the global namespace while allowing access to other modules (i.e. like a utility module).
Is this doable in a simple way (without libraries, etc)?
If not, in the realm of making client-side JS behave more like Node and npm, I'm aware of the existence of requireJS, browserify, AMD, and commonJS standardization attempts. However, I'm not sure of the pros and cons and actual usage of each.
I would strongly recommend you to go ahead with RequireJS.
The modules support approach (without requires/dependencies):
// moduleA.js
var MyApplication = (function(app) {
app.util = app.util || {};
app.util.hypotenuse = function(a, b) {
return Math.sqrt(a * a + b * b);
};
return app;
})(MyApplication || {});
// ----------
// moduleB.js
var MyApplication = (function(app) {
app.util = app.util || {};
app.util.area = function(a, b) {
return a * b / 2;
};
return app;
})(MyApplication || {});
// ----------
// index.js - here you have to include both moduleA and moduleB manually
// or write some loader
var a = 3,
b = 4;
console.log('Hypotenuse: ', MyApplication.util.hypotenuse(a, b));
console.log('Area: ', MyApplication.util.area(a, b));
Here you're creating only one global variable (namespace) MyApplication, all other stuff is "nested" into it.
Fiddle - http://jsfiddle.net/f0t0n/hmbb7/
**One more approach that I used earlier in my projects - https://gist.github.com/4133310
But anyway I threw out all that stuff when started to use RequireJS.*
You should check out browserify, which will process a modular JavaScript project into a single file. You can use require in it as you do in node.
It even gives a bunch of the node.js libs like url, http and crypto.
ADDITION: In my opinion, the pro of browserify is that it is simply to use and requires no own code - you can even use your already written node.js code with it. There's no boilerplate code or code change necessary at all, and it's as CommonJS-compliant as node.js is. It outputs a single .js that allows you to use require in your website code, too.
There are two cons to this, IMHO: First is that two files that were compiled by browserify can override their require functions if they are included in the same website code, so you have to be careful there. Another is of course you have to run browserify every time to make change to the code. And of course, the module system code is always part of your compiled file.
I strongly suggest you try a build tool.
Build tools will allow you to have different files (even in different folders) when developing, and concatenating them at the end for debugging, testing or production. Even better, you won't need to add a library to your project, the build tool resides in different files and are not included in your release version.
I use GruntJS, and basically it works like this. Suppose you have your util.js and index.js (which needs the helper object to be defined), both inside a js directory. You can develop both separately, and then concatenate both to an app.js file in the dist directory that will be loaded by your html. In Grunt you can specify something like:
concat: {
app: {
src: ['js/util.js', 'js/index.js'],
dest: 'dist/app.js'
}
}
Which will automatically create the concatenation of the files. Additionally, you can minify them, lint them, and make any process you want to them too. You can also have them in completely different directories and still end up with one file packaged with your code in the right order. You can even trigger the process every time you save a file to save time.
At the end, from HTML, you would only have to reference one file:
<script src="dist/app.js"></script>
Adding a file that resides in a different directory is very easy:
concat: {
app: {
src: ['js/util.js', 'js/index.js', 'js/helpers/date/whatever.js'],
dest: 'dist/app.js'
}
}
And your html will still only reference one file.
Some other available tools that do the same are Brunch and Yeoman.
-------- EDIT -----------
Require JS (and some alternatives, such as Head JS) is a very popular AMD (Asynchronous Module Definition) which allows to simply specify dependencies. A build tool (e.g., Grunt) on the other hand, allows managing files and adding more functionalities without relying on an external library. On some occasions you can even use both.
I think having the file dependencies / directory issues / build process separated from your code is the way to go. With build tools you have a clear view of your code and a completely separate place where you specify what to do with the files. It also provides a very scalable architecture, because it can work through structure changes or future needs (such as including LESS or CoffeeScript files).
One last point, having a single file in production also means less HTTP overhead. Remember that minimizing the number of calls to the server is important. Having multiple files is very inefficient.
Finally, this is a great article on AMD tools s build tools, worth a read.
So called "global namespace pollution" is greatly over rated as an issue. I don't know about node.js, but in a typical DOM, there are hundreds of global variables by default. Name duplication is rarely an issue where names are chosen judiciously. Adding a few using script will not make the slightest difference. Using a pattern like:
var mySpecialIdentifier = mySpecialIdentifier || {};
means adding a single variable that can be the root of all your code. You can then add modules to your heart's content, e.g.
mySpecialIdentifier.dom = {
/* add dom methods */
}
(function(global, undefined) {
if (!global.mySpecialIdentifier) global.mySpecialIdentifier = {};
/* add methods that require feature testing */
}(this));
And so on.
You can also use an "extend" function that does the testing and adding of base objects so you don't replicate that code and can add methods to base library objects easily from different files. Your library documentation should tell you if you are replicating names or functionality before it becomes an issue (and testing should tell you too).
Your entire library can use a single global variable and can be easily extended or trimmed as you see fit. Finally, you aren't dependent on any third party code to solve a fairly trivial issue.
You can do it like this:
-- main.js --
var my_ns = {};
-- util.js --
my_ns.util = {
map: function () {}
// .. etc
}
-- index.js --
my_ns.index = {
// ..
}
This way you occupy only one variable.
One way of solving this is to have your components talk to each other using a "message bus". A Message (or event) consists of a category and a payload. Components can subscribe to messages of a certain category and can publish messages. This is quite easy to implement, but there are also some out of the box-solutions out there. While this is a neat solution, it also has a great impact on the architecture of your application.
Here is an example implementation: http://pastebin.com/2KE25Par
http://brunch.io/ should be one of the simplest ways if you want to write node-like modular code in your browser without async AMD hell. With it, you’re also able to require() your templates etc, not just JS files.
There are a lot of skeletons (base applications) which you can use with it and it’s quite mature.
Check the example application https://github.com/paulmillr/ostio to see some structure. As you may notice, it’s written in coffeescript, but if you want to write in js, you can — brunch doesn’t care about langs.
I think what you want is https://github.com/component/component.
It's synchronous CommonJS just like Node.js,
it has much less overhead,
and it's written by visionmedia who wrote connect and express.

Categories

Resources