Grunt Speed: Directly Specifying Tasks vs Combining - gruntjs

With Grunt, when you are registering tasks, how much slower is it to use tasks you already registered, maybe with several subtasks of their own, versus using tasks straight from initConfig, or even writing the functions by hand in the registration? Here's an example:
How much slower would specifying grunt minify from the command line be here:
grunt.registerTask('minify', ['preprocessed', 'nonprocessed']);
gruntregisterTask('preprocessed', ['sass:convert', 'haml:convert']);
grunt.registerTask('nonprocessed', ['uglify', 'cssmin', 'htmlmin', 'phpmin']);
than if you created the minify task like this:
grunt.registerTask('minify', ['sass:convert', 'haml:convert', 'uglify', 'cssmin', 'htmlmin', 'phpmin']);
I have to believe there is at least some slowdown, as Grunt has to go through more steps to "see" the tasks at each level of abstraction, but I just want to know if it's something to worry about only with thousands of modules, tens of sub-tasks per task, etc. or if it'll affect smaller projects as well.

You can test this yourself by using time-grunt.
// Gruntfile.js
module.exports = function (grunt) {
// require it at the top and pass in the grunt instance
require('time-grunt')(grunt);
grunt.initConfig();
}
Personally I've never noticed any speed decrease by specifying more aliases rather than less, and if there is slowdown it'll be in milliseconds. It'd be interesting to see a full test suite though.

Related

How to run the same grunt task with different configurations (programmatically)?

I've trawled the web for the last 2 hours trying to figure out how to do this so I'm asking here. I've read the documentation but I can't find a good example and I think I may be implementing some sort of anti-pattern or I have missed something very basic but here goes.
I want to loop around an array and perform this task in each loop
grunt.task.run('string-replace:dist');
However, every time I run this loop I need a slightly different config. Different output folder, different replacement array etc etc
I have been changing the config like this.
grunt.config.set('string-replace.dist.options.replacements', translationsArray);
grunt.config.set('string-replace.dist.files.0.dest', 'dist/' + langCode + '/');
Here comes the problem. Grunt does not seem to execute tasks, wait for them to finish and then continue with your code. So it sets up the task for each loop but does not run it, then it changes the config for each loop overwriting the old config each time. Then it runs all the tasks with the last config. I just want to make Grunt execute the task, wait till its done, change the config, rinse and repeat.
Am I doing something really stupid? Grunt documentation seems to be desperately telling me its synchronous but this does not seem to be the case with grunt.task.run. I would also like to point out that I don't want to just register more tasks with the different options because I don't know how many times I might have to run this loop. It is controlled from elsewhere so it can be dynamic and data driven. Unless I'm supposed to register tasks dynamically?

Uglify directly or concat and uglify

I am using grunt to build my JS project. I see that the uglify plugin for grunt is capable of merging multiple JS files into a single file and uglify them. Given this feature, I am wondering if there is a need to use concat plugin at all. Can I directly use uglify. Is there something that i am missing.
Most tutorials seem to suggest that I must first use concat then uglify.
You don't need a separate concat tool. See the docs (under "Usage examples - Basic compression"). You just specify the files you want uglified, and it will concatenate them for you.

Compile, concat, and minify many source files during build process, with source maps

I'm trying to put together a Grunt task to build our JS assets as part of our build/deploy process. I'd characterize our needs as fairly standard, but serious (in that we need to support a real-world production app, not just a toy example).
We have a bunch of source files, some JavaScript, some CoffeeScript, in a bunch of separate files in a structured directory tree. We need to compile the CoffeeScript, and concatenate and minify all the code into several defined output files (i.e. all.js and vendor.js). And we need to end up with usable source maps to accompany this output that reflect the original source (the CS or JS files), preferably with embedded sourcesContent.
I'm having a surprisingly difficult time putting this together, and have yet to find an example of a Gruntfile that accomplishes all of these goals in a realistic build scenario. Has anyone accomplished this? It seems like almost any major Angular project that's building with Grunt would have a set of requirements that looks a lot like ours.
Right now I'm using grunt-contrib-coffee, grunt-contrib-concat, and grunt-contrib-uglify, and have something that's almost working but for all sorts of trouble with relative paths in the source maps. I've also run into problems with uglify not handling multiple source maps, and problems with each of those plugins having different capabilities when it comes to reading and generating source maps.

How should I structure my modules in order to make use of hbsfy and browserify?

I would like to use browserify and the hbsfy Handlebars transform to modularise the JavaScript in a web application I'm writing.
Using gulp, I set up tasks to run browserify and hbsfy to compile several js and hbs files into one using a source structure that grouped my modules:
/src
- /javascript
- app.js
- /module-one
- module-one.js
- module-one.hbs
- /moduleTwo
- module-two.js
- module-two.hbs
However this is problematic when referencing one module from another - requiring the use of brittle relative paths that would need updating if a module is moved or further nested.
substack wrote on Avoiding ../../../../../../.. in his (great) browserify handbook. There, he suggests storing app modules in a directory under node_modules.
Happily I set about doing this, but quickly ran into issues with hbsfy no longer compiling my templates. According to the docs, browserify will only transform top level files, and will only transform those in node_modules if the global option is set to true.
This fixed my problem, but the documentation states:
Use global transforms cautiously and sparingly, since most of the time
an ordinary transform will suffice.
I don't believe my use case is unusual - should I be storing my modules in a different manner? Or am I missing a piece of the puzzle?
I found a simple example in hbsfy itself which might be helpful to you https://github.com/epeli/node-hbsfy/blob/master/example/index.js
It depends on what is the framework you are looking at, if you are doing angularjs, you can see an example in https://github.com/mallim/sbangular/blob/master/src/main/resources/js/login/LoginCtrl.js
In this case, the specific code will be as follows:
app.run(['$templateCache', function($templateCache) {
$templateCache.put('login.html', require('./login.html') );
}]);
login.html is actually in the same folder as LoginCtrl.js

Run all Grunt SubTasks except one

I've a bunch of subtasks for grunt watch (e.g. grunt watch:styles, grunt watch:sprites, etc). Then many other tasks run grunt watch. I would like to exclude one task. Is there a way to specify that? Basically run all grunt watch subtasks except grunt watch:dist.
I know I could create another task and only specify the subtasks I'm actually interested on, however, if I add another subtask later, that means now I've to add it, so I would rather not do it that way.
Thanks
There might be a better way, but this is doing the trick for now:
grunt.registerTask('watch:basic', function () {
delete grunt.config.data.watch.dist;
grunt.task.run('watch');
});
Fortunately, in this case, I don't have other tasks that might run grunt watch:dist, so it's safe to simply remove the config, but I can think of other cases where this approach would create conflicts.

Resources