Adding a task with in a task in a gruntfile - gruntjs

I have gruntfile as below:
concat: {
options: {
banner: '<%= banner %>',
stripBanners: true
},
one: {
src: ['src/**/*.js'],
dest: 'dist/<%= pkg.name %>_ac.js'
},
two: {
src: ['/types/**/*.js'],
dest: 'dist/<%= pkg.name %>_lib.js'
},
all: {
}
},..... and so on
Now if i register the task like:
grunt.registerTask('basic', ['concat:all']);
I want both one and two to run. How shall i add this option in
all: {
// what i need to add here to include one and two both?
}

No need to add another target if you're registering a task to point to two targets. Just do:
grunt.registerTask('basic', ['concat:one', 'concat:two']);
Otherwise if you're intending on concatenating the files from one and two all together do:
grunt.initConfig({
concat: {
one: {
src: ['src/**/*.js'],
dest: 'dist/<%= pkg.name %>_ac.js'
},
two: {
src: ['/types/**/*.js'],
dest: 'dist/<%= pkg.name %>_lib.js'
},
all: {
src: ['<%= concat.one.src %>', '<%= concat.two.src %>'],
dest: 'dist/<%= pkg.name %>_all.js'
}
}
});

Grunt allow you to define the main target. So in your default target define as
grunt.registerTask( 'basic',['concat']);
This will activate the concat:one and concat:two.
If you need to activate a specific target, define your register task as follows.
grunt.registerTask( 'basic',['concat:one']);
If you need to run the specific task which has multiple targets then you can define as follows.
all: {
tasks: ['one','two']
}
Then in your registerTask call the all target.
grunt.registerTask( 'basic',['concat:all']);
Hope this might help.

You can use 'gruntfile' plugin where you are provided with more powerful functionality and you can add tasks of one grunt file to another using concat.
Refer the link : https://github.com/shama/gruntfile

Related

How to use array variable properly in gruntfile.js

Trying to use a predefined array inside of a grunt file, thought using this.js_paths would work, but doesn't seem to work as I'm getting the error, "Cannot read property IndexOf of undefined" when it comes to trying to uglify the scripts. How can I link the js_paths variable to the files src property properly instead of copying the array into the files. Would like to define it separately at the top. Is this possible?
module.exports = function(grunt) {
// loadNpmTasks from package.json file for all devDependencies that start with grunt-
require("matchdep").filterDev("grunt-*", './package.json').forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
js_paths: [
'inc/header1/js/*.js',
'!inc/header1/js/*.min.js',
'inc/header2/js/*.js',
'inc/header2/js/*.js',
'!inc/header2/js/*.min.js',
'js/*.js',
'!js/*.min.js'
],
uglify: {
options: {
mangle: true
},
build: {
files: [{
expand: true,
src: this.js_paths,
rename: function(dst, src) {
return src.replace('.js', '.min.js');
}
}]
}
},
watch: {
scripts: {
files: ['inc/header1/js/*.js', 'inc/header2/js/*.js', 'js/*.js'],
tasks: ['uglify'],
options: {
spawn: false,
}
}
}
});
grunt.registerTask('default', ['uglify', 'watch']);
};
Preferrably would like to use the same array js_paths in the watch files (since it's required there), if that makes sense? Still kinda new to using gruntfile.js
Utilize the Templates syntax. It's described in the docs as following:
Templates
Templates specified using <% %> delimiters will be automatically expanded when tasks read them from the config. Templates are expanded recursively until no more remain.
Essentially, change this.js_paths to '<%= js_paths %>' in your uglify task.
For instance:
// ...
uglify: {
options: {
mangle: true
},
build: {
files: [{
expand: true,
src: '<%= js_paths %>', // <-----
rename: function(dst, src) {
return src.replace('.js', '.min.js');
}
}]
}
},
// ...
Likewise for your watch task too.
For instance:
watch: {
scripts: {
files: '<%= js_paths %>', // <-----
tasks: ['uglify'],
options: {
spawn: false,
}
}
}

Grunt uglify. How to minify and replace original file with result?

We're using grunt for dev and prod. For dev we don't perform uglify but for prod we do. Unfortunately I can't change references to script from something like this "script.js" to "script.min.js".
I've tried grunt task like this for prod environment but it is not work:
// uglify
uglify: {
options: {
drop_console: true
},
componet: {
src: [componet.path + 'script.js'],
dest: componet.path + 'script.js'
},
}
What is the best workflow to change content "script.js" with uglified version?
Try with this:
uglify: {
options: {
},
main: {
files: [{
expand: true,
src: ['yourpath/**/*.js'],
dest: ''
}]
}
}
There are different possibilities to define the grunt task, here some examples:
uglify: {
options: {
drop_console: true
},
componet: {
files: [
// map one to one
{ 'path/to/minimized01.min.js': 'path/to/source01.js' },
{ 'path/to/minimized02.min.js': 'path/to/source02.js' },
// concat several sources into a minimized destination
{ 'path/to/minimized03and04.min.js': [ 'path/to/source03.js', 'path/to/source04.js' ]},
// map all files in a folder, one to one into a destination
{ expand: true,
cwd: 'path/to/a/source/folder',
src: [ '**/*.js', '!excludeThisFile.js' ],
dest: 'path/to/a/destination/folder',
ext: 'min.js' // if you want to change each extension to min.js
}
]
}
}
And then you can run it as grunt uglify:component... I always set separate tasks for development and production, for development I'd suggest using uglify, without dropping console, and use beautify option... Even better if you use source mapping, its very useful for debugging in browsers.

How to refresh package.json file after git pull in a grunt task?

I have a grunt file which does the following tasks in order:
Pefrorm a git pull command (grunt-shell)
Uglify all the javascript files defined in package.json file (grunt-uglify)
Concatanate all the uglified javascript files (grunt-concat)
The problem here is, sometimes, pulled commit may have some changes in package.json. Grunt caches package.json in the beginning of tasks so package.json is not affected by git pull which means grunt performs task according to old package.json file.
I'm looking for a solution which refreshes the cached package.json file so I it will run after git pull as expected.
Edit: You can find the whole process here
Here is the snippet I read files from package json:
uglify: {
options: {
report: 'gzip',
compress: true,
banner: '<%= banner %>',
},
mangle: {
toplevel: false
},
squeeze: {
dead_code: false
},
codegen: {
quote_keys: true
},
dist: {
files: {
'<%= pkg.dirs.js.dist.min %>': '<%= pkg.dirs.js.dist.src %>'
}
}
}
concat: {
js: {
options: {
banner: '<%= banner %>',
stripBanners: true,
separator: ';\n'
},
src: '<%= pkg.dirs.js.dev %>',
dest: '<%= pkg.dirs.js.dist.src %>'
},
css: {
options: {
banner: '<%= banner %>',
stripBanners: true,
separator: ' \n'
},
src: '<%= pkg.dirs.css.dev %>',
dest: '<%= pkg.dirs.css.dist.src %>'
}
}
This is something I don't think you can do simply from the basic config, I think you may need a custom task. The reason I say this is that you have to re-read the package.json file somehow, and there isn't a way to do that in the config (that I know of). So, instead, we can create a simple custom task that reads in the package.json file in between tasks 1 and 2. I wrote up a couple blog posts on custom tasks if you want to read up on it more.
Here's what I would do for the custom task:
grunt.registerMultiTask('readpkg', 'Read in the package.json file', function() {
grunt.config.set('pkg', grunt.file.readJSON('./package.json'));
});
Then we need to set up our multi-task for your setup:
grunt.registerMultiTask('build', [ 'shell', 'readpkg', 'uglify:dist', 'concat:js' ]);
Obviously you may need to tweak those tasks. You can leave the initial reading of the package.json file in your Gruntfile.js config, it should just be overwritten by the readpkg task.

grunt-string-replace: replace string in all files in a directory and its subdirectories

I would like to replace a string using grunt-string-replace in all files that are in a directory and its subdirectories
For example in all these files:
dist/templates_and_modules/templates/template1/template1.php
dist/templates_and_modules/templates/template2/template2.php
dist/templates_and_modules/modules/module1.php
dist/templates_and_modules/modules/module1.php
I want to replace
/*remove->*/
with:
/*
and
/*<-remove*/
with
*/
With explicitly defined files it works:
strrep: {
dist: {
files: {
'<%= yeoman.dist %>/templates_and_modules/templates/template1/template1.php':
'<%= yeoman.dist %>/templates_and_modules/templates/template1/template1.php'
},
options: {
replacements: [
{
pattern: '/*remove->*/',
replacement: '/*'
},
{
pattern: '/*<-remove*/',
replacement: '*/'
}
]
}
}
}
But I can not get it to work with all files in a directory.
By trial and error, I found out that this works:
files: {
'./': 'dist/**/*.*'
}
But I don’t understand, why.
You should be able to use globbing patterns to define which files & folders it processes.
See also the Files section of Configuring Tasks
Something like this:
src: [ '<%= yeoman.app %>/templates_and_modules/**/*.php' ]
dest: '<%= yeoman.dist %>/templates_and_modules/'
However, that plugin appears to be designed to copy files out to a new destination, not modify them in-place as you are trying to do. Here's a full example that copies them out to a new location:
module.exports = function(grunt) {
grunt.initConfig({
'string-replace': {
dist: {
src: './app/mylibs/**/*.js',
dest: './dist/mylibs/',
options: {
replacements: [{
pattern: 'old',
replacement: 'new'
}]
}
}
}
});
grunt.loadNpmTasks('grunt-string-replace');
grunt.registerTask('default', ['string-replace']);
};

Configuring grunt for uglify

I am using gruntfile for running uglify task for 2 separate modules. Both the modules are configured in the same gruntfile as:
uglify:
{
ac: {
dist: {
options: {
mangle: false, // Separate target for mangled output
report: 'min', // Reports actual minified size
banner: '<%= banner %>'
},
files: {
'dist/<%= pkg.name %>_ac.min.js': ['<%= concat.ac.dest %>']
}
},
mangled: {
options: {
mangle: true,
report: 'gzip',
banner: '<%= banner %>'
},
files: {
'dist/<%= pkg.name %>_ac.2.min.js': ['<%= concat.ac.dest %>']
}
}
},
lib: {
files: {
'dist/<%= pkg.name %>_lib.min.js': ['<%= concat.lib.dest %>']
},
mangled: {
files: {
'dist/<%= pkg.name %>_lib.2.min.js': ['<%= concat.lib.dest %>']
}
}
},
}
grunt.registerTask('ac', ['uglify:ac:dist']);
When i run the above grunt file, it runs without any error but i dont get any output. I am not sure if my way of configuring is correct.
Okay here's my answer from the limited info in the question;
The way you have your Gruntfile.js file set up it is looking for files in a concat task which you don't seem to have included. If it can't find these files it wont output anything.
My guess is that you copied some of this from the sample gruntfile.
Specifically this section ['<%= concat.ac.dest %>'] is explained in the documentation:
This tells uglify to create a file within dist/ that contains the
result of minifying the JavaScript files. Here I use <%=
concat.dist.dest %> so uglify will minify the file that the concat
task produces.
If you don't have a concat task specified or being called, there will be no output files to run uglify on so there will be no output. Either check that concat is called with grunt.registerTask('ac', ['concat', 'uglify:ac:dist']); and is producing output (if you have a tast set up) or change this to the location of the JS files you wish to uglify are.
'dist/<%= pkg.name %>_ac.min.js': ['/path/to/yourJavascriptFile.js']
Remove the dist task and have only
ac: {
options: {
mangle: false, // Separate target for mangled output
report: 'min', // Reports actual minified size
banner: '<%= banner %>'
},
files: {
'dist/<%= pkg.name %>_ac.min.js': ['<%= concat.ac.dest %>']
}
},
Hope concat.ac.dest is having the correct file name and the path. If you need to add more files you can add as
['src/input1.js', 'src/input2.js']
Fore more details refer https://github.com/gruntjs/grunt-contrib-uglify
Hope this would solve your issue.

Resources