Awesome
gulp-define-module
The gulp define module plugin produces modules from an input source. It allows other plugins to offload module definition to a separate plugin. For consistency, the input source should contain a single JavaScript expression and should not contain a trailing semicolon.
An example input file to create a callable module:
{
start: function() {},
end: function() {},
version: "1.0"
}
Transformed to CommonJS/Node (defineModule('commonjs')
or defineModule('node')
):
module.exports = {
start: function() {},
end: function() {},
version: "1.0"
};
Transformed to AMD (defineModule('amd')
):
define([], function() {
return {
start: function() {},
end: function() {},
version: "1.0"
};
});
Transformed to ES6 (defineModule('es6')
):
export default {
start: function() {},
end: function() {},
version: "1.0"
};
Transformed to Hybrid (defineModule('hybrid')
):
(function(definition) {
if (typeof exports === 'object') { module.exports = definition(); } // CommonJS
else if (typeof define === 'function' && define.amd) { define([], definition); } // AMD
else { definition(); } // Browser
})(function() {
return {
start: function() {},
end: function() {},
version: "1.0"
};
});
Transformed to Plain (defineModule('plain')
):
{
start: function() {},
end: function() {},
version: "1.0"
};
To use the module simply include it in your gulp pipeline:
var emberEmblem = require('gulp-ember-emblem');
var defineModule = require('gulp-define-module');
gulp.task('templates', function(){
gulp.src(['client/templates/*.hbs'])
.pipe(emberEmblem())
.pipe(defineModule('commonjs'))
.pipe(gulp.dest('build/templates/'));
});
API
defineModule(type, [options])
type
Type: String
Default: bare
The desired output type. One of the following:
commonjs
- Produce CommonJS modulesnode
- Produce Node modules (alias forcommonjs
)amd
- Produce AMD moduleses6
- Produce ES6 moduleshybrid
- Produce hybrid modules that can be used in most environmentsplain
- Return an unmolested function definition
options.require
Type: Object
Default: {}
An object containing dependencies that should be imported for this module. This option is only
supported for commonjs
, node
, amd
, es6
and hybrid
modules. For other systems, you will have
to manage the dependency loading in another way.
The property name in the object should be the value of the variable that the dependency will be accessed from, and the property value should be the name of the dependency.
For instance, { Library: 'library' }
will produce:
CommonJS/Node
var Library = Library || require('library');
module.exports = {};
AMD
define(['library'], function(Library) {
return {};
});
ES6
import Library from "library";
Hybrid
(function(definition) {
if (typeof exports === 'object') { module.exports = definition(require('library')); } // CommonJS
else if (typeof define === 'function' && define.amd) { define(['library'], definition); } // AMD
else { definition(Library); } // Browser
})(function(Library) {
return {};
});
options.wrapper
Type: String
Default: false
Wrapper in which to wrap input modules. This wrapper will be processed through lodash.template with the following context:
gulp-handlebars, for instance, sets a wrapper of "Handlebars.template(<%= contents %>)"
.
options.context
Type: Object
or Function
Default: undefined
Extend the context that's used to process the wrapper. If you pass an object, it will simply be merged with the default context.
A function argument should have the signature function(context) { return {}; }
. The
default context will be passed to your function and you can return new values to add
to the context. For instance, you can create complex definitions on a per-file basis.
defineModule('plain', {
wrapper: 'MyApp.templates["<%= templateName %>"] = <%= contents %>',
context: function(context) {
var file = context.file;
var name = path.relative(file.cwd, file.path)
.slice(0, -path.extname(file.path).length)
.split(path.sep).join('.');
return { templateName: name };
}
})
This will result in a template file, app/view.js
with an empty function, function() {}
, being compiled to
MyApp.templates["app.view"] = function() {};
.
options.name
Type: Function
Default: undefined
This option only works with defineModule('amd',...)
and therefore has no effect on other module types.
This function receives the file path as argument and should return a
name for the amd
module. For example:
defineModule('amd', {
name: function(filePath) { return "moduleName"; }
})
If no naming function is present, an
anonymous amd
module will be created.
This can be used with Hogan, for example:
gulp.src('client/templates/**/*.mustache')
.pipe(hoganCompiler())
.pipe(rename(function(filePath) { filePath.extname = '.mustache.js' })
.pipe(defineModule('amd', {
require: {
Hogan: 'hogan'
},
name: function(filePath) {
return filePath.split(process.cwd() + '/')[1].replace('.js', '')
}
}))
.pipe(gulp.dest('build/templates/'));
This will result in the following template file:
define("build/templates/path/to/template.mustache", ["hogan"], function(Hogan) { ... })
For gulp plugin developers
Plugin developers can pass options on to this plugin so that users don't have to define values that may be the most common setup for modules.
To do so set the defineModuleOptions
on the file
object. This object will be merged with options that users pass in to their defineModule
pipe
(user's options take precedence). It's recommended that if you define wrapper in these options,
that you make it a single value from the context for usage simplicity.
For an example, see gulp-ember-emblem.
License
This project is distributed under the MIT license.