You can follow along with the sample Gruntfile.
The example in this page assumes this setup:
└── src/
├── js/
│ ├── main.js
│ ├── one.js
│ └── two.js
├── Gruntfile.js
└── index.html
The main
module depends on one
and two
.
// A temporary directory used by amdserialize to output the processed modules.
var tmpdir = "../tmp/";
This directory will contain the source modified by grunt-amd-build tasks. Those files will then be minified and concatenated by UglifyJS.
// The final output directory.
var outdir = "../build/";
Uglify will write the minified files inside this directory. The plugin files that cannot be optimized are just copied from the temporary directory to this directory.
Note: Both paths are relative to the Gruntfile.
// The grunt.config property populated by amdserialize, containing the
// list of files to include in the layer.
var outprop = "amdoutput";
This is the name of the grunt config property that will be used to configure UglifyJS. This property will contain the list of files written to the temporary directory.
// The loader config should go here.
amdloader: {
baseUrl: "./js/"
}
The amdloader
property contains the requirejs configuration of your application.
This step should be just a copy paste of requirejs configuration.
Note: baseUrl
is relative to the Gruntfile.
// The common build config
amdbuild: {
// dir is the destination of processed files.
dir: tmpdir,
// List of layers to build.
layers: [{
name: "main.min",
include: [
"main"
]
}]
}
The amdbuild
property is the main configuration target shared by all Grunt-amd-build tasks.
Extensive documentation of each tasks can be found in the api documentation.
dir
: use the previously defined temporary directory to output the files processed by the build.layers
: describe all the layers and their dependencies. It is used by bothamddepsscan
andamddirscan
.
In this sample, the application have a single entry-point, main
.
Since it is specified in the include
field all its dependencies will be included in the layer.
The configuration written by amdserialiaze is used to configure UglifyJS.
// Config to allow Uglify to generate the layer.
uglify: {
options: {
banner: "<%= " + outprop + ".header%>"
},
dist: {
src: "<%= " + outprop + ".modules.abs %>",
dest: outdir + "<%= " + outprop + ".layerPath %>"
}
}
The banner configuration is mandatory as some plugins will write into this property.
A custom banner can be added by concatenating the string to the "<%= " + outprop + ".header%>"
.
For the full list of properties published by amdserialize
see the api documentation.
Notes:
- The configuration reference
outprop
using Grunt templates. They are evaluated just before the task is run so we are sure thatoutprop
is set. - If you want to use the source-map option in Uglify, you should keep the output of
amdserialize
in thebuildConfig.dir
directory. Otherwise the original sources will not be found.
The plugin files are in the temporary directory and are not in the layer so they need to be copied to the final output directory.
// Copy the plugin files to the real output directory.
copy: {
dist: {
expand: true,
cwd: tmpdir,
src: "<%= " + outprop + ".plugins.rel %>",
dest: outdir,
dot: true
}
}
Note that the plugins
property from amdserialize
output is used.
Just erasing the previous build result.
// Erase previous build.
clean: {
erase: [outdir]
}
This task define an end-to-end build.
// The main build task.
grunt.registerTask("amdbuild", function (amdloader) {
var name = this.name;
var layers = grunt.config(name).layers;
grunt.task.run("erase");
layers.forEach(function (layer) {
grunt.task.run("amddepsscan:" + layer.name + ":" + name + ":" + amdloader);
grunt.task.run("amdserialize:" + layer.name + ":" + name + ":" + amdloader + ":" + outprop);
grunt.task.run("uglify");
grunt.task.run("copy:plugins");
});
grunt.task.run("amdreportjson:" + name);
});
For each layer, it runs a construction task, then output the result using the serialization task, then this is combined by UglifyJS and the plugins are copied to the destination. This function is the reason of grunt-amd-build flexibility. The complete sample of Gruntfile shows how this function can be easily modified to create a custom build.
Load the plugins and define a shorthand
// Load the npm plugins
grunt.loadNpmTasks("grunt-amd-build");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-clean');