Configuring grunt for uglify - gruntjs

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.

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 less won't replace css file

I use grunt-contrib-less with grunt-contrib-watch to compile my less files automatically upon change.
When the css is not present, grunt compiles it ok. When a css already exists and watch sees the less file changed, the css file is not modified. I have to remove it every time and let grunt recreate it with the modifications.
less config:
less: {
options: {
banner: '<%= meta.banner %>'
},
dev: {
options: {
sourceMap: true,
sourceMapFileInline: true,
compress: true
},
src: '<%= meta.dev.less %>/main.less',
dest: '<%= meta.prod.css %>/main.css'
},
prod: {
options: {
plugins: [
new( require( 'less-plugin-clean-css' ) )( {
'advanced': true,
'compatibility': 'ie9'
} )
],
},
src: '<%= meta.dev.less %>/main.less',
dest: '<%= meta.prod.css %>/main.css'
}
},
I'm under Windows 10 and every user have the rights to modifiy/delete the files in my dist folder.
How can I let grunt modify the css file?
EDIT
watch config
watch: {
options: {
livereload: 6325
},
js: {
files: [ '<%= meta.dev.js %>/main.js', '<%= meta.dev.js %>/plugins/*.js' ],
tasks: [ 'newer:concat' ]
},
images: {
files: '<%= meta.dev.img %>/**/*.{png,jpg,gif,svg}',
tasks: [ 'newer:imagemin' ]
},
css: {
files: '<%= meta.dev.less %>/**/*.less',
tasks: [ 'newer:less:dev' ]
}
}
Registration
grunt.registerTask( 'default', [ 'less:dev', 'concat', 'imagemin', 'copy', 'watch' ] );
Grunt output (verbose)
>> File "dev\less\elements\menu.less" changed.
Initializing
Command-line options: --verbose
Reading "Gruntfile.js" Gruntfile...OK
Registering Gruntfile tasks.
Reading package.json...OK
Parsing package.json...OK
Initializing config...OK
Loading "Gruntfile.js" tasks...OK
+ default, prod
Running tasks: newer:less:dev
Loading "grunt-newer" plugin
Registering "D:\[...]\static\node_modules\grunt-newer\tasks" tasks.
Loading "newer.js" tasks...OK
+ any-newer, newer, newer-clean, newer-postrun
Running "newer:less:dev" (newer) task
Options: cache="D:\\[...]\\static\\node_modules\\grunt-newer\\.cache", override=undefined
Files: dev/less/main.less -> dist/css/main.css
No newer files to process.
Here's what happens:
you modify menu.less
watch detects that and runs newer:less:dev
less:dev uses file main.less as only source (not menu.less)
that file hasn't changed, so newer concludes it doesn't need to run the task again
I suppose main.less includes menu.less, but newer doesn't know it.
So my suggested fix would be to get rid of the newer part.
Have you added correct watch config for less ?
watch: {
less: {
files: ['less/**/*.less'], // which files to watch
tasks: ['less'],
options: {
nospawn: true
}
}
}
To run grunt with your profile : grunt.registerTask('myprofile', ['less:dev', 'watch']);

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.

Adding a task with in a task in a gruntfile

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

Where are JSHint errors logged?

I just started messing around with Grunt. I have a basic implementation running successfully, minifying my code and running JSHint.
It says 0 files lint free, which I've gathered means that all of the files it's checking have lint.
However, I've been googling for an hour, and somehwat incredibly, cannot figure out where the hell these errors are being saved.
Do I need to specify a logfile in the grunt config? I don't see anything like that in the JSHint or grunt documentation.
Gruntfile below, taken pretty much straight from Grunt's "Getting Started". I pulled out qunit because I don't currently have any tests -
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
// define a string to put between each file in the concatenated output
separator: ';'
},
dist: {
// the files to concatenate
src: ['spin/**/*.js'],
// the location of the resulting JS file
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: {
options: {
// the banner is inserted at the top of the output
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
},
jshint: {
// define the files to lint
files: ['gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
// configure JSHint (documented at http://www.jshint.com/docs/)
options: {
// more options here if you want to override JSHint defaults
"curly": true,
"eqnull": true,
"eqeqeq": true,
"undef": true,
globals: {
jQuery: true,
console: true,
module: true
}
}
},
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint']
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('test', ['jshint']);
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
};
0 files lint free does not mean that you have files which have errors, it means that zero files are checked!
the jshint-task will output errors to your console (including file, linenumber and column)
thats where you specify your files to check:
files: ['gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
if you change 'gruntfile.js' to 'Gruntfile.js' (case sensitive!) it should check your gruntfile (which you of course already have).

Resources