A collaborative website about the latest JavaScript features and tools.
Send a Post

*using github

Jaydson Gomes
Posted by
Fri May 08 2015 04:51:30 GMT+0000 (UTC)

how I'm using es6 modules in production

I've been using ES6 modules for a while in my daily work and I want to share with you guys how I'm doing it.
First of all, Babel is the consolidated tool for transpilation. It's a very active project, and it covers almost all of modern JavaScript features.
Babel works great for modules too, so you'll just need to decide the flavour, I mean AMD, Common, UMD and even customized modules.

In my company we're building applications using a homemade framework (not open-source yet) based on AMD modules.
We have A LOT of legacy AMD modules.
Believe me, for large applications AMD still one of the best solutions. We can't simply bundle everything in a single file. That's not how things work.
Nowadays we have solutions like Webpack, but we already have a huge installed base applications, so it's not so easy to migrate, and our home-made solution for delivering modules (not open-source yet) is working just fine.

Micro-modules strategy

This strategy is working quite well for me.
As I said before, our final module must be a AMD module, but sometimes the AMD module itself needs modules, and I'm calling them micro-modules.
These micro-modules I'm using do not necessarily need to be shared across applications, but they help me a lot with code organization.
Here's a piece of code we have in production:

import config from './config';
import { globalpkg } from './config';
import factory from './factory';

zaz.use((pkg) => {

    "use strict";

    config.dynamic.globalpkg = pkg;

    pkg.require(['modFactory'], (modFactory) => {
        modFactory.create(pkg.utils.deepMerge(config._static, factory));
    });

});

We're importing some modules above and using them in our AMD module.
Those ES6 modules aren't useful for any other application, but the final code looks much more readable using micro-modules.
The config we're importing above look like this:

const githubURL = "OUR GITHUB URL HERE";
const staticServer = "https://s1.trrsf.com";
const testsPath = `zaz-${type}-${name}/tests/index.htm?zaz[env]=tests`;
const name = "stalker";
const type = "mod";
const version = "0.0.1";
const state = "ok";
const description = "JavaScript API to deal with user data";
let globalpkg = null;

// default export 
const config = {
    _static: {
        name,
        version,
        state,
        description,
        docs: `${githubURL}/pages/terra/zaz-${type}-${name}`,
        source: `${githubURL}/Terra/zaz-${type}-${name}`,
        tests: `${staticServer}/fe/${testsPath}`,
        dependencies: ['mod.wilson']
    }
};

export default config;

Look at the tree we have for this specific AMD module:

src/
├── _js
│   ├── config.js
│   ├── environment.js
│   ├── factory.js
│   ├── helpers.js
│   ├── methods.js
│   └── mod-stalker.js

I've just split the logic inside my AMD module into tiny ES6 modules.
The build process is very simple: Babel transpiles the code to ES5 using CommonJS modules for micro-modules and then Browserify bundles everything.
Boom! The final code remains being an AMD module, but my source code is using CommonJS for micro-modules.

Next step

Sourcemaps don't work well with this workflow as I'm using Browserify to bundle.
Perhaps it should be easy to implement.
We're starting to rewrite our framework using some ES6 features and of course we'll use modules.
It may be possible to build a custom module formatter for our current structure, but I think it wouldn't be a good approach.
Maybe we'll need to rewrite the whole module system we already have.

Conclusion

The modules specification is already done, and in my opinion it's very mature and efficient.
However, we didn't have a browser API yet for dealing with modules loading, so a solution like AMD or CommonJS remains necessary.
We can have benefit of ES6 modules syntax right now, making our code more readable and concise.
Existing tools such as Babel and Browserify give us a painless development, and in the near future we can simply deactivate them because we'll have full support.

icon comments

Comments

comments powered by Disqus