FoundationPress: want to add task to Gruntfile.js - wordpress

I'm using the excellent FoundationPress and want to add a task to my watch to create a single .css file out of a single .scss file. In my case, this is for CKEditor - because it needs a separate .css file for custom formatting the input area.
However, I get this output whenever I edit my .scss file:
>> File "ckeditor/nb-ckeditor.scss" changed.
Warning: Task "sassckeditor" not found. Use --force to continue.
Aborted due to warnings.
Here's my the content of Gruntfile.js (see ADD 1 and ADD 2 for what I added to the original content):
module.exports = function(grunt) {
require('time-grunt')(grunt);
grunt.initConfig(
{
pkg: grunt.file.readJSON('package.json'),
sass: {
options: {
sourceMap: true
},
dist: {
options: {
outputStyle: 'compressed'
},
files: {
'css/foundation.css': 'scss/foundation.scss'
}
}
},
/* ADD 1 BEGIN */
sassckeditor: {
options: {
sourceMap: true
},
dist: {
options: {
outputStyle: 'compressed'
},
files: {
'ckeditor/nb-ckeditor-fromsass.css': 'ckeditor/nb-ckeditor.scss'
}
}
},
/* ADD 1 END */
copy: {
scripts: {
expand: true,
cwd: 'bower_components/foundation/js/vendor/',
src: '**',
flatten: 'true',
dest: 'js/vendor/'
},
iconfonts: {
expand: true,
cwd: 'bower_components/fontawesome/',
src: ['**', '!**/less/**', '!**/css/**', '!bower.json'],
dest: 'assets/fontawesome/'
},
},
'string-replace': {
fontawesome: {
files: {
'assets/fontawesome/scss/_variables.scss': 'assets/fontawesome/scss/_variables.scss'
},
options: {
replacements: [
{
pattern: '../fonts',
replacement: '../assets/fontawesome/fonts'
}
]
}
},
},
concat: {
options: {
separator: ';',
},
dist: {
src: [
'bower_components/foundation/js/foundation/foundation.js',
'js/custom/*.js'
],
dest: 'js/foundation.js',
},
},
uglify: {
dist: {
files: {
'js/foundation.js': ['js/foundation.js']
},
options: {
preserveComments: false
}
}
},
watch: {
grunt: { files: ['Gruntfile.js'] },
sass: {
files: 'scss/**/*.scss',
tasks: ['sass'],
options: {
livereload:true,
}
},
/* ADD 2 BEGIN */
sassckeditor: {
files: 'ckeditor/*.scss',
tasks: ['sassckeditor'],
options: {
livereload:true,
}
},
/* ADD 2 END */
js: {
files: 'js/custom/**/*.js',
tasks: ['concat', 'uglify'],
options: {
livereload:true,
}
},
all: {
files: '**/*.php',
options: {
livereload:true,
}
}
}
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-string-replace');
grunt.registerTask('build', ['copy', 'string-replace:fontawesome', 'sass', 'concat', 'uglify']);
grunt.registerTask('default', ['watch', 'sassckeditor']);
};
What am I doing wrong? Thanks in advance!

From reading your code it looks like the error is coming from trying to run a task by the name of 'sassckeditor' rather than sending the .scss through the 'sass' task. Here's an example of what your code should look like:
/* ADD 2 BEGIN */
sassckeditor: {
files: 'ckeditor/*.scss',
tasks: ['sass'],
options: {
livereload:true,
}
},
/* ADD 2 END */
This will keep your .scss file for the CKEditor separate from the rest of your Sass files, but will still run it thorough the proper 'sass' task that actually compiles the .scss files.

Okay, got this working by simply adding an entry for "files" in my "dist" task:
sass: {
options: {
sourceMap: true
},
dist: {
options: {
outputStyle: 'compressed'
},
files: {
'css/foundation.css': 'scss/foundation.scss',
'css/nb-ckeditor.css': 'scss/nb-ckeditor.scss' // <-- THIS
}
}
},

Related

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.

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']);
}

How to ignore one file in a grunt-watch task?

'use strict';
module.exports = function(grunt) {
// Project Configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
jade: {
files: ['app/views/**'],
options: {
livereload: true,
},
},
js: {
files: ['!public/build.js', 'gruntfile.js', 'server.js', 'app/**/*.js', 'public/js/**', 'test/**/*.js'],
tasks: ['uglify', 'jshint'],
options: {
livereload: true,
},
},
html: {
files: ['public/views/**'],
options: {
livereload: true,
},
},
css: {
files: ['public/css/**'],
options: {
livereload: true
}
}
},
jshint: {
all: {
src: ['!public/build.js', 'gruntfile.js', 'server.js', 'app/**/*.js', 'public/js/**', 'test/**/*.js'],
options: {
jshintrc: true
}
}
},
uglify: {
options: {
mangle: false
},
dist: {
files: {
'public/build.js': ['public/js/**/*.js']
}
}
},
nodemon: {
dev: {
options: {
file: 'server.js',
args: [],
ignoredFiles: ['public/**'],
watchedExtensions: ['js'],
nodeArgs: ['--debug'],
delayTime: 1,
env: {
PORT: 3000
},
cwd: __dirname
}
}
},
concurrent: {
tasks: ['nodemon', 'watch', 'uglify'],
options: {
logConcurrentOutput: true
}
},
mochaTest: {
options: {
reporter: 'spec',
require: 'server.js'
},
src: ['test/mocha/**/*.js']
},
env: {
test: {
NODE_ENV: 'test'
}
},
karma: {
unit: {
configFile: 'test/karma/karma.conf.js'
}
}
});
//Load NPM tasks
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-mocha-test');
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-nodemon');
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-env');
//Making grunt default to force in order not to break the project.
grunt.option('force', true);
//Default task(s).
grunt.registerTask('default', ['jshint', 'concurrent']);
//Test task.
grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']);
};
I'm trying to exclude the public/build.js file, but it doesn't seem to be working. What am I doing wrong?
Edit:
Why do you need to exclude it from your watch? I do not see any glob pattern in your watch:js task that would look for changed in that file to begin with.
Original Answer:
Have you tried moving '!public/build.js' as the last include in your watch task?
The part of the documentation sited:
"Patterns are processed in-order, with !-prefixed matches excluding matched files from the result set"
Makes me think that the excluded file at the beginning gets added back in with the 'public/js/**' pattern.
I would try changing your js watch task to this.
js: {
files: ['gruntfile.js', 'server.js', 'app/**/*.js', 'public/js/**', 'test/**/*.js', '!public/build.js'],
tasks: ['uglify', 'jshint'],
options: {
livereload: true,
},
},
Add the ! to the beginning of the file name. !public/build.js
You could also add a jshintignore file with all the files you want to ignore inside that.

Grunt outputs an empty .js-file after concatting

The output of the Gruntfile is an empty file in public/assets/app.js. The Sass-part works fine, but the JS-part doesn't.
//Gruntfile
module.exports = function(grunt) {
//Initializing the configuration object
grunt.initConfig({
// Task configuration
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'./public/assets/app.css': './app/assets/scss/style.scss'
},
noCache: true
}
},
concat: {
options: {
separator: ';',
},
dist: {
src: [
'./app/bower/jquery/jquery.js',
'./app/assets/js/script.js'
],
dest: './public/assets/app.js',
},
},
uglify: {
options: {
mangle: false
},
dist: {
files: {
'./public/assets/app.js': './public/assets/app.js',
}
},
},
jshint: {
all: ['Gruntfile.js', './public/assets/app.js']
},
watch: {
js: {
files: [
'./app/assets/bower/*.js',
'./app/assets/js/*.js'
],
tasks: ['jshint', 'concat', 'uglify'],
options: {
livereload: false
}
},
sass: {
files: ['./app/assets/scss/*.scss'],
tasks: ['sass'],
options: {
livereload: false
}
}
}
});
// Plugin loading
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
// Task definition
grunt.registerTask('default', ['sass', 'jshint', 'concat', 'uglify', 'watch']);
};
But I can't find out what is wrong. Even JShint isn't showing errors.
Structure looks like this: https://www.dropbox.com/s/y0t2tu0asotz0ex/Screenshot%202013-12-20%2020.49.54.png
Taking another look at your Gruntfile and directory structure, I think you have the folders specified incorrectly, You specify the source as being ./app/..., but if your Gruntfile is in that directory (app), then you would have to be running your grunt tasks from there, meaning it would be looking for app/app/... (because it's relative to the current directory). Try this:
concat: {
options: {
separator: ';',
},
dist: {
src: [
'bower/jquery/jquery.js',
'assets/js/script.js'
],
dest: 'public/assets/app.js',
},
},
My solution is set correct filepath: Scripts/libs/Timer.js - correct, /Scripts/libs/Timer.js - empty file
Scripts is a folder into my project.
Project/Scripts/libs/Timer.js - full path.
when I set this path:
Scripts/libs/Timer.js - file isn't empty, when /Scripts/libs/Timer.js - file is empty.
concat: {
options:{
// define a string to put between each file in the concatenated output
separator: '\n;'
},
own_scripts: {
//project-files
src: [
"Scripts/application/app.js",
"Scripts/application/Controllers/*.js",
"Scripts/application/Directives/*.js",
"Scripts/application/Filters/*.js",
"Scripts/application/Services/*.js"
],
dest: 'dist/scripts-concat.js'
}
maybe you should do this:
dist: {
src: [
'app/bower/jquery/jquery.js',
'app/assets/js/script.js'
],
dest: 'public/assets/app.js',
},

Resources