Fork me on GitHub

The JavaScript Universal Module Converter & Resource Builder

define(['Modular', 'Development', 'Deployment'], function(){ return 'that just works, painlessly!' });

Why use modules like AMD or Common/JS ?

Write modular, maintainable & reusable code:

  • Clearly stated dependencies & imports.

  • Employ standards and trusted tools.

  • Have a dynamic code loading mechanism.

  • The damnation of one huge .js file or concatenation must end!

Are U still concatenating .js files ?

But javascript developers hate modules!

Many woes on Module formats & incompatibilities:

  • Verbose syntax, boilerplate ceremony & intricacies (especially AMD)

  • execution environment (AMD only for Web, CommonJs only for nodejs)

  • capabilities, dependency/path resolutions, plugins, semantics etc are a mess

  • UMD is a semi-standard boilerplate, far from usable.

    U need a bridge to enjoy the richness of modules.
require('more').than(this);

Why use uRequire ?

If U required it or defined it, uRequire will find it.

Simplest Module Authoring

var dep1 = require('./rel/path/dep1'),
    dep2 = require('abs/path/dep2');
// do stuff with dep1, dep2
module.exports = {my: 'module'}

// or
define(['./rel/path/dep1','abs/path/dep2'],
  function(dep1, dep2) {
    // do stuff with dep1, dep2
    return {my:'module'}
  });

// or both, in a relaxed, non-weird way
define(['some/dirName','dep2'],
  function(dirNameIndex, dep2) {
    var dep3JSON = require('json!dep3AsJSON');
    // do stuff with dirNameIndex, dep2, dep3JSON
    return {my:'module'}
});

// mix well known features from both
define(['my/dep1'], function(dep1) {
    exports.prop = dep1 + require('./your/dep3');
});
dependencies: imports: bundle: { 'lodash': '_', 'backbone': 'Backbone'}

A Modules & Dependencies aware builder.

Exporting modules to window/global variables (like window._, window.$ etc), demystified and with no boilerplate.

Want noConflict(), baked in? Its a simple declaration away.

// file `uberscore.js` - export it to root (`window`) as `_B`
({ urequire: { rootExports: '_B', noConflict: true }});
module.exports = {...}

The same in a config is

dependencies: { imports: { root: { 'uberscore': '_B' }}}

How about exporting to your bundle only?

// inject `lodash` as `_` in (all) bundle's modules
dependencies: { imports: { 'lodash': '_' }}

Want to replace deps with mocks or alternative versions ?

Inject, replace or even delete dependencies with a simple declaration or a callback:

// underscore is dead, long live _
dependencies: { replace: { lodash: 'underscore'}}

// with code
function(modyle){ modyle.replaceDeps('models/PersonModel', 'mock/models/PersonModelMock'); }
[ '$coco', [ '**/*.co'], ((r)-> require('coco').compile r.converted), '.js']

A versatile in-memory Resource Conversion

Manipulate Module code while building:

  • inject, replace or delete code fragments or AST nodes or dependencies with one liners.

    // delete matching code of code skeleton
    function(m){ m.replaceCode('if (debug){}') }
    
    // traverse matching nodes, replace or delete em
    function(m){ m.replaceCode('console.log()', function(nodeAST){return nodeOrStringOrUndefined}) }

Perform any code manipulation - eg remove debug code, inject initializations etc

  • Inject code before (or after) each module's body eg. to initialize custom module code, for common module tasks:

    function(m) { m.beforeBody = "var l = new _B.Logger('" + m.dstFilename + "');"; }
  • Inject common or merged repeating statements: keep DRY, save space & speed when combined in a single .js

    // each module will have before its main body, in all templates
    bundle: commonCode: 'var expect = chai.expect;'
    
    // added before beforeBody for all templates except 'combined', where its merged
    function(m) { m.mergedCode = '"var p1 = myModule.p1, p2 = myModule.p2, ..., pN = myModule.pN;"' }

    Who needs bloated plugins ? Here's a ResourceConverter for our coco files (included along with coffeescript, LiveScript, iced-coffee-script.

    [ '$coco', [ '**/*.co'], ((r)-> require('coco').compile r.converted), '.js']
['+inject:VERSION', ['uberscore.js'], (m)-> m.beforeBody = "var VERSION = '0.0.15';"]

A spartan Module builder & config

This 'uberscore' config (coffeescript) will:

// Config as a `Gruntfile.coffee` task
// Can be a .coffee, .js, .json, .yml & more
uberscore:
  path: 'source'
  dstPath: 'build'
  filez: ['**/*', (f)-> f isnt 'badfile']
  copy: [/./]
  runtimeInfo: ['!**/*', 'Logger']
  dependencies: imports:
    bundle: 'lodash':  '_'
    root: 'uberscore': '_B'
  resources: [
    ['+inject:VERSION', ['uberscore.js'],
     (m)-> m.beforeBody = "var VERSION = '0.0.15';" ]
  ]
  template: banner: "// uBerscore v0.0.15"
  optimize: 'uglify2'
  watch: true
{ derive: ['uberscore'], filez: [ /.*\.(coffee\.md|litcoffee|coffee)$/ ] }

Parent configs ? Lets derive!

The 'distribute' config will:

See more simple examples and a detailed real project

Lets derive some children

distribute:
  derive: ['uberscore']
  filez: ['!', /useRegExpsAsFileSpecs/]
  template: 'combined'
  dstPath: 'build/uberscore-combined.js'
  optimize: uglify2: {more: uglify2: options}
`_.extend(window.libraryExported, exports)`

How about declarative, either per module or whole bundle:

All of these are tweaked to work in all templates, with the miminum required generated code.

build:
  globalWindow: false

  runtimeInfo: ['Logger']

  useStrict: true

  injectExportsModule: ['uberscore', 'circular/Dependency']

  bare: true

  allNodeRequires: ['/data/preCached']

  noRootExports: true

  scanAllow: false

How do I get started?

Read the Quick Introduction on using uRequire to modularize your code. See how trivial Using uRequire is. Learn more about Module Authoring and the Universal Module Format. Check out the wicked uRequire config and how to easily Convert Resources.