DefineJS 0.2.91

After a while eventually DefineJS comes with a bunch of new features to make it easy to use es6 generators along with promises. Being able to pass a function generator to the promise chain is one of the cool features that I really like now in DefineJS. Even IIFEs could disappear now, using this new feature and I my self startd it like this(Not relevant but it is worth noting that AsyncDB is an async local data storage based):


define.Promise.resolve(jQuery)
  .then(function * ($) {
    var db = {},
      AsyncDB = yield require('asyncdb'),
      pkg = yield $.getJSON('package.json');

    AsyncDB.new('packages', db);

    var pageContent = yield $.get(pkg.repository.url);

    $(pageContent).appendTo('.container');

    var packageId = yield db.packages.insert({
      name: pkg.name,
      version: pkg.version
    });

    return db;
  })
  .then(function * (db) {
    // a totally private and dedicated scope
    // which has access only to the db object
    var packages = yield db.packages.find();

    // This way we could make different scopes
    // with different access levels
  });

A working example of the new feature is now ready to ckeck out in examples folder: define-promise-dev. The code block below shows how it si easy now to setup an application lifecycle.


config.go()
  .then(firstPhase)
  .then(secondPhase)
  .then(finalPhase)
  .catch(lifecycleInterruption)
  .done(theEnd);

function * sameLifecycle() {
  var message;
  try {
    var packageInfo = yield config.go();
    var app = yield firstPhase.go(packageInfo);
    var shimModule2 = yield secondPhase.go(app);
    message = yield finalPhase.go(shimModule2);
  } catch (err) {
    message = yield lifecycleInterruption.go(err);
  }
  theEnd(message);
}

Take a thorough look at the two code block above. They both do the exact same thing without us needing to create IIFEs or to use callbacks.

Of course it still has new freatures comming, very soon.


Click on the post title to leave your comments (powered by Disqus)

Published

17 April 2015

Tags



##DefineJS v0.2.4 Released

This hybrid CommonJS/AMD format allows to write modules with a new syntax similar to CommonJS. This feature is now possible thanks to the ES6 generators.

Let’s imagine a CommonJS module like:

//app.js
var utils = require('utils'),
  $ = require('../vendor/jquery');

var app = {
  //...
};

module.exports = app;

The DefineJS alternative is:

//app.js
define(function* (exports, module) {
  var utils = yield require('utils'),
    $ = yield require('../vendor/jquery');

  var app = {
    //...
  };

  module.exports = app;
});

As mentioned the new syntax is similar to the CommonJS coding style, with two specific differences. First the yield keyword and the next is the define wrapper with a ES6 function generator.


Click on the post title to leave your comments (powered by Disqus)

Published

18 December 2014

Tags



##DefineJS v0.2.3 Released DefineJS v0.2.3 now offers an asynchronous but totally synchronous looking way of requiring dependencies using ES6 generators syntax, it still has a lot of possible implications but for now it could be useful if you are either using any of the modern browsers with ES6 generators syntax support, or any ES6 generators transpiler.

This is how it looks like to define a new module:

//app.js
define(function* () {
  var _,
    app;

  //conditional dependency lodash or underscore
  if(loadashIsNeeded){
    _ = yield require('../vendor/lodash');
  } else {
    _ = yield require('../vendor/underscore');
  }

  app = {
    //...
  };

  return app;
});

and to require it you could do the old AMD way:

//main.js
require(['app'],
  function (app) {
    app.lunch();
  });

Or the new way using ES6 generators syntax:

//main.js
require(function* () {
  var app = yield require('app');
  app.lunch();
});

Which to me is much cleaner code in compared with passing dependencies as parameters. If you take a short look at the code you would see that, because of the synchronous style of coding you could even have conditional dependencies.

It is worth noting that being able to have conditional dependencies makes the whole system more dynamic but on the other hand it goes through a totally different path of loading a module. For instance one of the possible debates around this approach would be the way we could concatenate this type of modules when we are not sure about their dependencies. Although I believe this type of issues and debates happen when you cross the border and com up with a new way of thinking.


Click on the post title to leave your comments (powered by Disqus)

Published

17 December 2014

Tags



The new version with a whole bunch of examples and couple of new features, is ready to use. DefineJS now offers Promissed Modules and use() syntax.

##Promised Modules Using the same AMD module style you can have privileged promise based modules. All you need to do is just returning a promise in your modules, to make them promised modules. To see how it works, just check out the simple-promised-module example in the examples folder.

In this example we have a promised module named: promisedModule.js which is responsible to wait for a specific global variable, and serves it as the module’s promised value.

define([ /*'dependency'*/ ], function ( /*dependency*/ ) {

  return new Promise(function (fulfill, reject) {
    // Here you expect to have a global variable named:
    // myApp after 2 seconds
    // otherwise your module definition gets rejected

    setTimeout(function () {
      if (window.myApp !== undefined) {

        // fulfill when succeeded and pass the fulfillment value
        fulfill({
          app: window.myApp,
          log: 'This is just a sample promised object!'
        });

      } else {

        // reject in case of error or unsuccessful operations
        reject(new Error('No global myApp object found!!'));
      }

    }, 2000);
  });

});

Now you could easily require it, or add it as a dependency. What will happen is, it waits for your promise to get resolved then you will have the promised module object.

// main.js
require(['promisedModule'],
  function (promisedModule) {
    console.log(promisedModule.log);
    // =>This is just a sample promised object!
    console.log(promisedModule.app);
  });

###Note: we are still discussing about the proper way of handling the rejected state of a promised module. Any feedback or proposal is really appreciated.

##use() vs require() You can also have the same modules flow using a new offered syntax by DefineJS:

use(['dependency1', 'dependency2'])
  .then(function (dependency1, dependency2) {
    // ...
    return dependency1.util;
  })
  .then(function (util) {
    // ...
    // use util object if it has any useful functionality
    return util.map([ /*...*/ ]);
  })
  .catch(function (e) {
    // in case of having a rejected promised module or any async error
    console.error(e);
  });

Click on the post title to leave your comments (powered by Disqus)

Published

15 December 2014

Tags



##AMD

The primary building block for referencing and defining modular JavaScript code.

The Asynchronous Module Definition (AMD) API specifies a mechanism for defining modules such that the module and its dependencies can be asynchronously loaded.

No need to discuss the definition further, it is accurately enough to see the starting point clearly.

It is all about writing clean, testable, understandable and maintainable code. There might be more descriptive adjectives here but what we actually mean when we discuss these points, to a large extent, could be summarized in one single principle which is writing modular code.

As an aged JavaScript developer I could remember debates and sometimes actual wars, around this very topic. When I hear the other team members, mostly from a more structural programming language, whispering:

WTF? What the hell is he talking about! He asks us to do the impossible: writing clean code in JavaScript. Has anyone seen it, for real?

To be honest the last time I heard someone saying that was just two weeks ago, of course someone with a Shell/Ruby/Python background and not a JavaScript developer, but it was still a lot to me.

These days, as JavaScript developers we can implement almost anything, a ROBOT or an end to end enterprise solution with a friendly and fun Javascript Fullstack. It means that JavaScript scales up as it finds more implications in different areas. And as it goes on, we necessarily need to have a general mechanism with a shared understanding around it, a general mechanism for defining independent and interchangeable pieces which can work together perfectly. This is what modular programming, gives us:

Modular programming is a software design technique that emphasizes separating the functionality of a program into independent, interchangeable modules, such that each contains everything necessary to execute only one aspect of the desired functionality. Conceptually, modules represent a separation of concerns, and improve maintainability by enforcing logical boundaries between components.

Writing Modular JavaScript

This mechanism has already been thought out and we now have a couple of great modular coding formats, and to me these three are the most exciting ones:

  • AMD: The Asynchronous Module Definition (AMD) API specifies a mechanism for defining modules such that the module and its dependencies can be asynchronously loaded. This is particularly well suited for the browser environment where synchronous loading of modules incurs performance, usability, debugging, and cross-domain access problems.
  • CommonJS: Unfortunately, it was defined without giving browsers equal footing to other JavaScript environments ….
  • ES6 Modules: What we are going to have in the next version of JavaScript, Harmony.

These three ways each seems to have bunch of pros and cons, but more importantly each has its own syntax format, which makes it difficult to use them interchangeably.

##DefineJS DefineJS is a lightweight implementation of AMD module format. Other than regular AMD module pattern, DefineJS also offers couple of nonstandard but usefull modular coding patterns.

Notes

There are couple of important points which I have faced with during the implementation of this module loader. All of them bring up one simple question:

As library authors are we better off implementing everything needed, the best and the worst practices all mixed together?

OR

Some might say, a great library is the one which prevents its developers from getting drowned in a bad code.

Since a module loader needs to be compatible even with possible uses of what is already known as a bad practice, my answer when implementing DefineJS was YES to the first question.

For instance, when working with an AMD module loader, you can explicitly name modules yourself, but it makes the modules less portable and if you move the file to another directory you will need to change the name. BUT it still is there and you can use it to define named modules.


Click on the post title to leave your comments (powered by Disqus)

Published

15 December 2014

Tags