Grunt-amd-build is a grunt plugin providing you with a collection of tasks to help you optimize your AMD application. There are two main steps to optimize an AMD application:
-
Bundle all the AMD modules used by the application into a single file, called a module layer. Using a module layer allows the application to load faster by reducing the number of HTTP request to the server.
-
Minify javascript code to reduce the size of the download to the client.
Grunt-amd-build focus on the first point as there are already a lot of great Javascript minifier online. A minimal build process will be composed of 3 tasks:
-
amddepscan
/amddirscan
: calculates the list of modules to include, names the modules and processes plugin dependencies. -
amdserialize
: outputs the results of the previous task so they can be fed to a minifier. -
uglify
or any other minifier: take the results of the previous task and actually create the module layer.
Grunt-amd-build provides you with tasks #1 and #2 but you need to install a minifier to get task #3.
This separation in different tasks allows you easily customize a build. For example if you need to add a banner at the top of your layer you can use the corresponding uglify option like you would do for any non-AMD file.
This plugin requires Grunt 0.4.x
.
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.
The following commands will install the Grunt-amd-build plugin and a few other plugins that will be needed to setup a build.
$ npm install grunt-amd-build --save-dev
$ npm install grunt-contrib-uglify --save-dev
$ npm install grunt-contrib-copy --save-dev
$ npm install grunt-contrib-clean --save-dev
The build config is split into two common properties:
amdloader
: contains the amd loader config. You can find the documentation here for RequireJS.amdbuild
: contains the build configuration (mainly the output directory and the list of layers). This property is shared between the tasks and each tasks add its result to the corresponding layer object.
###Avoid optimization names that are outside the baseUrl
For example, if baseUrl
is "js/"
, and the build targets:
layers: [{
name: "layer.min",
include: ['../myjs/main']
}]
The optimization could overwrite or place files outside the output directory. For those cases, create a paths config to map that file to a local name, like:
paths: {
myjs: '../myjs'
}
then use:
layers: [{
name: "layer.min",
include: ['myjs/main']
}]
for the optimization target.
Note: Using a package with paths
configuration outside of baseUrl
to name a layer can result in the layer being written outside the results
directory.
For example, with the following configuration:
amdloader: {
baseUrl: "./js",
paths: {
common: "../../common"
}
},
amdbuild: {
layers: [{
name: "common/layer",
include: ["main"]
}]
}
the layer will be written to "results/" + "./js/" + "../../common/layer" + ".js"
, ie. to common/layer.js
, outside the results
directory.
A work around for this is to use a baseUrl referencing the highest parent directory that your app will access. With the previous config it could be:
amdloader: {
baseUrl: "../../app/src/js",
paths: {
common: "../../common"
}
},
amdbuild: {
layers: [{
name: "common/layer",
include: ["main"]
}]
}
here the layer would be written to results/app/src/js/../../common
or results/app/common
.
Note that the leading ../
in baseUrl
are removed so the result stay in the right directory.