grunt-concat-in-order
Concatenates files respecting dependencies.
Getting Started
This plugin requires Grunt ~0.4.1
If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
npm install grunt-concat-in-order --save-dev
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
grunt;
The "concat_in_order" task
Overview
The concat_in_order
task extracts declared required dependencies as well as provided modules/classes from your javascript (or any other text) files. Having this dependency graph the task will perform topological sort and concatenate file so that all modules will be put after their required dependencies.
In your project's Gruntfile, add a section named concat_in_order
to the data object passed into grunt.initConfig()
.
grunt
Sample
Let's say you have 4 files in a lib
directory
- AUsingBaseBAndBaseA.js
/*start AUsingBaseBAndBaseA*/framwork;framwork;frameworkdeclare'module.UsingBaseBAndBaseA';var {};/*end AUsingBaseBAnddBaseA*/
- AUsingBaseA.js
/*start AUsingBaseA*/framwork;var {};/*end AUsingBaseA*/
- BaseA.js
/*start BaseA*/frameworkdeclare'module.BaseA';var {};/*end BaseA*/
- BaseBUsingBaseA.js
/*start BaseBUsingBaseA*/framwork;frameworkdeclare'module.BaseBUsingBaseA';frameworkdeclare'module.BaseB';var {};/*end BaseBUsingBaseA*/
Given the above configuration the task will produce build/concatenated.js
file with following content:
/*start BaseA*/frameworkdeclare'module.BaseA';var {};/*end BaseA*//*start BaseBUsingBaseA*/framwork;frameworkdeclare'module.BaseBUsingBaseA';frameworkdeclare'module.BaseB';var {};/*end BaseBUsingBaseA*//*start AUsingBaseA*/framwork;var {};/*end AUsingBaseA*//*start AUsingBaseBAndBaseA*/framwork;framwork;frameworkdeclare'module.UsingBaseBAndBaseA';var {};/*end AUsingBaseBAnddBaseA*/
File based
You can enable automatic addition of files with the following example. (notice the onlyConcatRequiredFiles : true) This is the same way of declaring dependencies used by juicer
files: {
'dist/mybuild.js': ['js/src/main.js']
},
options: {
extractRequired: function(filepath, filecontent) {
var workingdir = path.normalize(filepath).split(path.sep);
workingdir.pop();
var deps = this.getMatches(/\*\s*@depend\s(.*\.js)/g, filecontent);
deps.forEach(function(dep, i) {
var dependency = workingdir.concat([dep]);
deps[i] = path.join.apply(null, dependency);
});
return deps;
},
extractDeclared: function(filepath) {
return [filepath];
},
onlyConcatRequiredFiles: true
}
This will declare all files as modules using their filenames. In main.js you will typically have these depend statements:
/**
* @depend ../lib/jquery.js
* @depend otherfile.js
* @depend calculator/add.js
*/
You only need to specify the main.js and the other dependencies will be added automatically. As well as their dependencies etc.
If you want to add a file that isn't referenced anywhere you need to add it manually.
files: {
'dist/mybuild.js': ['js/src/main.js', 'js/src/unReferencedButWanted.js']
},
The option onlyConcatRequiredFiles will only work if modules are declared and required with their actual filenames.
Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.
Release History
- 0.1.6 - @mokkabonna updated documenation and fixed path splitting in sample
- 0.1.4 - @mokkabonna added ability to concat only files that are required by some module