This week we had a chance to have a new event of the JSSophia user group, hosted by CrossKnowledge, well organized by Olivier and Corinne. Really cool to see the crowded room each time!

## Cordova

The first talk was given by Erik Jan de Wit about Cordova and how easy it is to convert an application written with web technologies inside native wrappers for most mobile platforms. I especially like the advice not to try replicate the exact look and feel of the platform but rather create your own recognizable style. It was also cool to highlight the aim at following WebAPI so that once those are standardized and included in webviews, there will not even be a need for native wrappers.

It was then followed by lightning talks. I took the challenge to introduce Browserify in less than 5 minutes.

Browserify lightning talk

I started by showing the difference between CommonJS modules initially made for Node.js and were designed synchronous, and AMD more targeted at browser environments and designed to allow for lazily loading modules from the server asynchronously.

// CommonJS
var math = require('math');

exports.increment = function(val) {
    return math.add(val, 1);
};

// AMD
define('increment', ['math'], function (math) {
  function increment(val) {
    return math.add(val, 1);
  }

  return { increment : increment };
});

I personally build code which is aimed at working both on the server and on the client, for example a small tool or an application for which part of the code can be shared amond server and client logics. To solve this, people derived universal module definition, but it makes a large boilerplate to maintain on each and every file.

(function (root, factory) {
  if (typeof define === 'function' ∧∧ define.amd) {
    define('increment', ['math'], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory(require('math'));
  } else {
    root.returnExports = factory(root.b);
  }
}(this, function (math) {
  function increment(val) {
    return math.add(val, 1);
  }
  return { increment : increment };
}));

And this is where Browserify proves useful. It is aimed at reading CommonJS modules, analyzing dependencies with static analysis and bundling everything in a single javascript file, along with bootstrap code to link all of them. The resulting file thus works in the browser. For the use case of an application one wants to share logic, the whole application is authored in CommonJS modules.

// shared code
var math = require('math');

exports.increment = function(val) {
    return math.add(val, 1);
};
// server.js
var increment = require('increment');

/* server logic */
server.start();
// client.js
var increment = require('increment');

/* client side logic */
client.start(global);

Server is then ran using Node directly on server.js file and will natively use library code. At application build time, Browserify is used to compile client.js into a bundled asset including all dependencies. When a client loads the application, it simply downloads this bundle with a <script> tag and the application starts by itself.

The use case of libraries or tools is slightly different. My personal workflow is to author code in CommonJS modules

var math = require('math');

exports.increment = function(val) {
    return math.add(val, 1);
};

During build time, I use Browserify to compile library entry point into an asset from with a standalone build. A standalone build simply wraps the original module in a universal module definition so that the asset can be consumed both by CommonJS or AMD modules, but also using a browser global variable. The good news here is that boilerplate is not under version control and needs not be maintained. Once the asset is generated, I push both original modules and the browserified one to NPM. I still prefer to push original modules so that people looking at the code have a better time and using other packagers is still possible.

Building an asset with Browserify is really easy both in Gulp or Grunt.

// Gulp
var browserify = require('browserify');
var source = require('vinyl-source-stream');

gulp.task('browser', function() {
  return browserify('./src/increment.js')
    .bundle({ standalone : 'increment' })
    .pipe(source('browser.js'))
    .pipe(gulp.dest('browser'));
});

// Grunt
grunt.initConfig({
  browserify: {
    standalone: {
      src: [ 'increment.js' ],
      dest: './browser/dist/increment.js',
      options: {
        standalone: 'increment'
      }
    }
  }
});
grunt.loadNpmTasks('grunt-browserify');

I then had a small digression, because none of AMD or CommonJS modules are actual standards, and ES6 includes a module standard.

module 'Increment' {

  import add from 'Math';

  export default function increment(n) {
    return add(n, 1);
  }
}

Using that layout sounds more future-forward to me, and will hopefully eventually be supported by everyone. Detailing the standard would be worth one full talk! To use it currently, one can have a look to Traceur compiler, which is aimed at transpiling next javascript to something current platforms understand. This one at that day does not support modules but may be worth looking at.

## Other lightning talks

There were a lot other lightning talks. Bertrand followed and spoke about noder-js which has some similar goals to Browserify but offers more flexible packaging which may especially be useful for multi pages websites and for debugging. Noder-js supports some Node apis in the browser, especially the module-related ones. Browserify does this too and includes complex apis but I did not mention it during my talk as I am not convinced using require('http') in client side code makes that much sense. I thus prefer noder’s approach here.

Then Sebastien spoke about Firefox OS, Bertrand about debugging a Cordova application, Frédéric introduced the MEAN stack and Yacine closed with ionic.