In my Grunt file, I use usemin to analyze my index.html file build the concat schema, on top of which the other processes will occur.
Here is the Grunt file:
module.exports = function(grunt) {
// Load grunt tasks automatically.
require('load-grunt-tasks')(grunt);
// Configurable paths for the application.
var appConfig = {
src: require('./bower.json').appPath || 'src',
dist: 'dist'
};
grunt.initConfig({
settings: appConfig,
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= settings.dist %>/{,*/}*',
'!<%= settings.dist %>/.git*'
]
}]
},
tmp: {
src: '.tmp'
}
},
html2js: {
app: {
options: {
htmlmin: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true,
removeEmptyAttributes: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true
}
},
src: [ '<%= settings.src %>/app/**/*.tpl.html' ],
dest: '.tmp/concat/js/templates-app.js'
}
},
// Process all the .less files into a single css file.
less: {
process: {
files: {
".tmp/concat/css/less.css": "src/less/**/*.less"
}
}
},
concat: {
templates: {
src: ['.tmp/concat/js/app.js', '.tmp/concat/js/templates-app.js'],
dest: '.tmp/concat/js/app.js'
},
css: {
src: ['.tmp/concat/css/main.css', '.tmp/concat/css/less.css'],
dest: '.tmp/concat/css/main.css'
}
},
useminPrepare: {
html: '<%= settings.src %>/index.html',
options: {
// This is the folder which holds our build.
dest: '<%= settings.dist %>',
// This is the temp folder, which is used by "usemin", to prepare the build.
// It needs to be cleaned when finished.
}
},
usemin: {
html: '<%= settings.dist %>/index.html',
options: {
blockReplacements: {
less: function (block) {
return '<link rel="stylesheet" href="' + block.dest + '">';
}
}
}
},
copy: {
dist: {
files: [
{
src: '<%= settings.src %>/index.html',
dest: '<%= settings.dist %>/index.html'
},{
expand: true,
cwd: '<%= settings.src %>/assets',
src: ['**'],
dest: '<%= settings.dist %>/assets'
}
]
}
},
// Minifies everything after they have been copied.
htmlmin: {
dist: {
options: {
collapseWhitespace: true,
conservativeCollapse: false,
collapseBooleanAttributes: true,
removeCommentsFromCDATA: true,
removeOptionalTags: true
},
files: [{
expand: true,
cwd: '<%= settings.dist %>',
src: ['*.html', '**/*.tpl.html'],
dest: '<%= settings.dist %>'
}]
}
},
/**
* karma
*/
karma: {
unit: {
configFile: 'karma/karma.conf.js'
}
}
});
grunt.registerTask('build', [
'clean:dist',
'html2js:app',
'less:process',
'useminPrepare',
'concat:generated',
'concat:templates',
'concat:css',
'copy:dist',
'cssmin',
'uglify',
'usemin',
'htmlmin',
'clean:tmp'
]);
grunt.registerTask('test', [
'karma:unit'
]);
};
Here is the HTML file:
<!DOCTYPE html>
<html ng-app="app" ng-controller="AppCtrl">
<head>
<title ng-bind="pageTitle"></title>
<meta lang="en" charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- build:css css/main.css -->
<link rel="stylesheet" type="text/css" href="less/main.less">
<!-- endbuild -->
</head>
<body>
<div id="ng-view" ng-view></div>
<!-- build:js js/vendor.js -->
<script type="text/javascript" src="../vendor/angular/angular.js"></script>
<script type="text/javascript" src="../vendor/angular-route/angular-route.js"></script>
<script type="text/javascript" src="../vendor/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<!-- endbuild -->
<!-- build:js js/app.js -->
<script type="text/javascript" src="app/app.js"></script>
<script type="text/javascript" src="app/home/home.js"></script>
<script type="text/javascript" src="app/about/about.js"></script>
<!-- endbuild -->
<!-- build:js -->
<script type="text/javascript" src="app/templates-app.js"></script>
<!-- endbuild -->
</body>
</html>
The problem is, I use less.css
It looks like usemin does not recognize less files and does not include them in the flow.
What I did is a bit hackish - I have made a bogus main.css file in my src folder.
I used less plugin to process it and turn it into a css file, saving it, inside my .tmp folder.
// Process all the .less files into a single css file.
less: {
process: {
files: {
".tmp/concat/css/less.css": "src/less/**/*.less"
}
}
},
**Now when the file is in the .tmp folder, I have concatenated it with the bogus style.css that usemin see's from reading the index.html**
concat: {
templates: {
src: ['.tmp/concat/js/app.js', '.tmp/concat/js/templates-app.js'],
dest: '.tmp/concat/js/app.js'
},
css: {
src: ['.tmp/concat/css/main.css', '.tmp/concat/css/less.css'],
dest: '.tmp/concat/css/main.css'
}
},
And this allows me to add my data in the file which usemin will take through the flow.
grunt.registerTask('build', [
'clean:dist',
'html2js:app',
'less:process',
'useminPrepare',
'concat:generated',
'concat:templates',
'concat:css', // HERE WAS MY HACK, CONCAT IT BEFORE COPYING INTO THE DIST FOLDER
'copy:dist',
'cssmin',
'uglify',
'usemin',
'htmlmin',
'clean:tmp'
]);
This works, but it's pretty hackish... anybody has a elegant solution?
I mean, it should be able to append a file that was generated later to the usemin flow.
Any ideas?