Nodejitsu free for Open Source programFork me on GitHub

MasterDefaultsConfig.coffee

Introduction

The config is the heart of uRequire, to the user's side. This file is both docs & the defaults of the config file/object.

Scroll to some super cool config examples, that show the power of uRequire & its config.

Note: Literate Coffescript

This file is written in Literate Coffeescript: it serves both as markdown documentation AND the actual code that represents the master config. Most code blocks shown (unless otherwise noted) are the actual code, i.e each key declares name and default value.

module.exports = MasterDefaultsConfig =

NOTE: This file primary location is https://github.com/anodynos/uRequire/blob/master/source/code/config/MasterDefaultsConfig.coffee.md & copied over to the urequire.wiki - DONT edit it separately in the wiki.

@see the tags legend of the documentation

Config Usage

A config determines a bundle and a build that uRequire will process. A config is an {} with expected keys & can be used as:

  • File based, using the urequire CLI (from npm install urequire -g) as $ urequire config myConfig.js, where myConfig.js is a node module file that exports the config object. The file can actually be a .coffee or .js node module, or a .json file as well as many other formats - see butter-require. The 'XXX' of `derive:'XXX' can be another parent file (eg parentConfig.yml), relative to the 1st children's path. @todo: make relative to each children's path).

  • Using grunt-urequire, having (almost) the exact config object of the file-base, but as a urequire:XYZ grunt task. The difference is that `derive:'XXX' can be another urequire:XXX task, and if its not found its assumed to be a filename, relative to Gruntfile.js.

  • Within your tool's code, using urequire.BundleBuilder.

Versatility

uRequire configs are extremely versatile:

The 'bundle' and the 'build'

uRequire config has 2 top-level keys/hashes: bundle and build. All related information is nested bellow these two keys.

@note: user configs (especially simple ones) can safely omit bundle and build hashes and put the keys belonging on either on the 'root' of their config object. uRequire safely recognises where keys belong, even if they're not in bundle/build.


bundle

The bundle hash defines what constitutes a bundle, i.e where files are located, which ones are converted and how etc. Consider a bundle as the 'source' or the 'package' that is then processed or built, based on the build part of the config.

bundle:

bundle.path

The filesystem path where source files reside (relative to urequire's CWD, or Gruntfile.js for grunt-urequire).

@mandatory But, if bundle.path is ommited, it is implied by the 1st config's file position (only for file-based 'config' command, not in grunt-urequire's config).

@example './source/code'

@alias bundlePath DEPRECATED

  path: undefined

bundle.filez

All files that somehow participate in the bundle are specified here. Its the ultimate filter of your bundle, virtually including or excluding files. Its very versatile

@type filespecs

@derive arrayizeConcat.

@note all files are relative to bundle.path

@alias filespecs DEPRECATED

@note the z in filez is used to segregate from gruntjs files, when urequire is used within grunt-urequire and allow its different features like RegExp & deriving.

@note: The master default is undefined, so the last child filez in derived hierarchy determines what is ultimately allowed.

@default: The actual default (runtime hard-coded), if no bundle.filez exists in the final cfg, is ['**/*'] (and not undefined). That's why its optional!

  filez: undefined

bundle.copy

Copy (binary & sync) of all non-resource bundle.filez (i.e those that are BundleFiles) to build.dstPath as a convenience. If destination exists, it checks nodejs's fs.statSync 'mtime' & 'size' and copies (overwrites) ONLY changed files.

@example copy: ['**/images/*.gif', '!dummy.json', /\.(txt|md)$/i]

@type filespecs

@derive arrayizeConcat.

@alias copyNonResources DEPRECATED

@default [], i.e no non-resource files are copied. You can use /./ or '**/*' for all non-resource files to be copied.

  copy: []

bundle.name

The name of the bundle, eg 'MyLibrary'.

@note When using grunt-urequire, it defaults to the multi-task @target. So with grunt config {urequire: 'MyBundlename': {bundle : {name:undefined}, build:{} }}, bundle.name will default to 'MyBundlename'.

@note: bundle.name serves as the 1st default for bundle.main (if main is not explicit).

@alias bundleName DEPRECATED

  name: undefined

bundle.main

The 'main' or 'index' module file of your bundle, that requires and kicks off all other modules (perhaps implicitly).

@optional unless 'combined' template is used, or you have a build.template.banner.

@example

 bundle: main: "MyAwesomeLibrary"

whereas 'MyAwesomeLibrary.js' would be something like:

 define(function(){
    return {
      aModule: require('somepath/aModule'),
      anotherModule: require('somepath/anotherModule')
    }
 }

or the module.exports = {...} version.

Details:

  • bundle.main is used as 'name' / 'include' on RequireJS build.js, on combined/almond template.

  • It should be the 'entry' point module of your bundle, where all dependencies are require'd. Then r.js recursively adds all dependency tree to the 'combined' optimized file.

  • It is also used to as the initiation require on your combined bundle. It is the module just kicks off the app and/or requires all your other library modules.

  • Defaults to bundle.name, 'index', 'main': If bundle.main is missing, it defaults to bundle.name, only if there is a module by that name. If bundle.name fails to match an existing module, 'index' or 'main' are used as bundle.main (again provided there is a module named 'index' or 'main' - which ever found first). In all cases of automatic discovery, uRequire will issue a warning.

  • Its the name of the module build.template.banner is added.

If bundle.main can't match an existing module, it will cause a 'combined' template error.

  main: undefined

bundle.dependencies

All information related to dependencies handling is listed here.

  dependencies:

bundle.dependencies.exports

Holds keys related to binding and exporting modules (i.e making them available to bundle modules, or globally).

    exports:

bundle.dependencies.exports.bundle

Allows you to export or inject (i.e have available) specific dependencies (other modules) throughout the whole bundle, under the given variable name(s).

Eg you want to access 'underscore' from _, 'backbone' from Backbone etc, from all modules, without having to declare it in each module.

Effectively this means that each module will have an injection of all dependencies.exports.bundle, so you don't have to list them in each module.

@example

{ 'underscore': '_',
 'jquery': ["$", "jQuery"],
 'models/PersonModel': ['persons', 'personsModel'] }

will give you :

  • Injection of Modules / dependencies 'underscore', 'jquery', and 'models/PersonModel' to each module in the bundle.

  • Access of _, $, jQuery, persons & personsModel variables everywhere, without listing them once on any module's code.

  • Working the same way on all templates, on any environment (AMD, nodejs, Web/Script).

  • Saving space: on 'combined' template, they are listed & loaded only once, made available only within bundle's 'combined' closure.

@type depsVars

@derive dependenciesbindings

@note the shortcut depsvars format, can also be used (eg ['underscore', 'jquery', 'models/PersonModel']), in which case the vars are inferred].

@alias bundleExports DEPRECATED

      bundle: {}

bundle.dependencies.imports [.bundle ?]

@todo NOT IMPLEMENTED https://github.com/anodynos/uRequire/issues/39

bundle.dependencies.exports.root

Make a module be available GLOBALY (by attaching it to window and/or nodejs's global object) under varName(s), same as in Exporting Modules.

Access via plain varName works both in browser and nodejs.

  • On browser its attached as a property to window object

  • On nodejs its attached to the global object with the same effect: accessing it via its name from everywhere.

@note: When bundle.dependencies.exports.root is used (instead of precise Exporting Modules), noConflict is always true.

@example

bundle: dependencies: exports: root: {'models/PersonModel': ['persons', 'personsModel']}

is like having a

({rootExports: ['persons', 'personsModel'], noConflict:true});

in module 'models/PersonModel' as described in Exporting Modules.

@type depsVars

@derive dependenciesbindings

@todo dependencies.exports.root globals being optional on AMD or node

@note both window and global objects exist as an alias of each other on the 'combined' template or when build.globalWindow: true (the default).

      root: {}

bundle.dependencies.replace

Replace one or more dependencies with another. Enables you to substitute with mocks, substitutes or provide compatibility etc.

It replaces all right hand side dependencies (String value or []<String> values), to the left side (key) in the build modules.

@example

{
  lodash: ['underscore', 'otherscore'],
  newDep2Name: 'oldDep2Name'
}

replaces all 'underscore' or 'otherscore' deps to 'lodash' and all 'oldDep2Name' with 'newDep2Name' in all modules of the bundle.

All deps are considered / translated to bundleRelative:

  • 'depDir/dep' matches and/or replaces the deps that resolved to this as bundle relative, even if they are declared in the code of 'someOtherdir/someModule' as require('../depDir/dep') (when authored with the nodejs fileRelative path convention).

  • '../../some/external/dep' will fall outside the bundle, it refers to a directory that is two '..' steps before bundle.path and will match require('../../../some/external/dep') declared in 'someOtherdir/someModule'.

@see inject / replace dependencies in Manipulating Modules.

@type depsVars

@derive paradoxically its dependenciesbindings

      replace: undefined

bundle.dependencies.node

Dependencies (declared in filespecs) listed here are treated as node-only: they aren't added to the AMD dependency array (and hence not available on the Web/AMD side).

Your code should not use these deps outside node - you can use __isNode, __isAMD, __isWeb available in uRequire compiled modules with build.runtimeInfo to follow a different branch in your code.

Using bundle.dependencies.node has the same effect as the node! fake plugin, eg require('node!my_fs'), but its probably more useful cause your code can execute on nodejs without the template conversion that strips 'node!' and you can declare in them in bulk without poluting the source code.

@type filespecs, used WITHOUT extensions (.js), only as deps.

@derive arrayizeConcat.

@example node: ['myUtil', 'my_fs', 'node/*', '!stream']

@alias noWeb DEPRECATED

@stability 2

@default All known built-in nodejs packages (as of 10.8) like 'util', 'fs' etc are the default of bundle.dependencies.node. Use node: [[null], 'myNodeModule'] to reset the node array with only your modules.

@note: If your bundle contains a dependency that is also in dependencies.node (eg you have 'url.js' in the root of you bundle), then this is considered to be a node-only dep, so you DO need to exclude it with '!url', or it wont be available on the AMD side.

    node: [
      'fs', 'events', 'util', 'http', 'path', 'child_process',
      'events', 'crypto', 'string_decoder', 'timers', 'tls'
      'domain', 'buffer', 'net', 'dgram', 'dns', 'stream',
      'https', 'querystring', 'punycode', 'readline', 'url',
      'repl', 'vm', 'assert', 'tty', 'zlib', 'os', 'cluster'
      'console', 'freelist', 'sys', 'constants' # 'module' conflicts with dep.isSystem
    ]

bundle.dependencies.locals

Declare your local packages, like 'lodash' or 'when' that are installed either on npm (i.e /node_modules), bower (i.e /bower_components) or vanilla (eg /vendor). Local deps are NOT considered part of the bundle, hence they are not reported as "Bundle-looking dependencies not found in bundle".

All deps that have no nested path (i.e no '/') and are not in the bundle's path (eg 'someDepNotInBundle') are considered as local automatically. The only reason you would need to declare a dep as local is :

  • you use something like require('when/node/function') and it's reported as "Bundle-looking dependencies not found in bundle", but it shouldn't be. So you list when in locals and everything that falls below 'when/**/*' is also considered local (@todo it could be inferred from package.json / bower.json etc).

  • (@todo: inlining NOT IMPLEMENTED yet) you want to override the paths infered from bower.json/package.json for lodash and also inline 'lodash' in a combined build.

@optional

@todo experimental / partially implemented (especially for AMD's loading mechanism that doesn't understand the CommonJS semantics of 'when/node/function').

@stability 1

@example locals: ['when'] or locals: {'when': '../node_modules/when'}

@type :

  • Array<String>, eg ['when', 'backbone', 'lodash']. Declare only the first path part of you local-only deps, eg 'when', instead of 'when/node/function'

  • depsVars type where

    • keys are the first part of local deps

    • value(s) are the paths when the dependency 'main' can be found. eg

      {
       'when': "./node_modules/when"
       'backbone': "./node_modules/backbone"
       'lodash': "./node_modules/lodash"
      }

      @todo: NOT IMPLEMENTED yet: the paths are not taken into consideration (and not needed anyway if you don't indent to inline them in a combined template).

@todo infer locals AND their paths from package.json, bower.json etc

    locals: {}

bundle.dependencies.depsVars

List of dependencies bound with one or more vars.

@optional list them only as reference/backup, when they cant be inferred], or some specific deps shouldnt be inferred.

@note In case identifiers can't be inferred (i.e only used require('myLocalDep') without assigning to a var) and bindings aren't in bundle.dependencies.depsVars (or _knownDepsVars below), then the build will fail.

@example { underscore: ['_'], jquery: ['$', 'jQuery'], }.

@type depsVars

@derive dependenciesBindings

@alias variableNames DEPRECATED

    depsVars: {}

bundle.dependencies._knownDepsVars

Some known depsVars, have them as backup - its a private field, not meant to be extended by users (use depsVars).

@type depsVars

@derive dependenciesBindings

@alias _knownVariableNames DEPRECATED

@todo: provide some 'common/standard' ones.

    _knownDepsVars:
      chai: 'chai'
      mocha: 'mocha'
      lodash: "_"
      underscore: "_"
      jquery: ["$", "jQuery"]
      backbone: "Backbone"
      knockout: ["ko", 'Knockout']

bundle.resources

An Array of ResourceConverters (RC) (eg compilers, transpilers etc), that perform a conversion from one resource format (eg coffeescript, teacup) to another converted format (eg javascript, HTML).

ResourceConverters is a generic and extendible in-memory conversions workflow, that is trivial to use and extend with your own, perhaps one-liner, converters (eg ['$coco', [ '**/*.co'], ((r)-> (require 'coco').compile r.converted), '.js'] is an RC).

The workflow unobtrusively uses bundle & build info like paths and is a highly in-memory-pipeline and read-convert-and-save only-when-needed workflow, with an integrated build.watch capability (grunt or standalone).

Read all about them in ResourceConverters.coffee.

Notes on RCs:

  • Each file in bundle.filez that is matched by an RC is considered a Resource that needs convert()-ing.

  • All non-matching filez are just BundleFiles - useful for declarative sync bundle.copying at each build.

@optional unless you want to add you own Resource Converters for your conversion needs.

@derive arrayizeConcat. Hint: You can use [null] as the 1st item to reset inherited/parent array items (i.e the ResourceConverters defined in parent configs) and add your own RC or lookup, clone and change an existing one.

@stability: 3 - Stable

@type An Array<ResourceConverter>, where a ResourceConverter can be either :

  • an 'Object', for boring formal RC definitions.

  • an 'Array' (for fancy RC-specs)

  • a 'String' name search of a previously registered RC, eg 'teacup'. Note that name flags passed on the search (eg '#teacup'), find the actual RC, modify it according to the name flags, strip the flags and then return the RC.

  • a function that returns an RC. This function is called with the 1st argument & this with a searchOrMaterialize function that takes a String name (or an Array-spec) of an RC and returns a looked up (or materialized RC). For example:

    // example - not part of coffee.md source
    resources: [
      // lookup & clone an RC 
      function(search){
        // (use rc.clone() to get a proper instance)
        var rc = search("RCname").clone();
        // change the clone's name
        // & type to 'module' via '$' name flag
        rc.name = '$MyNewRCname';
        // add some file specs to `filez`
        rc.filez.push('!**/DRAFT*.*');
        // return the new RC, which is
        // added to `resources` array
        return rc;
      },
      // create a new RC from an Array spec
      // add some fields and return it
      function(materialize){
        // create an RC {} from an RC []
        myRC = materialize([ 'myNewRC', [/./], convertToMoreFn]);
        // we now have an {} RC with above fields
        myRC.srcMain = 'main.lessIsMore';
        return myRC;
      }  
    ]

    If the function returns null or undefined, its not added to the Array.

@note Important: The order of RCs in resources does matter, since only the last matching RC determines the actual class) of the created resource (file).

@example

A dummy example follows (in coffeescript) :

# example - not part of coffee.md source
resources: [
 # search registered RC 'teacup' & use as-is
 'teacup'

 # search RC, change its flags and return it
 '@someRCname' 

 # search, clone, change, return in one line
 -> tc = @('someRC').clone(); tc.filez.push('**/*.someExt'); tc

 # define a new RC, with the fancy [] RC-spec
 ['$koko', ['**/*.ko'], ((m)-> require('koko').compile m.converted), '.js']

 # define a new RC, with the grandaddy {} RC-spec
 {
   name: 'kookoo'
   type: 'module'
   filez: [ '**/*.koo']
   convert: (m)-> require('kookoo').compile m.source
   convFilename: '.js'
 }

 # define a new RC, and reuse an existing
 # with the magic search-create-alter function
 # passed as `this` (@ in coffeescript)
 ->
   # lookup an existing
   kookoo = @ 'kookoo'
   # return a new one, that uses `kookoo.convert`   
   ['$doodoo', [ '**/*.doo'], kookoo.convert, '.js']
]

@default

By default resources has ResourceConverters 'javascript', 'coffee-script', 'LiveScript', 'iced-coffee-script' and 'coco' as defined in Default Resource Converters.

Some extra RCs are registered, but not added to 'resources' - they can be used by searching for 'teacup', 'execSync' or 'lessc'. Feel free to contribute yours.

  resources: require('./ResourceConverters').defaultResourceConverters

bundle.commonCode

This is an opportunity to add code once and have it included:

In all templates, the code should access only bundle.dependencies.exports.bundle vars & other globals. It should not it self require anything, cause its depedencies are not (and should not be) analyzed.

@see inject code and strings in modules & Merging code in bundles

@example

  commonCode: undefined

bundle.webRootMap

When running on nodejs, for dependencies that refer to web's root (eg '/libs/myLib'), it maps / to a directory on the nodejs file system.

When running on Web/AMD, the AMD loader (eg RequireJS) maps it to the http-server's root by default (eg http://example.com/).

webRootMap can be absolute ('/mnt/libs/') or relative to bundle.path. - it defaults to bundle.

@example "/var/www" or "/../../fakeWebRoot"

@note webRootMap is currently working only with 'UMD' template.

  webRootMap: '.'

Build

The build hash holds keys that define the conversion or build process, such as where to output, details on how to convert/build etc.

build:

build.dstPath

Output converted files (Modules & Resources) onto this:

  • directory, for all templates except 'combined'

  • filename, if 'combined' template is used and build.template.combinedFile is undefined.

    If using 'combined' template & combinedFile, you can:

    • omit dstPath and all converted resources will go in the same directory as the combinedFile file.

    • specify any alternative dstPath, where all other resources (non-modules) will be written.

@note: build.dstPath, like bundle.path, is relative to urequire's CWD or Gruntfile.js for grunt-urequire.

@mandatory unless build.forceOverwriteSources or build.template.combinedFile is used

@example 'build/code' or 'build/dist/myLib-min.js'

@alias outputPath DEPRECATED

  dstPath: undefined

build.forceOverwriteSources

Output on the same directory as the source bundle.path, overwriting all files. Useful if your sources are not real sources.

@note: Be warned that when true, build.dstPath is ignored and always takes the value of bundle.path.

  forceOverwriteSources: false

build.template

The template to use to either convert:

  • each module file, to a new format like 'UMD', 'UMDPlain', 'nodejs', 'AMD' etc

  • all modules files into one combined.js file, using the special 'combined' template that actually drives an r.js/almond conversion.

@type

  • The simple usage, just the name of the template as a string in Build.templates = ['UMD', 'UMDplain', 'AMD', 'nodejs', 'combined']

  • An options hash such as :

template: {
   # the String **name of the template**
   name: 'combined'

   # for the 'combined' template only, you can declare the `combinedFile`,
   # if its different (or instead of) [`build.dstPath`](#build.dstPath).
   combinedFile: 'build/someOtherPath/combinedModulesFilename.js'

   # By default, when AMD is present, 'combined' template calls `define()` that registers your (main) module **anonymously** - you can define it with a [moduleName](http://www.requirejs.org/docs/api.html#modulename) eg `moduleName: "foo/title"` here.
   # Its useful when you want to 'inject' it inside some other hierarchy (than what its dstPath implicitly defines it as), eg you want to have `'foo/bar' as a separate package `foo_bar.js` but correctly register its self on your dependency tree.
   # You can even load such combined file with moduleName via plain script eg `<script src='foo_bar.js'>`, without RequireJS throwing `Error: Mismatched anonymous define()` and then `require(['foo/bar', function(foo_bar){ foo_bar.doStuff()})`.
   moduleName: 'foo/bar'

   # Adds the **String** banner at the top of your `bundle.main` file, or the top of the combined file.
   # @note as of v0.6.10, it works independently of rjs optimizer, so you can `rjs: preserveLicenseComments: false` to strip all other banner but yours (but watch out for license deprivation).
   banner: "/** I am a banner on top */"

   # Template debug - outputs section comments with values of 10, 20, 30.
   # Multiply that by 10 and you'll get `console.log`s of sections while they load.
   # Highly experimental and pre-alpha!
   debugLevel: 0
}

@note: combinedFile and build.dstPath derive from each other, if either is undefined:

  • In the previous example, if build.dstPath is undefined, it will default to 'build/someOtherPath/'

  • If combinedFile is undefined, it will use build.dstPath with a '.js' appended.

  • if both are undefined uRequire will quit (unless forceOverwriteSources is true).

@example template: 'UMDplain' or see @type example before

@see Conversion Templates in docs.

  template: 'UMD'

build.runtimeInfo

Adds __isAMD, __isNode & __isWeb variables to your modules, so you can easily determine the execution environment your module is running in.

For example they can be used to select a different execution branch, depending on where the module is executing. Make sure to add modules that are nodejs-only to bundle.dependencies.node so they aren't loaded in AMD (i.e not added to define() dependency array).

See a Q&A / tutorial on how this helps nodejs/browser cross development at stackoverflow.com.

@note 'combined' template always has these variables available on the enclosing function cause it needs them!

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

@example runtimeInfo: ['index', 'libs/**/*']

  runtimeInfo: true

build.bare

Like coffeescript --bare:

  • if bare: false (the default), it encloses each module in an Immediately Invoked Function Expression (IIFE):

    (function () {
      .....
    }).call(this);
  • if bare: true it doesnt.

The IIFE is just a top-level safety wrapper used to prevent leaking and have all variables as local to the module and to provide the build.globalWindow functionality.

@note if bare: true, then build.globalWindow functionality is disabled.

@note It doesn't apply to 'combined' template: your modules & almond are always enclosed in a single IIFE, and windows === global is always true and the modules themselves are plain define(...) calls.

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

  bare: false

build.useStrict

Add the famous 'use strict'; so you dont have to type it at each module.

Its added either at:

  • the begining of each module's body, for modules that pass filespecs or to all modules if build.useStrict: true.

  • once at the closure of the 'combined' template, only if the value is true.

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

@default is undefined, which doesn't inject use strict; on any module, BUT it in combined template it enables the corresponding rjs config useStrict: true. Effectively this allows 'use strict;' on the modules that already have it. Use false to give a false on rjs, which strips them off and true to inject it on the once on the combined template or on each module in UMD/AMD/nodejs (even if modules already have it).

  useStrict: undefined

build.globalWindow

Allow global & window to be global === window, whether on nodejs or the browser. It works independently of build.runtimeInfo but it doesn't work if build.bare is true. It uses the IIFE that's enclosing modules to pass 'window' or 'global' respectively.

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

@note the global === window functionality is always true in 'combined' template - false-ing it makes no difference!

  globalWindow: true

build.injectExportsModule

Always inject exports, module as dependencies on AMD/UMD templates from modules that are originally AMD (it always inject them on originally nodejs/commonjs modules).

Having exports around solves the circular dependencies problem with AMD, so its enabled by @default as true.

@note with this commonjs trick (see it in requirejs docs), you can export only the plain {} that exports already points to, not a function or any other type.

@note uRequire fixes the AMD mandate that you still need to return exports or return module.exports that both point to {the:'module'} from the AMD factory (not just setting module.exports = {the:'module'}). With uRequire conversion and you can use exports as you normally do with nodejs/commonjs modules, and never return it even from AMD modules.

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

@note modules originally nodejs and converted to AMD/UMD always have exports, module injected anyway, and ALL converted modules always get a require dependency, so you never have declare any of the 3 stooges.

@optional changing the @default being true, would save a few bytes in each module definition, with the cost of falling into the circular dep trap and having to return exports etc. Advice is to leave it on, and never manually type define(['require', 'exports', 'module', ..], function(require, exports, module, ..){..} etc again!

@todo improve detection/injection of the 3 stooges.

  injectExportsModule: true

build.noRootExports

When true, it doesn't produce the boilerplate for exporting modules (& noConflict()). It ignores both :

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

  noRootExports: false

build.scanAllow

By default, ALL require('missing/NodeStyle/Dep') in your module are added on the dependency array define(['existingArrayDep',.., 'missing/NodeStyle/Dep'], ...).

Even if there is even one dep on [], runtime scan is disabled on RequireJs. If any require('dep1') is forgotten, your app will halt. uRequire adds them all to prevent this problem.

With scanAllow: true you allow require('') scan @ runtime (costs at starting up). This is meaningfull only for source modules that have no other define([]) deps (even injected), that is i.e. modules using ONLY require(''), either written as pure nodejs modules or AMD.

@note in combined-template, rjs / almond optmization scans and adds all requires on AMD define array, so its completelly useless.

@note: uRequire ignores scanAllow for modules with rootExports / noConflict(), bundle.dependencies.exports.bundle or injected deps. @todo why, can this be removed ?

@optional

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

  scanAllow: false

build.allNodeRequires

Pre-require all require('') deps on node, even if they aren't mapped to any parameters, just like they are pre-loaded as AMD define() array deps. It preserves the same loading order as on Web/AMD, with a trade off of a possible slower starting up (they are cached nevertheless, so you gain speed later).

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

  allNodeRequires: false

build.dummyParams

Add dummy params __dummy__param__n for deps that have no corresponding param in the AMD define array. Should not be needed but might solve some issues with dependencies not loading on nodejs.

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

  dummyParams: false

build.noLoaderUMD

Allow modules to execute and register their exports (as defined in [bundle.dependencies.exports.root] or rootExports), even when running without an AMD or CommonJS loader, i.e it runs on a browser via <script src='my/UMDModule.js'>. It works only:

  • on 'UMD' and 'UMDplain' templates.

  • if module has local/global dependencies only (eg 'underscore') and it has already load it self (eg as window._).

If the UMD module has bundle deps (eg 'my/models/Person') it needs an AMD loader and loading as <script src="require.js" data-main="MainModule">.

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

  noLoaderUMD: false

build.warnNoLoaderUMD

Provides a warning when a UMD module is loaded as <script>, but the build.noLoaderUMD generated code is missing.

@default true as a warning to new users, advice is to turn it off & save space (when you know AMD or CommonJs loader is present).

@see build.noLoaderUMD

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

  warnNoLoaderUMD: true

build.watch

Watch for changes in bundle files and reprocesses only changed ones.

The watch feature of uRequire works with:

@note at each watch event there is a partial build. The first time a partial build is carried out, a full build is automatically performed instead. You don't need (and shouldn't) perform a full build before the watched task (i.e dont run the urequire:xxx grunt task before running watch: xxx: tasks: ['urequire:xxx']). A full build is always enforced by urequire.

  watch: false

build.verbose

Print bundle, build & module processing information.

@type: Boolean

@todo: make it less verbose / work better with build.debugLevel

  verbose: false

build.debugLevel

Debug levels 1-100.

@todo: make it less verbose - reassign levels

  debugLevel: 0

build.continue

Dont bail out while processing when there are soft / module processing errors.

For example ignore an RC conversion error or a missing dependency and just do all the other modules.

@note: Not needed when build.watch is used - the continue behaviour is applied to build.watch.

  continue: false

build.optimize

Optimizes output files (i.e it minifies/compresses them for production).

@type

  • false: no optimization.

  • true: uses sane defaults of 'uglify2' to minify/compress.

  • 'uglify2' / 'uglify': specifically select either (with default settings). @note: 'uglify' works ONLY for 'combined' template, delegating options to r.js.

  • Object - just like 'uglify' or 'uglify2'.

@example

  • optimize: true - simplest, minifies with 'uglify2' defaults.

  • Passing options to uglify2, works the same on all templates & r.js optimization.

  optimize:
    uglify2:
      output: beautify: true
      compress: false
      mangle: false
  optimize: false
  _optimizers: ['uglify2', 'uglify']

build.out

Callback to pass you the converted content & dstFilename of each resource/module, instead of saving to filesystem under dstPath/dstFilename via FileResource.save().

@note: Its not working on the resources when 'combined' template is used, cause r.js optimizer doesn't yet work in-memory, so the files have to be saved for the r.js optimization to work.

@type function (dstFilename, converted){}

@default undefined - uses FileResource.save() instead.

  out: undefined

build.done

This is set by either urequireCMD or grunt-urequire to signify the end of a build.

@todo: NOT TESTED in user configs!

  done: (doneVal)-> console.log "done() is missing and I got a #{doneVal} on the default done()"

build.clean

Clean directory or destination files in build.dstPath.

@type booleanOrFilespecs

@derive arraysConcatOrOverwrite

clean rules

On every initial / full build:

If clean: 'true',

  • on non-combined template builds, the whole build.dstPath directory is removed before reading anyfiles, just like a grunt:clean task against the directory.

  • on combined template, only the combined.js file (and possible leftover temp directory) is deleted (cause your directory might contain other files).

If clean is a filesspec type (eg `clean: ['some/**/file.someext', '!', (f)-> f is 'dontDeleteMe.txt']), only files passing the filespecs filter are deleted in any case (along with any possible leftover combinedFile temp directory).

On subsequent partial builds, no files are deleted.

  clean: undefined

build.rjs

The [r.js config] https://github.com/jrburke/r.js/blob/master/build/example.build.js, when cobining with r.js (combined template).

Its keys are just _.defaults for urequire's idea about using r.js with combined template, so use with caution!

@stability 2

@example build: rjs: preserveLicenseComments: false

  rjs: undefined

Examples

Borrowed from the Grunt config with comments of uBerscore, which also powers uRequire.

The 'urequire: uberscore' task:

  • read from source, write to build

  • filters some filez

  • converts each module in path to UMD (the default)

  • copies all other files to build

  • injects losash dep as _ in each module

  • exports a global window._B with a noConflict()

  • injects a VERSION string inside the body of a file

  • adds a banner to main (ouside UMD template/minification)

  • cleans (deletes) dstPath before starting the build

  • watch changes, convert only what's really changed

# config is .json, .js, gruntjs task, .coffee, .yml, you name it
uberscore:                    # serves as 'name' & consequently 'main'
  path: 'source'
  dstPath: 'build'
  filez: ['**/*']             # can be RegExp, Function, exclusion etc
  copy: [/./]                 # copy non-converted files, only if changed
  main: 'uberscore'
  dependencies:
    exports:
      bundle: 'lodash': '_'   # _ will always be there for you
      root: 'uberscore': '_B' # _B will always be there for everyone
  resources: [                # simple manipulative concat
    [ '+inject:VERSION',      # isBeforeTemplate: true, i.e AST is parsed & a module is there!
      ['uberscore.js'],       # only on this module, inject the following
      (m)-> m.beforeBody = "var VERSION = '0.0.15';"]
  ]
  template: banner: "// uBerscore v0.0.15"
  clean: true
  watch: true

Now, lets derive from the above and:

  • Use 'combined' template

  • adds a banner on top of the main / build file

  • all modules go into one file that runs everywhere

dev:
  derive: ['uberscore']
  template:
    name: 'combined'
    banner: '// I am a banner that goes on top'
  dstPath: 'build/uberscore-dev.js'

Finally the 'urequire: min' task

  • derives all from 'urequire: dev', with differences:

  • filters some more filez

  • converts to a single uberscore-min.js with 'combined' template

  • injects deps (different than parent's)

  • manipulates each module:

    • removes all debuging code, matching skeletons

    • replaces 'lodash' with 'underscore' (for compatibility, mocking etc)

    • removes code (eg debug stuff ) and a dependency from a specific file.

  • disables runtime info, for all but one files

  • minifies the combined file, with some uglify2 options

min:
  derive: ['uberscore']
  filez: [ '!**deepExtend.coffee' ]
  dstPath: 'build/uberscore-min.js'
  dependencies:
   exports: bundle: [
      [null], 'underscore', 'agreement/isAgree']
   replace: 'underscore': ['lodash']
  resources: [
  [
     '+remove:debug/deb & deepExtend', [/./]
     (m)->
       # match each of these code *skeletons*
       for code in [ 'if (l.deb()){}', 'if (this.l.deb()){}',
                     'l.debug()', 'this.l.debug()']
         # replace with undefined, i.e delete
         m.replaceCode code
       # replace code & dep on a specific file
       if m.dstFilename is 'uberscore.js'
         m.replaceCode
           type: 'Property'
           key: {type: 'Identifier', name: 'deepExtend'}
         # actually remove this dependency
         m.replaceDep 'blending/deepExtend'
   ]
  ]
  runtimeInfo: ['!**/*', 'Logger.js']
  optimize: { uglify2: output: beautify: false }

Finally we easily configure our grunt-contrib-watch tasks

watch:
  UMD:
    files: ["source/**/*"]
    tasks: ['urequire: uberscore', 'urequire: spec', 'mocha']
  options: spawn: false