grunt-angular-templates
Speed up your AngularJS app by automatically minifying, combining, and automatically caching your HTML templates with
$templateCache
.
Here's an example of the output created by this task from multiple .html
files:
angular.module('app').run(["$templateCache", function($templateCache) {
$templateCache.put("home.html",
// contents for home.html ...
);
...
$templateCache.put("src/app/templates/button.html",
// contents for button.html
);
}]);
Then, when you use ng-include
or templateUrl
with $routeProvider
, the template is already loaded without an extra AJAX request!
Table of Contents
Installation
This plugin requires Grunt ~0.4.0
Usemin integration requires grunt-usemin ~2.0.0
Install the plugin:
$ npm install grunt-angular-templates --save-dev
Enable the plugin within your Gruntfile
:
grunt.loadNpmTasks('grunt-angular-templates');
Options
angular
Global namespace for Angular.
If you use angular.noConflict()
, then set this value to whatever you re-assign angular to. Otherwise, it defaults to angular
.
bootstrap
Callback to modify the bootstraper that registers the templates with
$templateCache
.
By default, the bootstrap script wraps function($templateCache) { ... }
with:
angular.module('app').run(['$templateCache', ... ]);
If you want to create your own wrapper so you register the templates as an AMD or CommonJS module, set the bootstrap
option to something like:
bootstrap: function(module, script) {
return 'module.exports[module] = ' + script + ';';
}
concat
Name of
concat
target to append the compiled template path to.
This is especially handy if you combine your scripts using grunt-contrib-concat or grunt-usemin.
htmlmin
Object containing htmlmin options that will significantly reduce the filesize of the compiled templates.
Without this, the HTML (whitespace and all) will be faithfully compiled down into the final .js
file. Minifying that file will only cut down on the Javascript code, not the HTML within the strings.
Note - this does incur a performance cost. Simply leave out this option to prevent minificaiton.
I recommend using the following settings for production:
htmlmin: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
keepClosingSlash: true, // Only if you are using SVG in HTML
removeAttributeQuotes: true,
removeComments: true, // Only if you don't use comment directives!
removeEmptyAttributes: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true
}
module
String
of theangular.module
to register templates with.
If not specified, it will automatically be the name of the ngtemplates
subtask (e.g. app
, based on the examples below).
prefix
String
to prefix template URLs with. Defaults to''
If you need to use absolute urls:
ngtemplates: {
app: {
options: {
prefix: '/'
}
}
}
If you serve static assets from another directory, you specify that as well.
source
Callback to modify the template's source code.
If you would like to prepend a comment, strip whitespace, or do post-processing on the HTML that ngtemplates
doesn't otherwise do, use this function.
append
Boolean to indicate the templates should be appended to dest instead of replacing it. Normally grunt-angular-templates creates a new file at
dest
. This option makes it append the compiled templates to thedest
file rather than replace its contents. This is just a useful alternative to creating a temporarydest
file and concatting it to your application.
standalone
Boolean indicated if the templates are part of an existing module or a standalone. Defaults to
false
.
- If the value is
false
, the module will look likeangular.module('app')
, meaningapp
module is retrieved. - If the value is
true
, the module will look likeangular.module('app', [])
, meaningapp
module is created.
url
Callback to modify the template's
$templateCache
URL.
Normally, this isn't needed as specifying your files with cwd
ensures that URLs load via both AJAX and $templateCache
.
usemin
Path to
<!-- build:js [path/to/output.js] -->
usemin target
This should be the output path of the compiled JS indicated in your HTML, such as path/to/output.js
shown here.
quotes
Use single or double quotes to wrap the template strings
Defaults to 'double', other option is 'single'
Usage
Compiling HTML Templates
After configuring your ngtemplates
task, you can either run the task directly:
$ grunt ngtemplates
Or, bake it into an existing task:
grunt.registerTask('default', [ 'jshint', 'ngtemplates', 'concat' ]);
Including Compiled Templates
Finally, you have to load the compiled templates' .js
file into your application.
Using HTML
<script src="templates.js"></script>
Using Grunt's concat
task:
This is my personal preference, since you don't have to worry about what the destination file is actually called.
concat: {
app: {
src: [ '**.js', '<%= ngtemplates.app.dest %>' ],
dest: [ 'app.js' ]
}
}
Using grunt-usemin
Using the following HTML as an example:
<!-- build:js dist/vendors.js -->
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
<!-- endbuild -->
Do not use the concat
option, even though grunt-usemin generates a concat.generated
object behind the scenes. Instead, use the usemin
option to indicate the anticipated output filepath from grunt-usemin.
ngtemplates: {
app: {
src: '**.html',
dest: 'template.js',
options: {
usemin: 'dist/vendors.js' // <~~ This came from the <!-- build:js --> block
}
}
}
Note: Earlier versions of grunt-usemin (correctly, in my opinion) would have generated a concat['dist/vendors.js']
object for each build section in the HTML. Now, because there's a single concat.generated
object with all JS/CSS files within it, I'm back-tracking the proper concat
target for you.
Examples
Register HTML Templates in app
Module
ngtemplates: {
app: {
src: '**.html',
dest: 'templates.js'
}
}
Register Relative Template URLs
Normally, your app, templates, & server are in separate folders, which means that the template URL is different from the file path.
ngtemplates: {
app: {
cwd: 'src/app',
src: 'templates/**.html',
dest: 'build/app.templates.js'
}
}
This will store the template URL as templates/home.html
instead of src/app/templates/home.html
, which would cause a 404.
Minify Template HTML
Simply pass the same options as the htmlmin
task:
ngtemplates: {
app: {
src: '**.html',
dest: 'templates.js',
options: {
htmlmin: { collapseWhitespace: true, collapseBooleanAttributes: true }
}
}
}
Or, if you already have an existing htmlmin
task, you can reference it:
ngtemplates: {
app: {
src: '**.html',
dest: 'templates.js',
options: {
htmlmin: '<%= htmlmin.app %>'
}
}
}
Customize Template URL
Suppose you only use ngtemplates
when on production, but locally you serve templates via Node, sans the .html
extension.
You can specify a url
callback to further customize the registered URL:
ngtemplates: {
app: {
src: '**.html',
dest: 'templates.js',
options: {
url: function(url) { return url.replace('.html', ''); }
}
}
}
Customize Output
Some people like AMD & RequireJS and would like wrap the output in AMD or something else (don't ask me why!):
ngtemplates: {
app: {
src: '**.html',
dest: 'templates.js',
options: {
bootstrap: function(module, script) {
return 'define(' + module + ', [], function() { return { init: ' + script + ' }; });';
}
}
}
}
You will be able to custom everything surrounding $templateCache.put(...)
.
Changelog
- v1.1.0 - Added the
merge
option to allow templates to maintain directory structure if set tofalse
(#114) - v1.0.4 - Updated html-minifier to 2.1.2 (#162)
- v1.0.3 - Fixes issue with using usemin without uglify (#153)
- v1.0.2 - Fixes issue with escaping carriage returns (#147), Fixes issue with escaping backslashes (#146)
- v1.0.1 - Log error instead of warning when minify fails (#139)
- v1.0.0 - Updated unit tests for performance and bumps dependency versions (#143)
- v0.6.0 - Adds
quotes
options to allow wrapping in single instead of double quotes (#142) - v0.5.9 - Fixes over-matching on
cwd
whenexpand:true
- v0.5.8 - Fixes
cwd
being part of the $templateCache string whenexpand:true
(#134), Added verbose logging for minify (#136) - v0.5.7 – Improve error messages (#100)
- v0.5.6 – Updated
html-minifier
to correct whitespace issues. (96) - v0.5.5 – Add
append
option to concat, not overwrite thedest
. (#89) - v0.5.4 – Specifying an invalid
usemin
option still creates file (#84) - v0.5.3 – Fix bug with Underscore templates (#79)
- v0.5.2 – Fix
usemin
matching issue on Windows (#80) - v0.5.1 – Add
usemin
option form v0.4.10 - v0.5.0 – Works with
grunt-usemin
(#44) - v0.4.10 – Add
usemin
option - v0.4.9 – Improve
prefix
and support for URLs (#57) - v0.4.8 – Compiled assets are JSHint-able (#58)
- v0.4.7 – Fix bug for when htmlmin is not an Object (#56)
- v0.4.6 – Add
prefix
option for easier URL prefixes (#53) - v0.4.5 – Attempt to better normalize templates based on current OS (#52)
- v0.4.4 – Fixed regression caused by
htmlmin
(#54) - v0.4.3 -
options.concat
targets on Windows convert/
to\\
. #48 - v0.4.2 - Fix for using
grunt-env
to change environments. Thanks to @FredrikAppelros (#20) - v0.4.1 – Fix bug with empty files.
- v0.4.0 – Complete rewrite.
- v0.3.12 – Whoops, forgot to make
htmlmin
a regular dependency. Thanks @rubenv (#37) - v0.3.11 – Add
htmlmin
option that supports both an{ ... }
and<%= htmlmin.options %>
for existing tasks. - v0.3.10 – Fix unknown concat target bug on windows, thanks to @trask (#31)
- v0.3.9 – Allow the creation of a new module via
module.define
, thanks to @sidwood (#28) - v0.3.8 – Fix error that occurs when adding 0-length files, thanks to @robertklep (#27)
- v0.3.7 – Add
noConflict
option to work with angular.noConflict, thanks to @mbrevoort (#26) - v0.3.6 – Fix issue with dading to
concat
task when it's an array, thanks to @codefather (#23) - v0.3.5 – Preserver line endings in templates, thanks to @groner (#21)
- v0.3.4 – Attempt to fix a bug with
Path
, thanks to @cgross (#19) - v0.3.3 – Add
concat
option for automatically adding compiled template file to existingconcat
(orusemin
-created) task, thanks to @cgross (#17) - v0.3.2 – Add
module
option for setting which module the templates will be added to, thanks to @sidwood (#20) - v0.3.1 – Add
prepend
option for modifying final$templateCache
IDs, thanks to @mbarchein. (#16) - v0.3.0 – BC break - Templates are added to an existing module (e.g.
myapp
) rather than being their ownmyapp.templates
module to be manually included, thanks to @geddesign. (#10) - v0.2.2 – Escape backslashes, thanks to @dallonf. (#9)
- v0.2.1 – Remove
./bin/grunt-angular-templates
. No need for it! - v0.2.0 – Update to Grunt 0.4, thanks to @jgrund. (#5)
- v0.1.3 – Convert
\\
to/
in template IDs (for on win32 systems) (#3) - v0.1.2 – Added NPM keywords
- v0.1.1 – Fails to combine multiple templates. Added directions to README on how to integrate with AngularJS app. Integrated with TravisCI
- v0.1.0 – Released to NPM
License
Copyright (c) 2013 Eric Clemmons Licensed under the MIT license.