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 */
}
});
Related
The uglify task takes too long to complete, it is difficult while development, How can I disable the task without removing from grunt.registerTask, because other tasks are also calling uglify
uglify: {
compile: {
options: {
banner: '<%= meta.text%>'
},
files: {
'<%= assets %>': '<%= concat.assets%>'
}
}
},
this is how I solved the issue
uglify: {
compile: {
options: {
banner: '<%= meta.text%>'
},
files: {
// commented this line to stop uglify task
// '<%= assets %>': '<%= concat.assets%>'
}
}
},
I have 2 sass targets.
one creates debug info, the other does not.
If I don't copy/paste the files section between the targets, it doesn't seem to work.
sass: {
server: {
options: {
debugInfo: true
},
files: {
'.tmp/styles/main.css': '<%= yeoman.app %>/styles/main.scss'
}
},
dist: {
files: {
'.tmp/styles/main.css': '<%= yeoman.app %>/styles/main.scss'
}
}
},
How can I reuse the files decleration?
From a grunt-sass point of view, you can't share the file declaration between multiple targets.
But to avoid duplication in your Gruntfile, you can always use plain old Javascript variables:
var cssFiles = {
'.tmp/styles/main.css': '<%= yeoman.app %>/styles/main.scss'
}
// ...
grunt.initConfig({
// ...
sass: {
server: {
options: {debugInfo: true},
files: cssFiles
},
dist: {
files: cssFiles
}
},
// ...
});
I am using grunt-contrib-less to compile my .less files in to a single CSS stylesheet. Everything is working, except the source map, which I cannot get to work under any circumstances!
Here is my Gruntfile:
'use strict';
module.exports = function(grunt) {
// Force use of Unix newlines
grunt.util.linefeed = '\n';
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
project: {
// Add entries to this array to create variables for use by Grunt
app: ['app'],
server: 'http://mysite.app',
// Components
bower: ['<%= project.app %>/bower_components'],
bootstrap: ['<%= project.bower %>/bootstrap'],
// Custom Assets
assets: ['<%= project.app %>/assets'],
css: ['<%= project.assets %>/css'],
less: ['<%= project.assets %>/less'],
js: ['<%= project.assets %>/js']
},
less: {
production: {
options: {
ieCompat: true,
sourceMap: true,
sourceMapFilename: '<%= project.css %>/style.css.map',
sourceMapURL: '<%= project.server %>/assets/css/style.css.map',
sourceMapBasepath: 'app',
sourceMapRootpath: '<%= project.server %>'
},
files: {
'<%= project.css %>/style.css': '<%= project.less %>/style.less'
}
}
},
autoprefixer: {
dist: {
files: {
'<%= project.assets %>/css/style.css': '<%= project.assets %>/css/style.css'
}
}
},
concat: {
options: {
separator: ';\n',
sourceMap: true
},
plugins_head: {
// Add further Javascript plugins to this array and they will be
// concatenated in to the plugins-built-head.js file
src: [
'<%= project.bower %>/modernizr/modernizr.js'
],
dest: '<%= project.js %>/built/plugins-built-head.js'
},
plugins: {
// Add further Javascript plugins to this array and they will be
// concatenated in to the plugins-built.js file
src: [
'<%= project.bootstrap %>/js/dropdown.js'
],
dest: '<%= project.js %>/built/plugins-built.js'
},
custom: {
// Add further custom-written javascript files to this array and
// they will be concatenated in to the scripts-built.js file
src: [
'<%= project.js %>/scripts.js'
],
dest: '<%= project.js %>/built/scripts-built.js'
}
},
watch: {
css: {
files: [
'<%= project.bootstrap %>/less/*.less',
'<%= project.less %>/*.less'
],
tasks: [
'less',
'autoprefixer'
],
options: {
livereload: true
}
},
js: {
files: [
'<%= project.js %>/scripts.js'
],
tasks: ['concat']
},
html: {
files: [
'<%= project.app %>/*.html'
],
options: {
livereload: true
}
}
}
});
grunt.loadNpmTasks('grunt-run-grunt');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.registerTask('default', [
'watch'
]);
};
What's happening is that Grunt is writing a proper and correct style.css.map file, but it's not writing the following line to the end of the compiled style.css file:
/*# sourceMappingURL=http://mysite.app/assets/css/style.css.map */
That's the one line that's missing. Everything else is getting compiled and written correctly. If I manually add that line to the end of the compiled CSS, Chrome picks up on the source map properly, but it's not being written in.
Additionally, trying options like sourceMapFileInline seems to make no difference - the file is never written inline.
Any ideas?
Hopefully you have found a solution by now. This is for other people with the same issue:
Make sure the soourcemap will be placed in the same folder as css.
Set sourceMapUrl to only the name of the map file.
This will add the following line to your .css file: /*# sourceMappingURL=default.css.map */
Here are the sourcemap settings in my grunt file:
sourceMap: true,
sourceMapFilename: "src/assets/css/default.css.map",
sourceMapURL: "default.css.map"
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']
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']);
};