The environment is: Linux 2.6.32-573.12.1.el6.x86_64 x86_64, via SSH
I have a slightly non-standard setup for my grunt, as detailed below:
/home/scoots/public_html/
grunt/
package.json
node_modules/
project1/
Gruntfile.js
project2/
Gruntfile.js
project1/
project2/
When I start grunt watch and make a change to my Gruntfile.js (Which is not a common occurance, but still something that might happen depending on the needs of the project), I get the following error:
$ cd ~/public_html/grunt/project1
$ grunt watch
Running "watch" task
Waiting...
Reloading watch config...
Fatal error: EACCES: permission denied, scandir '/home'
It's simple enough to deal with (just cancel and restart grunt) - but that requires me to notice. I can sometimes try and carry on working, but grunt watch will now be locked-up.
Also, what's annoying is this code used to work when I had grunt installed on my local (Windows) machine and ran it from a Node.js command prompt.
For reference, here is an example Gruntfile.js that exhibits this problem:
module.exports = function(grunt) {
require('time-grunt')(grunt);
require('jit-grunt')(grunt);
grunt.file.setBase('../');
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
site_dir: {
site: '../tcl/wp-content/themes/twentysixteen-child',
jscache: 'wp-content/themes/twentysixteen-child/js/src',
grunt: 'tcl'
},
watch: {
css: {
files: ['<%= site_dir.site %>/css/sass/*.scss'],
tasks: ['sass', 'postcss'],
options: {
spawn: false
}
},
scripts: {
files: ['<%= site_dir.site %>/js/src/*.js'],
tasks: ['include_file', 'uglify'],
options: {
spawn: false
}
},
configFiles: {
files: ['<%= site_dir.grunt %>/Gruntfile.js'],
options: {
reload: true
}
}
},
sass: {
options: {
style: 'expanded', // compressed in postcss
sourcemap: true,
sourceMapEmbed: true,
precision: 8,
includePaths: ['node_modules/bootstrap-sass/assets/stylesheets']
},
dist: {
files: {
'<%= site_dir.grunt %>/css/layout.css': '<%= site_dir.site %>/css/sass/layout.scss'
}
}
},
postcss: {
options: {
map: {
inline: false,
annotation: '<%= site_dir.grunt %>/css/maps/'
},
processors: [
require('autoprefixer')({
browsers: [
"Android 2.3",
"Android >= 4",
"Chrome >= 20",
"Firefox >= 24",
"Explorer >= 8",
"iOS >= 6",
"Opera >= 12",
"Safari >= 6"
]
}),
require('csswring')()
]
},
dist: {
src: '<%= site_dir.grunt %>/css/layout.css',
dest: '<%= site_dir.site %>/css/layout.min.css'
}
},
include_file: {
js: {
cwd: '<%= site_dir.grunt %>/',
src: [
'../<%= site_dir.site %>/js/src/common.js'
],
dest: '<%= site_dir.grunt %>/js/'
}
},
uglify: {
options: {
compress: {
warnings: true
},
mangle: true,
preserveComments: /(?:^!|#(?:license|preserve|cc_on))/
},
build: {
src: [
'<%= site_dir.grunt %>/<%= site_dir.jscache %>/common.js'
],
dest: '<%= site_dir.site %>/js/common.min.js'
}
}
});
grunt.registerTask('default', ['sass', 'postcss', 'include_file', 'uglify']);
};
And package.json:
{
"name": "Test",
"version": "0.1.0",
"dependencies": {
"bootstrap-sass": "3.3.7"
},
"devDependencies": {
"autoprefixer": "^6.4.1",
"csswring": "^5.1.0",
"grunt": "^1.0.1",
"grunt-contrib-uglify": "^2.0.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-include-file": "^0.1.3",
"grunt-postcss": "^0.8.0",
"grunt-sass": "^2.0.0",
"jit-grunt": "^0.10.0",
"time-grunt": "^1.4.0"
}
}
EDIT: Verbose / debug enabled:
$ grunt -v -d watch
Initializing
Command-line options: --verbose, --debug=1
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
Running tasks: watch
Loading "grunt-contrib-watch" plugin
Registering "/home/scoots/public_html/grunt/node_modules/grunt-contrib-watch/tasks" tasks.
Loading "watch.js" tasks...OK
+ watch
Running "watch" task
[D] Task source: /home/scoots/public_html/grunt/node_modules/grunt-contrib-watch/tasks/watch.js
Waiting...
Verifying property watch exists in config...OK
Verifying property watch.css.files exists in config...OK
Verifying property watch.scripts.files exists in config...OK
Verifying property watch.config.files exists in config...OK
Watching ../tcl/wp-content/themes/twentysixteen-child/css/sass/__bookings.scss for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/css/sass/__variables.scss for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/css/sass/_bootstrap-custom.scss for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/css/sass/_contactform7.scss for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/css/sass/_lightslider.scss for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/css/sass/_lity.scss for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/css/sass/_zoom.scss for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/css/sass/layout.scss for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/js/src/bootstrap.js for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/js/src/common.js for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/js/src/instafeed.js for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/js/src/lightslider.js for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/js/src/lity.js for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/js/src/scrollreveal.min.js for changes.
Watching ../tcl/wp-content/themes/twentysixteen-child/js/src/zoom.js for changes.
Watching tcl/Gruntfile.js for changes.
Watching tcl/css for changes.
Watching tcl/js for changes.
Watching tcl/wp-content for changes.
Clearing require cache for "tcl/Gruntfile.js" file...OK
[[[[I edit the Gruntfile here]]]]
Reloading watch config...
Fatal error: EACCES: permission denied, scandir '/home'
A leading slash in a files glob sometimes cause this error but grunt will not throw any errors. Just a silent fail with this warning.
make sure that your "files" config does not lead to this , and this <%= site_dir.site %> template does not lead to null or empty.
watch: {
css: {
files: ['<%= site_dir.site %>/css/sass/*.scss'],
tasks: ['sass', 'postcss'],
options: {
spawn: false
}
},
scripts: {
files: ['<%= site_dir.site %>/js/src/*.js'],
tasks: ['include_file', 'uglify'],
options: {
spawn: false
}
},
configFiles: {
files: ['<%= site_dir.grunt %>/Gruntfile.js'],
options: {
reload: true
}
}
}
Related
I have a problem with grunt. My Grunt version is:
grunt-cli v1.4.3
grunt v1.4.1
An Error occurs as I run any task.
Warning: Task "speak" not found. Use --force to continue.
This occurs with every function I run (for example grunt css or grunt default function) . I tried to take out whole code and make a test function and it worked... So I can sort out that the global installation is the problem. It must be my Gruntfile that is wrong.
Meanwhile I found out that some tasks were not in the right syntax structure. I changed that. Now it run my default task and other tasks without errors and firstly it looked like all runs fine. But as I tested it. The Changes in SCSS file doesn't show up in the compiled CSS File...
So something must be still wrong. So I added the new Gruntfile and replaced my name in Banner with name (so don't wonder about that). Maybe somebody know this issue... I also not know if it really would make the sourcemaps with this gruntfile code without additional plugins... But most important is that it compiles the scss ... without the whole reason of using grunt is gone...
Does anybody have an idea whats wrong
module.exports = function(grunt) {
grunt.initConfig({
package: grunt.file.readJSON('package.json'),
concat: {
js: {
src: 'scripts/js/**/_*.js',
dest:'scripts/js/app.js'
},
css: {
src: 'scripts/css/**/_*.css',
dest: 'scripts/css/app.css'
},
options: {
stripBanners: true,
banner: '//<%= package.name %> - Minified main Javascript from *Name* - <%= grunt.template.today("yyyy-mm-dd") %>'
}
},
uglify: {
options: {
banner: '//<%= package.name %> - Minified main Javascript from *Name* - <%= grunt.template.today("yyyy-mm-dd") %>',
mangle: {
reserved: 'jQuery'
},
compress: {
global_defs: {
"DEBUG": false
},
},
dead_code: false,
unused: false,
drop_console: true
},
build: {
src: 'scripts/js/app.js',
dest: 'build/scripts/js/app.min.js'
}
},
cssmin: {
options: {
specialComments: 0,
mergeIntoShorthands: false,
roundingPrecision: -1
},
target: {
files: {
'build/scripts/css/app.css': 'scripts/css/app.css'
}
}
},
sass: {
build: {
options: {
style: 'expanded',
debugInfo: true,
sourcemap: true
},
files: [{
expand: true,
cwd: 'scripts/css/',
src: ['scripts/scss/**/_*.scss'],
dest: 'scripts/css/',
ext: '.css'
}]
}
},
watch: {
js: {
files: ['scripts/js/_*.js'],
tasks: ['concat', 'uglify']
},
css: {
files: ['scripts/scss/_*.scss'],
tasks: ['concat', 'sass', 'cssmin']
},
php: {
files: ['*.html'],
tasks: ['htmlmin']
}
},
htmlmin: {
options: {
collapseWhitespace: true
},
target: {
files: {
src: '*.html',
dest: 'build/index.html'
}
}
}
});
//Load Plugins of Grunt
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-htmlmin');
grunt.loadNpmTasks('grunt-contrib-cssmin');
//Grunt Tasks
grunt.registerTask('default', ['sass', 'concat', 'cssmin', 'uglify']);
grunt.registerTask('all', ['sass', 'concat', 'cssmin','uglify']);
grunt.registerTask('css', ['sass', 'concat', 'cssmin']);
grunt.registerTask('js', 'uglify');
grunt.registerTask('publish', ['sass', 'concat', 'cssmin', 'uglify', 'htmlmin']);
grunt.registerTask('speak', function() {
console.log('I am running!');
});
};
Packages installes for grunt in package.json:
"devDependencies": {
"debug": "^4.3.1",
"grunt": "^1.4.1",
"grunt-cli": "^1.4.3",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-sass": "^2.0.0",
"grunt-contrib-uglify": "^5.0.1",
"grunt-contrib-watch": "^1.1.0",
"webpack": "^5.40.0",
"webpack-cli": "^4.7.2"
}
}
I am developing a WordPress site on a server (not local). I want to refresh the page in my browser whenever I modify a sass file. I've got some grunt tasks listed, but right now I just want it to refresh on any sass modification. Right now, it catches whenever a file is modified, but it does not refresh the page.
Gruntfile:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
scripts: {
options: { livereload: true },
files: ['**/*.scss'],
//tasks: ['criticalcss:front', 'criticalcss:page', 'cssmin', 'postcss'],
}
},
postcss: {
options: {
processors: [
require('autoprefixer')({browsers: 'last 6 versions'}), // add vendor prefixes
//require('cssnano')() // minify the result
]
},
dist: {
src: 'style.css',
dest: 'style.css'
}
},
criticalcss: {
front : {
options: {
url: "https://grandeurflooring.ca/grand_dev/",
minify: true,
width: 1500,
height: 900,
outputfile: "critical_css/critical-front.css",
filename: "style.css",
buffer: 800*1024,
ignoreConsole: true
}
},
page : {
options: {
url: "https://grandeurflooring.ca/grand_dev/sample-page/",
minify: true,
width: 1500,
height: 900,
outputfile: "critical_css/critical-page.css",
filename: "style.css",
buffer: 800*1024,
ignoreConsole: true
}
}
},
cssmin: {
target: {
files: [{
expand: true,
cwd: 'critical_css',
src: ['*.css', '!*.min.css'],
dest: 'critical_css',
ext: '.min.css'
}]
}
}
});
// Load the plugin that provides the "critical" task.
grunt.loadNpmTasks('grunt-criticalcss');
// Load the plugin that provides the "cssmin" task.
grunt.loadNpmTasks('grunt-contrib-cssmin');
// Load the plugin that provides the "watch" task.
grunt.loadNpmTasks('grunt-contrib-watch');
// Load the plugin that provides the "PostCSS" task.
grunt.loadNpmTasks('grunt-postcss');
// Critical task.
grunt.registerTask('critical', ['criticalcss:front']);
};
In footer.php, before wp_footer(), I put the script:
<script src="http://localhost:35729/livereload.js"></script>
You can configure Grunt to watch the compiled css file in your dist directory, which would be updated every time the Sass is recompiled.
Here is my watch configuration which is achieving what you want:
watch: {
options: {
livereload: true,
},
html: {
files: ['index.html'],
},
js: {
files: ['js/**/*.js'],
tasks: ['jshint'],
},
sass: {
options: {
livereload: false
},
files: ['css/scss/**/*.scss'],
tasks: ['sass'],
},
css: {
files: ['dist/css/master.css'],
tasks: []
}
}
You might need to change spawn: false to spawn: true depending on your setup as well.
EDIT: Additionally, you can use the grunt-contrib-watch plugin which allows you to:
Run predefined tasks whenever watched file patterns are added, changed or deleted
This plugin contains numerous additional options for live-reloading, watching, etc. which you may find useful.
I'm struggeling with the Chrome DevTools. I would like to optimize my workflow so I tried to configure Chrome to reload the css after compiling with grunt-contrib-compass. But I've tried now for two hours and Chrome won't reload my css file. Did I miss something?
SERVER ist running with XAMPP
CHROME CONFIG
GRUNT CONFIG
module.exports = function( grunt ) {
grunt.initConfig({
// JavaScript
eslint: {
all: [
"Gruntfile.js",
"js/app.js"
]
},
// CSS
compass: {
dev: {
options: {
importPath: "node_modules/foundation-sites/scss",
sassDir: "sass",
cssDir: "../assets/css",
noLineComments: true,
sourcemap: true
}
},
deploy: {
options: {
importPath: "node_modules/foundation-sites/scss",
sassDir: "sass",
cssDir: "../assets/css",
noLineComments: true,
environment: "production"
}
}
},
// Watch for changes
watch: {
css: {
files: ["sass/**/*.scss"],
tasks: ["compass:dev"]
},
js: {
files: ["js/**/*.js"],
tasks: ["eslint"]
}
}
});
// Load plugins
grunt.loadNpmTasks("grunt-contrib-compass");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks("eslint-grunt");
// Register Task(s).
grunt.registerTask( "dev", ["watch"] );
grunt.registerTask( "deploy", ["uglify"] );
};
RESPONSE OF grunt dev:
>> File "sass\_header.scss" changed.
Running "compass:build" (compass) task
write D:/xampp/htdocs/defaultwp/wp-content/themes/wadt/assets/css/app.css (0.853s)
write D:/xampp/htdocs/defaultwp/wp-content/themes/wadt/assets/css/app.css.map
Done. Completed in 3.455s
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']);
I have c9 workspace and I am running grunt with grunt-watchify to automatically create the bundle file. It was working fine when suddenly I get this error (debug is true on grunt-watchify):
./app/js/controller.js [ [ '.', 'app', 'js', 'controller.js' ] ]
./app/js/controller.js [ [ '.', 'app', 'js', 'controller.js' ] ]
stat [ '/home/ubuntu/workspace',
'./app/js/controller.js',
'=',
'./app/js/controller.js' ]
emit! match
matches[0] = { './app/js/controller.js': true }
emitting end [ './app/js/controller.js' ]
emit! end
Fatal error: watch EMFILE
And now it is not working. If I change watchify to browserify, it works.
This is my Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
compass: {
dist: {
options: {
appDir: 'app/',
//sassDir: 'sass',
//cssDir: 'app/stylesheets'
}
},
dev: {
options: {
appDir: 'app/',
watch: true
}
}
},
concurrent: {
dev:
['watch', 'compass:dev']
},
watchify: {
dev: {
src: './app/js/controller.js',
dest: 'app/bundle.js',
debug: true
},
},
watch: {
css: {
files: '**/*.scss',
tasks: ['compass']
},
app: {
files: 'app/js/bundle.js',
options: {
livereload: true
}
}
},
browserify: {
dist: {
files: {
'app/bundle.js': [
'app/js/*.js',
]
}
},
},
bower: {
install: {
//just run 'grunt bower:install' and you'll see files from your Bower packages in lib directory
},
options: {
targetDir: './app/lib'
}
}
});
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-watchify');
grunt.loadNpmTasks('grunt-bower-task');
grunt.registerTask('default',['bower:install', 'watchify', 'concurrent']);
grunt.registerTask('heroku',['compass:dist', 'browserify', 'bower:install']);
}
EMFILE means that there are too many files open. This is most likely caused by a process that is still running and has somehow opened many files. You can use "ps aux" to check which processes are running. In Cloud9 you can see this also in the process manager via the Tools menu (Tools > Process Manager). If you see any processes that look suspicious, such as node processes running, you can kill them via the process manager UI or by typing "kill " where is the process id of the process you which to kill. After that you should be able to run grunt again without the EMFILE error. (Assuming that grunt is not causing the issue itself).