Changing grunt uglify config options on watch - gruntjs

I'm trying to alter my default uglify dev options on 'watch', however they're not getting set. I'm planning on adding more subtasks to the uglify task for 'production' as an example, which will use the default options, however for my 'dev' subtask, i'd like to pass new options with the watch task.
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
// ...
uglify: {
// default options
options: {
banner: '<%= banner %>/* Built <%= grunt.template.today("yyyy/mm/dd") %> for <%= powerful.name %> */\n',
preserveComments: 'some',
report: 'min',
mangle: {
except: ['jQuery', 'Backbone']
}
},
dev: {
// options were here...
files: {
// Powerful Theme JS
'<%= powerful.jspath %>touch.min.js':
[
'<%= powerful.jspath %>libs/jquery.hammer.js',
'<%= powerful.jspath %>dev/touch.js'
],
'<%= powerful.jspath %>768down.min.js':
[
'<%= powerful.jspath %>dev/768down.js'
]
}
},
production: {
// production files here, use default options....
}
},
watch: {
js: {
files: ['<%= themesPath %>/**/js/{dev,libs,bootstrap}/*.js'],
tasks: ['uglify:dev'],
options: {
nospawn: true
}
}
}
});
// ...
grunt.event.on('watch', function(action, filepath) {
grunt.config.set('uglify.dev.options', {
banner: '/*! TESTING 123 */',
preserveComments: 'all',
report: false,
compress: false,
beautify: true
});
});
grunt.registerTask('default', ['watch']);
};

Related

Grunt: How do I run seperate processes for CSS and JS

As you can see I have tasks for CSS ['sass:main'] and for JS ['jshint:main', 'concat:main', 'uglify:main'], but I want to do separate tasks for separate files (JS and CSS) and listen for changes (watch). Can someone point me in the correct direction, I'm not really sure what I should be searching for. Is this something that watch can handle, or is there another plugin? I'm a little new to grunt so still trying to figure out how to use it. Thanks
GruntFile.js:
module.exports = function(grunt) {
var config = {
pkg: grunt.file.readJSON('package.json'),
jshint: {
options: {
globals: {
jQuery: true,
console: true,
module: true,
document: true
}
},
main: {
src: [
'assets/templates/main/js/crm/*.js',
]
}
},
concat: {
options: {
separator: '\n\n'
},
main: {
src: [
'assets/templates/main/js/crm/*.js',
],
dest: 'assets/templates/main/js/crm.min.js'
}
},
sass: {
options: {
style: 'compressed'
},
main: {
files: {
'assets/templates/main/css/main.min.css': 'assets/templates/main/sass/main.scss',
}
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
main: {
src: 'assets/templates/main/js/crm.min.js',
dest: 'assets/templates/main/js/crm.min.js'
}
},
watch: {
mainjs: {
files: ['assets/templates/main/js/crm/*.js'],
tasks: ['jshint:main', 'concat:main', 'uglify:main'],
},
mainsass: {
files: ['assets/templates/main/sass/*.scss''],
tasks: ['sass:main'],
}
},
concurrent: {
maincss: ['sass:main'],
mainjs: ['jshint:main', 'concat:main', 'uglify:main']
}
};
grunt.initConfig(config);
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-concurrent');
grunt.registerTask('main', ['jshint:main', 'concat:main', 'uglify:main', 'sass:main']);
grunt.registerTask('main-watch', ['jshint:main', 'concat:main', 'uglify:main', 'sass:main', 'concurrent:mainsass']);
};
When I try run tasks:
$ grunt main-watch
Loading "Gruntfile.js" tasks...ERROR
SyntaxError: Invalid or unexpected token
Warning: Task "main-watch" not found. Use --force to continue.
Aborted due to warnings.
It sounds like you want to perform two concurrent watch tasks. You can do that using a configuration like this:
...
concurrent: {
options: { logConcurrentOutput: true },
watch: ['watch:mainjs', 'watch:mainsass']
}
};
...
grunt.registerTask('main-watch', ['concurrent:watch']);
Note that logConcurrentOutput defaults to false, so if you want to see output logged to the console, you need to set it to true.

Grunt Watch not creating files on save

The tasks in my grunt file are running without errors but the files i'm asking it to create aren't being compiled. They are created if I simple run 'grunt' but if I use 'grunt watch' and save a file it doesn't update.
Particularly I am working on file 'script/src/latestNews.js' so on save this should concat with others to create 'script/dist/main.js', which it does. But it does not then go on to create 'dist/build.min.js' like it should.
module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
mangle: false
},
target: {
files: {
'script/dist/main.min.js':'script/dist/main.js'
}
},
build: {
files: {
'script/dist/build.min.js':'script/dist/build.min.js'
}
}
},
concat: {
options: {
stripBanners: true,
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */',
},
srcJS: {
src: ['script/src/menu.js',
'script/src/custom_plugins.js',
'script/src/banner.js',
'script/src/latestNews.js',
'script/src/officers.js',
'script/src/eventsCalendar.js',
'script/src/combinedSocialMedia.js',
'script/src/haveYourSay.js',
'script/src/photoGallery.js',
'script/src/countdown.js'
],
dest: 'script/dist/main.js'
},
css: {
src: ['style/libs/bootstrap.min.css',
'style/libs/bootstrap-theme.min.css',
'style/src/css/*'],
dest: 'style/dist/build.min.css'
},
build: {
src: ['script/libs/jquery.easing.min.js',
'script/dist/main.js',
'script/libs/bootstrap.min.js',
'script/libs/velocity.min.js',
'script/libs/date.js',
'script/libs/jquery.timeago.js',
'script/libs/owl.carousel.min.js'
],
dest: 'script/dist/build.min.js'
}
},
jshint: {
main: 'script/dist/main.js'
},
watch: {
js: {
files: 'script/src/*',
tasks: ['concat:srcJS', 'uglify:target', 'jshint:main', 'copy:js']
},
css: {
files: 'style/src/css/*',
tasks: ['copy:css']
},
less: {
files: 'style/src/less/*',
tasks: ['less', 'copy:css']
},
html: {
files: '*.html',
tasks: ['validation', 'bootlint']
}
},
clean: {
js: [
'script/dist/main.min.js',
'dist/build.min.js',
'dist/build.min.css'
]
},
copy: {
css: {
files: [
{ expand: true, 'src' : 'style/src/css/main.css',
'dest' : 'style/dist/', flatten: true,
rename: function(dest, src) {
return dest + src.replace('main','build.min');
}
},
{ expand: true, 'src' : 'style/dist/build.min.css',
'dest' : 'dist/', flatten: true },
]
},
js: {
files: [
{ expand: true, 'src' : 'script/dist/build.min.js',
'dest' : 'dist/', flatten: true }
]
}
},
validation: {
options: {
reset: grunt.option('reset') || false,
stoponerror: true,
relaxerror: ['Bad value X-UA-Compatible for attribute http-equiv on element meta.'] //ignores these errors
},
files: {
src: ['homepage.html']
}
},
bootlint: {
options: {
stoponerror: false,
relaxerror: ['E001', 'E003', 'E031', 'W001', 'W002', 'W003', 'W005', 'W007', 'W009', 'E013']
},
files: ['homepage.html'],
},
less: {
build: {
options: {
paths: ["style/src/less"],
cleancss: true,
compress: true
},
files: {
"style/src/css/main.css": "style/src/less/main.less"
}
}
}
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-html-validation');
grunt.loadNpmTasks('grunt-bootlint');
// Default task(s).
//grunt.registerTask('default', ['concat:srcJS','concat:css','uglify','jshint:main']);
grunt.registerTask('default', [
'validation',
'bootlint',
'concat:srcJS',
'jshint:main',
'uglify:target',
'clean',
'concat:build',
'uglify:build',
'less',
'copy'
]);
};
It looks like the array of tasks that are run by your watch:js task is simply missing a couple of critical tasks. Specifically you are not running the concat:build and uglify:build tasks.
Your current array of tasks:
['concat:srcJS', 'uglify:target', 'jshint:main', 'copy:js']
Complete/fixed array of tasks:
['concat:srcJS', 'uglify:target', 'jshint:main', 'concat:build', 'uglify:build', 'copy:js']
Replacing your current array with the fix that I supplied should solve your issue.

Why my grunt autoprefixer does not work?

I don't know why but this code stopped working after a while. It is minifing the code but does not add any vendor prefixes. I would also like to add another files to css like normalize but it didn't work either.
Here is the code:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
dist: {
options: {
banner: '/*! <%= pkg.name %> <%= pkg.version %> filename.min.js <%= grunt.template.today("yyyy-mm-dd h:MM:ss TT") %> */\n',
},
files: {
'js/scripts.min.js' : [
]
}
},
dev: {
options: {
banner: '/*! <%= pkg.name %> <%= pkg.version %> filename.js <%= grunt.template.today("yyyy-mm-dd h:MM:ss TT") %> */\n',
beautify: true,
compress: false,
mangle: false
},
files: {
'js/scripts.js' : [
]
}
}
},
sass: {
dist: {
options: {
compass: true,
style: 'expanded'
},
files: [{
expand: true,
cwd: 'sass',
src: [
'style.scss'
],
dest: 'css',
ext: '.css'
}]
}
},
watch: {
styles: {
files: ['**/*.scss'],
tasks: ['style']
}
},
postcss: {
options: {
map: {
inline: false, // save all sourcemaps as separate files...
annotation: 'css/maps/' // ...to the specified directory
},
processors: [
require('pixrem')(), // add fallbacks for rem units
require('autoprefixer')({browsers: ['last 3 versions']}), // add vendor prefixes
require('cssnano')() // minify the result
]
},
dist: {
src: 'css/style.css',
dest: 'css/styles.min.css'
}
}});
Edit, I've included whole grunt file in the snippet.
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
dist: {
options: {
banner: '/*! <%= pkg.name %> <%= pkg.version %> filename.min.js <%= grunt.template.today("yyyy-mm-dd h:MM:ss TT") %> */\n',
},
files: {
'js/scripts.min.js' : [
]
}
},
dev: {
options: {
banner: '/*! <%= pkg.name %> <%= pkg.version %> filename.js <%= grunt.template.today("yyyy-mm-dd h:MM:ss TT") %> */\n',
beautify: true,
compress: false,
mangle: false
},
files: {
'js/scripts.js' : [
]
}
}
},
sass: {
dist: {
options: {
compass: true,
style: 'expanded'
},
files: [{
expand: true,
cwd: 'sass',
src: [
'style.scss'
],
dest: 'css',
ext: '.css'
}]
}
},
watch: {
styles: {
files: ['**/*.scss'],
tasks: ['style']
}
},
postcss: {
options: {
map: {
inline: false, // save all sourcemaps as separate files...
annotation: 'css/maps/' // ...to the specified directory
},
processors: [
require('pixrem')(), // add fallbacks for rem units
require('autoprefixer')({browsers: ['last 3 versions']}), // add vendor prefixes
require('cssnano')() // minify the result
]
},
dist: {
src: 'css/style.css',
dest: 'css/styles.min.css'
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-postcss');
// Default task(s).
grunt.registerTask('style', [
'sass',
'postcss'
]);
// Default task(s).
grunt.registerTask('default', [
'uglify:dist',
'sass',
'postcss',
'watch'
]);
};
I think the issue might be, that it doesn't support last 3 versions directive, that's why it doesn't add anything.
Here's the reference on the possible parameters autoperfixer processor might interpret: https://github.com/ai/browserslist
Try to use something alike:
last 2 versions
hopefully this help, as everything else seems to be correct.

Grunt concat not working during watch task

If I run 'grunt concat' it compiles my JS files as per the Grunt file (line 82). However, it doesn't concatenate when I'm doing 'grunt watch' (line 107).
From what I can see, my file is ok but I'm fairly new to grunt so would love to see if you guys can see an issue.
Here is my full Grunt file...
// All scripts to be included in project go here
var _SCRIPTS = [
'js/prefixfree.js',
'js/jquery-1-10-2.js',
'js/ie-detect.js',
'js/application.js'
];
var _PORT = 7777;
module.exports = function(grunt) {
// load all grunt tasks
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
connect: {
server: {
options: {
port: _PORT,
base: 'prototype'
}
}
},
htmlvalidation: {
options: {
},
files: {
src: ['prototype/*.php']
},
},
jshint: {
beforeconcat: _SCRIPTS,
afterconcat: ['js/main.js']
},
csslint: {
check: {
src: ['css/*.css']
},
strict: {
options: {
import: 2
},
src: ['css/*.css']
},
lax: {
options: {
import: false
},
src: ['css/*.css']
}
},
compass: {
dev: {
options: {
config: 'config.rb',
force: false
}
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'js/main.js': ['js/main.js']
}
}
},
concat: {
options: {
stripBanners: true,
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */',
},
dist: {
src: _SCRIPTS,
dest: 'js/main.js',
nonull: true
},
},
cssmin: {
add_banner: {
options: {
banner: '/* <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */',
},
files: {
'css/style.css': ['css/style.css']
}
}
},
watch: {
concat: {
files: ['js/**/*.js', '!js/main.js'],
tasks: 'concat',
options: {
spawn: false,
},
},
sass: {
files: ['sass/**/*.scss'],
tasks: ['compass:dev'],
options: {
spawn: false,
},
},
/* watch and see if our javascript files change, or new packages are installed */
/* watch our files for change, reload */
livereload: {
files: ['*.html', 'css/*.css', 'img/*', 'js/*.js'],
options: {
livereload: true
}
},
}
});
// Default task (Watch)
grunt.registerTask('default', ['watch']);
// grunt.registerTask('default', [ 'preprocess:dev', 'watch']);
// Watch with localhost (For Static Templates)
grunt.registerTask('watch_with_server', [ 'connect:server', 'watch']);
// TESTING
// Run all tests
grunt.registerTask('allTests', [ 'jshint:beforeconcat', 'concat', 'jshint:afterconcat', 'cssLint', 'htmlvalidation']);
// JS Testing
grunt.registerTask('jsHint', ['jshint:beforeconcat', 'concat', 'jshint:afterconcat']);
// CSS Testing csslint
grunt.registerTask('cssLint', ['csslint:check']);
grunt.registerTask('cssLintLax', ['csslint:lax']);
grunt.registerTask('cssLintStrict', ['csslint:strict']);
// HTML Vaidation
grunt.registerTask('htmlTest', [ 'htmlvalidation']);
grunt.registerTask('printenv', function () { console.log(process.env); });
// Concat and uglify js and minify css for release
grunt.registerTask('release', [ 'concat:dist', 'uglify', 'cssmin']);
};
Many thanks
I managed to get it working by moving 'livereload' above 'concat' in the watch task. No idea why this would make a difference but it's working!
If anyone has any insight on why this would affect it I'd love to know.
add this and see:
livereload: {
files: ['*.html', 'css/*.css', 'img/*', 'js/*.js'],
options: {
livereload: true
}
},
options: {
livereload: true
},
files: '<%= options.watch.files %>',//might have to change this line
tasks: ['default', 'notify:watch']

Grunt Multitask configuration issues

I'm trying to configure a grunt file that can run multiple tasks on multiple "themes". Since i'm new to this whole grunt thing, i'm having some problems with the configuration.
My example below is just a start, but essentially I'd like to have some global configs, and then nest specific "theme" configurations within a named "target". I'm not fully up to speed on syntax, so that could be the issue, but when I run grunt powerful I get the error Warning: Required config property "watch" missing? I feel that the configs are ok, but the problem lies with my registerMultiTask. Any ideas?
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
// Metadata.
pkg: grunt.file.readJSON('package.json'),
banner: '/*!\n' +
'* Microsites v<%= pkg.version %>\n' +
'* Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
'*/\n' +
'/* #package: <%= pkg.name %> */\n',
jqueryCheck: 'if (!jQuery) { throw new Error(\"<%= pkg.name %> requires jQuery\") }\n\n',
basePath: '../../www/wp-content/themes',
powerful: {
name: 'Powerful Theme',
path: '<%= basePath %>/powerful',
less: {
development: {
options: {
dumpLineNumbers: true
},
files: {
'<%= powerful.path %>/static/css/project.css': '<%= powerful.path %>/static/css/less/project.less',
'<%= powerful.path %>/static/css/editor.css': '<%= powerful.path %>/static/css/less/editor.less',
'<%= powerful.path %>/static/css/login.css': '<%= powerful.path %>/static/css/less/login.less'
}
},
production: {
options: {
yuicompress: true
},
files: {
'<%= powerful.path %>/static/css/project.css': '<%= powerful.path %>/static/css/less/project.less',
'<%= powerful.path %>/static/css/editor.css': '<%= powerful.path %>/static/css/less/editor.less',
'<%= powerful.path %>/static/css/login.css': '<%= powerful.path %>/static/css/less/login.less'
}
},
ie: {
options: {
yuicompress: true
},
files: {
'<%= powerful.path %>/static/css/ie.css': '<%= powerful.path %>/static/css/less/ie.less'
}
}
},
watch: {
less: {
files: ['<%= powerful.path %>/static/css/less/*.less'],
tasks: ['less:development']
}
}
}, // end: powerful
});
// load the plugin
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
// load tasks
//grunt.registerTask('default', ['less']);
grunt.registerMultiTask('powerful', 'do things', function(){
grunt.task.run(['watch']);
});
};
Tasks should go on the first level of your config, not within another task config. Also your powerful task isnt a multitask so it doesnt even need a config block. Just configure the tasks the standard way:
grunt.initConfig({
less: {
/* config here */
},
watch: {
/* config here */
}
});

Resources