problems with grunt tasks - gruntjs

My package.json is:
{
"name": "pink",
"version": "0.1.0",
"private": true,
"description": "Личный проект «Пинк» от HTML Academy",
"devDependencies": {
"#htmlacademy/editorconfig-cli": "0.1.x",
"autoprefixer": "^6.7.7",
"grunt": "^1.0.1",
"grunt-browser-sync": "2.2.0",
"grunt-contrib-imagemin": "^1.0.1",
"grunt-contrib-less": "^1.4.0",
"grunt-contrib-watch": "1.0.0",
"grunt-css-mqpacker": "^3.0.1",
"grunt-postcss": "0.8.0",
"grunt-svgmin": "^4.0.0",
"grunt-svgstore": "^1.0.0",
"load-grunt-tasks": "^3.5.2",
"postcss-csso": "^2.0.0"
},
"scripts": {
"test": "editorconfig-cli",
"build": "grunt less && grunt postcss",
"start": "npm run build && grunt serve"
},
"editorconfig-cli": [
"*.html",
"*.json",
"*.js",
"js/**/*.js",
"img/**/*.svg",
"less/**/*.less"
],
"engines": {
"node": "6.7"
}
}
Gruntfile.js is:
"use strict";
module.exports = function(grunt) {
require("load-grunt-tasks")(grunt);
grunt.initConfig({
less: {
style: {
files: {
"css/style.css": "less/style.less"
}
}
},
postcss: {
style: {
options: {
processors: [
require("autoprefixer")({browsers: [
"last 1 versions",
"last 2 Chrome versions",
"last 2 Firefox versions",
"last 2 Opera versions",
"last 2 Edge versions",
]}),
]
},
src: "css/*.css"
}
},
browserSync: {
server: {
bsFiles: {
src: [
"*.html",
"css/*.css"
]
},
options: {
server: ".",
watchTask: true,
notify: false,
open: true,
cors: true,
ui: false
}
}
},
watch: {
style: {
files: ["less/**/*.less"],
tasks: ["less", "postcss"]
}
}
});
grunt.registerTask("serve", ["browserSync", "watch"]);
};
All Grunt tasks are working well.
I added a new grunt plugin, for example, imagemin (https://www.npmjs.com/package/grunt-contrib-imagemin).
My updated Gruntfile.js looks like this:
"use strict";
module.exports = function(grunt) {
require("load-grunt-tasks")(grunt);
grunt.initConfig({
less: {
style: {
files: {
"css/style.css": "less/style.less"
}
}
},
postcss: {
style: {
options: {
processors: [
require("autoprefixer")({browsers: [
"last 1 versions",
"last 2 Chrome versions",
"last 2 Firefox versions",
"last 2 Opera versions",
"last 2 Edge versions",
]}),
]
},
src: "css/*.css"
}
},
// Configuration for imagemin-task
imagemin: {
dynamic: {
options: {
optimizationLevel: 3
},
files: [{
expand: true,
cwd: "src/",
src: ["images/**/*.{png,jpg,gif}"],
dest: "img/"
}]
}
}
browserSync: {
server: {
bsFiles: {
src: [
"*.html",
"css/*.css"
]
},
options: {
server: ".",
watchTask: true,
notify: false,
open: true,
cors: true,
ui: false
}
}
},
watch: {
style: {
files: ["less/**/*.less"],
tasks: ["less", "postcss"]
}
}
});
// Here is registerTask
grunt.registerTask("default", ["imagemin"]);
grunt.registerTask("serve", ["browserSync", "watch"]);
};
After this addition, no tasks work anymore.
Terminal shows me the following error:
Loading "Gruntfile.js" tasks...ERROR
SyntaxError: Unexpected identifier Warning: Task "less" not found. Use --force to continue.
Aborted due to warnings.
bash: --force: command not found
The same error appears for all tasks (for example, grunt less, which was working correctly before the last addition).
What's wrong? Please help me.
After addition the comma's and new plugins initConfig is following:
grunt.initConfig({
less: {
style: {
files: {
"css/style.css": "less/style.less"
}
}
},
postcss: {
style: {
options: {
processors: [
require("autoprefixer")({browsers: [
"last 1 versions",
"last 2 Chrome versions",
"last 2 Firefox versions",
"last 2 Opera versions",
"last 2 Edge versions",
]}),
]
},
src: "css/*.css"
}
},
csso: {
style: {
options: {
report: "gzip"
},
files: {
"css/style.min.css": "css/style.css"
}
}
},
imagemin: {
images: {
options: {
optimizationLevel: 3
},
files: [{
expand: true,
cwd: "src/",
src: ["images/**/*.{png,jpg,gif}"],
dest: "img/"
}]
}
},
svgstore: {
options: {
svg: {
style: "display: none"
}
}
symbols: {
files: {
"images/symbols.svg": "images/icons/*.svg"
}
}
},
svgmin: {
symbols: {
files: [{
expand: true,
src: ["images/icons/*.svg"]
}]
}
},
browserSync: {
server: {
bsFiles: {
src: [
"*.html",
"css/*.css"
]
},
options: {
server: ".",
watchTask: true,
notify: false,
open: true,
cors: true,
ui: false
}
}
},
watch: {
style: {
files: ["less/**/*.less"],
tasks: ["less", "postcss"]
}
}
});
But I have the same mistake again.

You're missing a comma after the (newly added) imagemin block:
imagemin: {
// ...
} // <- right here
browserSync: {
// ...

Related

PostCSS not compiling but executes successfully

I am a grunt newbie...
Please read through my grunt file bellow. Everything executes successfully, however the PostCSS function doesn't do it's job. If I remove the expanded and compressed calls within it and just use the options and dist then it works, but when I try to double up on the calls it doesn't work. What do I need to do?
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
scripts_jquery: {
options: {
beautify: false,
mangle: false
},
files: {
'js/vendor/jquery-1.12.4.min.js': ['js/vendor/jquery-1.12.4.js']
}
},
scripts_functions: {
options: {
beautify: false,
mangle: false
},
files: {
'js/functions.min.js': ['js/functions.js']
}
},
scripts_expanded: {
options: {
beautify: true,
mangle: false,
sourceMap: true,
sourceMapName: 'js/scripts.js.map'
},
files: {
'js/scripts.js': ['js/plugins/**/*.js']
}
},
scripts_compressed: {
options: {
beautify: false,
mangle: false,
sourceMap: true,
sourceMapName: 'js/scripts.min.js.map'
},
files: {
'js/scripts.min.js': ['js/plugins/**/*.js']
}
}
},
sass: {
compile: {
options: {
indentType: 'tab',
indentWidth: 1,
linefeed: 'crlf',
sourceMap: false
},
files: {
'css/styles.css': 'css/styles.scss',
'css/styles.min.css': 'css/styles.scss'
}
}
},
postcss: {
css_expanded: {
options: {
map: {
inline: false,
annotation: 'css/'
},
processors: [
require('autoprefixer')({
browsers: 'last 2 versions'
})
]
},
dist: {
src: 'css/styles.css'
}
},
css_compressed: {
options: {
map: {
inline: false,
annotation: 'css/'
},
processors: [
require('autoprefixer')({
browsers: 'last 2 versions'
}),
require('cssnano')()
]
},
dist: {
src: 'css/styles.min.css'
}
}
},
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'img/',
src: ['img/**/*.{png,jpg,gif}'],
dest: 'img/'
}]
}
},
svgmin: {
options: {
plugins: [{
removeViewBox: false
}, // don't remove the viewbox atribute from the SVG
{
removeEmptyAttrs: false
} // don't remove Empty Attributes from the SVG
]
},
dist: {
files: [{
expand: true,
cwd: 'img/',
src: ['img/**/*.svg'],
dest: 'img/'
}]
}
},
svgstore: {
options: {
prefix: 'icon-',
cleanup: true,
includedemo: true,
svg: {
viewBox: '0 0 100 100',
xmlns: 'http://www.w3.org/2000/svg'
}
},
dist: {
files: {
'svg/svg-sprite.svg': ['img/**/*.svg']
},
}
},
watch: {
scripts: {
files: ['js/plugins/**/*.js', 'js/vendor/jquery-1.12.4.js', 'js/functions.js'],
tasks: ['uglify'],
options: {
livereload: true,
},
},
css: {
files: ['css/**/*.scss'],
tasks: ['sass', 'postcss'],
options: {
livereload: true,
},
},
images: {
files: ['img/**/*.{png,jpg,gif}'],
tasks: ['imagemin'],
options: {
livereload: true,
},
},
svgs: {
files: ['img/**/*.svg'],
tasks: ['svgmin', 'svgstore'],
options: {
livereload: true,
},
}
},
});
require('load-grunt-tasks')(grunt);
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-svgmin');
grunt.loadNpmTasks('grunt-svgstore');
// Default task(s).
grunt.registerTask('default', ['watch']);
};
You don't need the dist property inside each target. dist is a name for the default target. Remove it and the task should work:
postcss: {
css_expanded: {
options: {
map: {
inline: false,
annotation: 'css/'
},
processors: [
require('autoprefixer')({
browsers: 'last 2 versions'
})
]
},
src: 'css/styles.css'
},
css_compressed: {
options: {
map: {
inline: false,
annotation: 'css/'
},
processors: [
require('autoprefixer')({
browsers: 'last 2 versions'
}),
require('cssnano')()
]
},
src: 'css/styles.min.css'
}
},
There is actually a thread on this here: https://github.com/nDmitry/grunt-postcss/issues/67

Grunt - nodemon + watch

i'm new to grunt so i'm guessing i'm doing something simple really wrong. I'm using angular-client-side-auth for my single page app and i wanted to add grunt-contrib-sass and grunt-contrib-watch into Gruntfile.js. Here's the problem, when i start the server using nodemon, the watch never run. I tried concurrent, but no luck.
Here's my Gruntfile.js:
module.exports = function(grunt) {
// Load tasks
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadNpmTasks('grunt-env');
grunt.loadNpmTasks('grunt-nodemon');
grunt.loadNpmTasks('grunt-contrib-clean');
//require('load-grunt-tasks')(grunt); // npm install --save-dev load-grunt-tasks
grunt.initConfig({
mochaTest: {
test: {
options: {
reporter: 'spec'
},
src: ['server/tests/**/*.js']
}
},
env : {
options : {
//Shared Options Hash
},
dev : {
NODE_ENV : 'development'
},
test : {
NODE_ENV : 'test'
}
},
nodemon: {
dev: {
script: 'server.js',
}
},
watch: {
//options: { nospawn: true, livereload: true },
sass: {
files: ["client/css/styles.sass"],
tasks: ['sass'],
},
cssmin: {
files: ["client/css/styles.sass"],
tasks: ['cssmin'],
}
},
sass: {
dist: {
files: {
'client/css/styles.css': 'client/css/styles.scss'
}
}
},
cssmin: {
options: {
shorthandCompacting: false,
roundingPrecision: -1
},
target: {
files: [{
expand: true,
cwd: 'client/css',
src: ['styles.css', '!*.min.css'],
dest: 'client/css',
ext: '.min.css'
}]
}
},
concurrent: {
dev: {
options: {
logConcurrentOutput: true
},
tasks: ['watch', 'nodemon:dev']
}
},
clean: ["node_modules", "client/components"]
});
grunt.registerTask('serverTests', ['env:test', 'mochaTest']);
grunt.registerTask('test', ['env:test', 'serverTests']);
grunt.registerTask('dev', ['env:dev', 'concurrent:dev']);
};

grunt will not run on my project, which default Task?

I am trying to run grunt in order to get SASS and a few other things to compile my project (that someone else created), however I keep getting the following error:
Warning: Task "default" not found. Use --force to continue.
Aborted due to warnings.
I do not understand which "default" task it is is referring to. The grunt file I have inherited is as follows:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';'
},
dev: {
src: ['www/_assets/js/vendor-concat/*.js', 'www/_assets/js/*.js', '!www/_assets/js/prototype.js', '!www/_assets/js/scripts.js', '!www/_assets/js/scripts.min.js'],
dest: 'www/_assets/js/scripts.js'
}
},
uglify: {
dist: {
files: {
'www/_assets/js/scripts.min.js': ['www/_assets/js/scripts.js']
}
}
},
jshint: {
files: ['Gruntfile.js'],
options: {
// options here to override JSHint defaults
globals: {
jQuery: true,
console: true,
module: true,
document: true
}
}
},
modernizr: {
dist: {
// [REQUIRED] Path to the build you're using for development.
"devFile" : "www/_assets/js/vendor/modernizr-2.7.1.js",
// [REQUIRED] Path to save out the built file.
"outputFile" : "www/_assets/js/vendor/modernizr-custom.js"
}
},
imageoptim: {
dev: {
src: ['www/_assets/img']
}
},
sass: {
dev: {
options: {
includePaths: ['www/_assets/scss'],
outputStyle: 'compressed',
sourceMap: true
},
files: {
'www/_assets/css/main.css' : 'www/_assets/scss/main.scss',
'www/_assets/css/main-ie8.css' : 'www/_assets/scss/main-ie8.scss'
}
}
},
assemble: {
options: {
flatten: false,
expand: true,
assets: 'www/_assets',
layout: 'default.hbs',
layoutdir: 'www/_templates/layouts',
partials: ['www/_templates/partials/*.hbs'],
data: ['www/_templates/data/*.json']
},
dev: {
files: [
{expand: true, cwd: 'www/_templates/pages/', src: '**/*.hbs', dest: 'www/', ext: '.html'}
]
}
},
watch: {
options: {
livereload: true,
spawn: false
},
css: {
files: ['www/_assets/scss/**/*.scss'],
tasks: ['sass']
},
js: {
files: ['www/_assets/js/**/*.js', '!www/_assets/js/scripts.min.js', '!www/_assets/js/scripts.js'],
tasks: ['jshint', 'concat:dev']
},
hbs: {
files: ['www/_templates/{,*/}*.hbs', 'www/_templates/{,*/*/}*.hbs', 'www/_templates/{,*/*/*/}*.hbs'],
tasks: ['assemble']
},
html: {
files: ['www/email.html']
}
},
copyto: {
prototype: {
files: [
{cwd: 'www/', src: ['**/*'], dest: 'prototype/'}
],
options: {
ignore: [
'www/_assets/scss{,/**/*}',
'www/_assets/js{,/**/*}',
'!www/_assets/js/vendor{,/**/*}',
'!www/_assets/js/scripts.min.js',
'!www/_assets/js/prototype.js',
'www/_templates{,/**/*}',
'www/z-backups{,/**/*}',
'www/_assets/css/*.map'
]
}
},
beta: {
files: [
{cwd: 'prototype/_assets/', src: ['**/*'], dest: '_beta-sln/Beta/src/SFA.as.Web.Candidate/Content/_assets/'}
],
options: {
ignore: [
'prototype/_assets/video{,/**/*}',
'prototype/_assets/js/prototype.js'
]
}
},
sprint: {
files: [
{cwd: 'prototype/', src: ['**/*'], dest: 'sprint/'}
]
},
dist: {
files: [
{cwd: 'www/', src: ['**/*'], dest: 'dist/'}
],
options: {
ignore: [
'www/_assets/scss{,/**/*}',
'www/_assets/css/*.map',
'www/_assets/video{,/**/*}',
'www/_assets/js/plugins{,/**/*}',
'www/_assets/js/interactions.js',
'www/_assets/js/scripts.js',
'www/_templates{,/**/*}',
'www/*.html',
'!www/index.html',
'www/z-backups{,/**/*}'
]
}
}
},
clean: {
prototype: {
src: [ 'prototype/' ]
},
sprint: {
src: [ 'sprint/' ]
},
dist: {
src: [ 'dist/' ]
}
},
replace: {
map: {
src: ['www/_assets/css/*.css'],
overwrite: true,
replacements: [{
from: 'sourceMappingURL=main.css.map',
to: 'Map removed'
},{
from: 'sourceMappingURL=main-ie8.css.map',
to: 'Map removed'
}]
},
scripts: {
src: ['www/apprentice/*.html', 'www/test/apprentice/*.html', 'www/trainee/*.html', 'www/employer/*.html', 'www/*.html'],
overwrite: true,
replacements: [{
from: 'scripts.js',
to: 'scripts.min.js'
}]
}
},
prettify: {
options: {
indent: 2,
wrap_line_length: 78,
brace_style: 'expand',
},
// Specify a number to padcomments
dist: {
files: [
{expand: true, cwd: 'dist/', src: ['apprentice/*.html', 'trainee/*.html', 'employer/*.html', '*.html'], dest: 'dist/', ext: '.html'}
]
},
prototype: {
files: [
{expand: true, cwd: 'prototype/', src: ['apprentice/*.html', 'trainee/*.html', 'employer/*.html', '*.html', '!pattern-library.html'], dest: 'prototype/', ext: '.html'}
]
}
},
devUpdate: {
main: {
options: {
updateType: 'report', //just report outdated packages
reportUpdated: false, //don't report already updated packages
semver: true, //use package.json semver rules when updating
packages: { //what packages to check
devDependencies: true, //only devDependencies
dependencies: false
},
packageJson: null //find package.json automatically
}
}
},
browserSync: {
dev: {
bsFiles: {
src : [
'www/_assets/css/*.css',
'www/_assets/js/scripts.js',
'www/**/*.html'
]
},
options: {
ghostMode: {
clicks: true,
scroll: true,
links: true,
forms: true
},
watchTask: true,
server: {
baseDir: "www"
}
}
}
},
connect: {
server: {
options: {
port: 7000,
base: 'www',
livereload: true,
open: true
}
}
},
uncss: {
offline: {
options: {
// csspath : 'www/_assets/css/',
// urls : ['http://localhost:/mypage', '...'], // Deprecated
timeout : 1000,
},
files: {
'www/offline/offline.css': ['www/offline/maintenance.html']
}
}
}
});
[
'assemble',
'grunt-modernizr',
'grunt-contrib-imagemin',
'grunt-imageoptim',
'grunt-contrib-uglify',
'grunt-contrib-jshint',
'grunt-sass',
'grunt-uncss',
'grunt-criticalcss',
'grunt-contrib-concat',
'grunt-text-replace',
'grunt-contrib-watch',
'grunt-copy-to',
'grunt-contrib-clean',
'grunt-contrib-compress',
'grunt-pngmin',
'grunt-browser-sync',
'grunt-dev-update',
'grunt-contrib-connect',
'grunt-prettify'
].forEach(function (task) {
grunt.loadNpmTasks(task);
});
grunt.registerTask('images', ['imageoptim']);
grunt.registerTask('modern', ['modernizr']);
grunt.registerTask('offline', ['uncss:offline']);
grunt.registerTask('dev', ['jshint', 'concat:dev', 'sass', 'assemble', 'connect', 'watch']);
grunt.registerTask('sync', ['jshint', 'concat:dev', 'sass', 'assemble', 'browserSync', 'watch']);
grunt.registerTask('proto', ['uglify:dist', 'replace:map', 'clean:prototype', 'replace:scripts', 'copyto:prototype', 'prettify:prototype']);
grunt.registerTask('sprint', ['clean:sprint', 'copyto:sprint']);
grunt.registerTask('dist', ['uglify:dist', 'replace:map', 'clean:dist', 'replace:scripts', 'copyto:dist', 'prettify:dist']);
grunt.registerTask('beta', ['copyto:beta']);
};
As I have not created this myself, I am reluctant to go ahead and break it but is there anything there which stands out? I have seen similar questions but as the grunt files need to vary it is difficult to find the correct answer for this.
Many thanks!
Since file doesn't have default task you have to either create it or run grunt with one of defined tasks:
> grunt dev
or add default task in your Gruntfile.js
grunt.registerTask('default',['dev']);
please refer to http://gruntjs.com/creating-tasks for more information

Grunt Watch - Verifiying property

I'm attempting to seperate my grunt file so I can process two separate chunks of code, everything seems to work apart from the watch task.
I get the following error which loops out until it exceeds the call stack
Waiting...Verifying property watch.app.files exists in config...ERROR
>> Unable to process task.
Warning: Required config property "watch.app.files" missing.
It seems it doesn't like my watch task being split into two. I've look around and it doesn't seem to be an issue for other people.
My gruntfile looks like this:
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
app: {
src: [
'themes/site_themes/app/scripts/build/libs/!(html5shiv|respond).js',
'themes/site_themes/app/scripts/build/modules/*.js'
],
dest: 'themes/site_themes/app/scripts/production/app.min.js'
},
marketing: {
src: [
'themes/site_themes/marketing/scripts/build/libs/!(html5shiv|respond).js',
'themes/site_themes/marketing/scripts/build/modules/*.js'
],
dest: 'themes/site_themes/marketing/scripts/production/app.min.js'
}
},
uglify: {
app: {
files: {
'themes/site_themes/app/scripts/production/app.min.js': ['themes/site_themes/app/scripts/production/app.min.js'],
'themes/site_themes/app/scripts/production/html5shiv.min.js': ['themes/site_themes/app/scripts/build/libs/html5shiv.js'],
'themes/site_themes/app/scripts/production/respond.min.js': ['themes/site_themes/app/scripts/build/libs/respond.js'],
}
},
marketing: {
files: {
'themes/site_themes/marketing/scripts/production/app.min.js': ['themes/site_themes/marketing/scripts/production/app.min.js'],
'themes/site_themes/marketing/scripts/production/html5shiv.min.js': ['themes/site_themes/marketing/scripts/build/libs/html5shiv.js'],
'themes/site_themes/marketing/scripts/production/respond.min.js': ['themes/site_themes/marketing/scripts/build/libs/respond.js'],
}
}
},
jshint: {
app: {
all: ['themes/site_themes/app/scripts/build/modules/!(analytics).js', 'themes/site_themes/app/scripts/build/app.js'],
},
marketing: {
all: ['themes/site_themes/marketing/scripts/build/modules/!(analytics).js', 'themes/site_themes/marketing/scripts/build/app.js'],
}
},
sass: {
app: {
options: {
style: 'compressed'
},
files: {
'themes/site_themes/app/styles/production/style.min.css':'themes/site_themes/app/styles/build/style.scss'
}
},
marketing: {
options: {
style: 'compressed'
},
files: {
'themes/site_themes/marketing/styles/production/style.min.css':'themes/site_themes/marketing/styles/build/style.scss'
}
}
},
autoprefixer: {
options: {
browsers: ['last 2 versions', 'ie >= 8']
},
app: {
no_dest: {
src: 'themes/site_themes/app/styles/production/style.min.css',
}
},
marketing: {
no_dest: {
src: 'themes/site_themes/marketing/styles/production/style.min.css',
}
}
},
watch: {
app: {
jshint: {
files: ['themes/site_themes/app/scripts/build/modules/!(analytics).js', 'themes/site_themes/app/scripts/build/app.js'],
tasks: 'jshint:app'
},
scripts: {
files: ['themes/site_themes/app/scripts/build/*/*.js'],
tasks: ['concat:app', 'uglify:app'],
options: {
spawn: false,
},
},
css: {
files: ['themes/site_themes/app/styles/build/*.scss', 'themes/site_themes/app/styles/build/inuit/*/*.scss', 'themes/site_themes/app/styles/build/theme/*/*.scss'],
tasks: ['sass:app', 'autoprefixer:app'],
options: {
livereload: true,
spawn: false,
}
}
},
marketing: {
jshint: {
files: ['themes/site_themes/marketing/scripts/build/modules/!(analytics).js', 'themes/site_themes/marketing/scripts/build/app.js'],
tasks: 'jshint:marketing'
},
scripts: {
files: ['themes/site_themes/marketing/scripts/build/*/*.js'],
tasks: ['concat:marketing', 'uglify:marketing'],
options: {
spawn: false,
},
},
css: {
files: ['themes/site_themes/marketing/styles/build/*.scss', 'themes/site_themes/marketing/styles/build/inuit/*/*.scss', 'themes/site_themes/marketing/styles/build/theme/*/*.scss'],
tasks: ['sass:marketing', 'autoprefixer:marketing'],
options: {
livereload: true,
spawn: false,
}
}
}
}
});
// 3. Where we tell Grunt we plan to use this plug-in.
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['concat:app', 'uglify:app', 'jshint:app', 'sass:app', 'autoprefixer:app', 'watch:app']);
grunt.registerTask('marketing', ['concat:marketing', 'uglify:marketing', 'jshint:marketing', 'sass:marketing', 'autoprefixer:marketing', 'watch:marketing']);
};
Just found this. Looks like nested targets aren't supported by watch.
I'll try find another way to to this and post if I do.

Grunt isn't making changes when watching

Grunt says waiting... but doesn't make changes to sass while watching. I have to run grunt on the command line every time I want it to run and change things. The thing I need it to update the most is the sass to css. But it's not working. Please help.
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// package options
express: {
server: {
options: {
port: 3000,
hostname: 'localhost',
bases: 'public' // the 'public' folder for your project
}
}
},
jshint: {
options: {
jshintrc: '.jshintrc' // jshint config file
},
all: [
'Gruntfile.js',
'js/*.js'
]
},
concat: {
basic: {
src: [
'bower_components/jquery/dist/jquery.js',
'bower_components/foundation/js/foundation/foundation.js',
'dev/js/jquery.royalslider.custom.min.js',
'dev/js/royalslider.js',
'dev/js/megamenu_plugins.js',
'dev/js/megamenu.min.js',
'dev/js/megamenu.js',
'dev/js/app.js'
],
dest: 'dev/tmp/app.js'
},
extras: {
src: [
'bower_components/modernizr/modernizr.js'
],
dest: 'dev/tmp/modernizr.js'
}
},
sass: {
options: {
includePaths: ['bower_components/foundation/scss']
},
dist: {
options: {
outputStyle: 'compressed'
},
files: {
'public/build/css/app.min.css': 'dev/scss/app.scss'
}
}
},
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'dev/img/',
src: ['**/*.{png,jpg,gif}'],
dest: 'public/build/img/'
}]
}
},
uglify: {
build: {
files: {
'public/build/js/modernizr.min.js': 'dev/tmp/modernizr.js',
'public/build/js/app.min.js': 'dev/tmp/app.js'
}
}
},
clean: {
dist: [
'tmp/**',
'public/build/img/**'
]
},
watch: {
grunt: {
files: ['Gruntfile.js']
},
css: {
files: ['scss/*.scss'],
tasks: ['newer:sass'],
options: {
spawn: false
}
},
js: {
files: [
'js/*.js'
],
tasks: ['newer:concat', 'newer:uglify'],
options: {
livereload: true,
atBegin: true
}
},
imagemin: {
files: [
'img/**'
],
tasks: ['newer:imagemin'],
options: {
livereload: true,
atBegin: true
}
}
}
});
// Load tasks
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-notify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-express');
grunt.loadNpmTasks('grunt-newer');
// Register default tasks
grunt.registerTask('build', ['sass']);
grunt.registerTask('default', ['build','watch']);
}

Resources