I've got the latest yeoman stack, and I just upgraded generator-webapp to master as per: https://github.com/yeoman/generator-webapp/pull/67 to get livereload working properly.
HTML files and css files seem to be working with livereload just fine, but scss files don't trigger a reload. Here's a snippet of output:
OK
>> File "app/index.html" changed.
Running "watch" task
... Reload app/index.html ...
... Reload app/index.html ...
Completed in 0.005s at Wed Jun 05 2013 22:45:46 GMT+0100 (BST) - Waiting...
OK
>> File "app/styles/main.scss" changed.
Running "compass:server" (compass) task
overwrite .tmp/styles/main.css
Running "watch" task
Completed in 1.101s at Wed Jun 05 2013 22:45:57 GMT+0100 (BST) - Waiting...
The scss file is being watched and compiled, but it looks as though the outputted css in .tmp is being ignored. This is despite the following in the (default) Gruntfile.
livereload: {
options: {
livereload: LIVERELOAD_PORT
},
files: [
'<%= yeoman.app %>/*.html',
'{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css',
'{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
I would post this as a bug on github, but it's difficult to know which part of the stack is responsible.
Try setting
watch: {
options: {
nospawn: false
}
}
Let me know if this does the trick!
Related
For a project I am using SASS 3.2.19 and Compass 0.12.5 combined with the last version of Grunt.
My file structure looks like this :
styles/
css/
page1.css
page2.css
page3.css
...
sass/
page1.scss
page2.scss
page3.scss
...
generics/
_general.scss
_menu.scss
_ie.scss
...
partials/
_sectionBegin.scss
_sectionClients.scss
...
In each pages{number}.scss file I import the scss blocks I actually need like this :
#import "generics/general"; // inside this file _ie.scss is imported
#import "generics/menu";
#import "partials/sectionBegins";
#import "partials/sectionClients";
.additionalStyles {
background: url(/example/example-cover.jpg) no-repeat;
}
And finally, here is my Gruntfile.js :
compass: {
dev: {
options: {
sassDir: ['styles/sass'],
cssDir: ['styles/css'],
outputStyle: 'expanded',
noLineComments: true,
environment: 'development'
}
},
...
grunt.registerTask('default', ['compass:dev' , 'watch']);
So, what I am doing here is setting Grunt to watch the sass/ repository. As soon as it detects some changes the page.css will be overwrite.
Well, this project structure actually works perfectly when there are only a few pages but now that I have more than 40 pages the compilation time is taking approximately 1min.
Indeed supposed that I edit a .scss file which is used by all the pages, all the pages will have to be overwritten.
So, what I am missing here ? How can I improve my project file structure and do you have some good examples of a gruntfile conf in a similar scenario ?
We also have a Sass project with a lot of partials. We still haven't figured out what to do when modifying a partial that is used by a lot of .scss files; there really isn't a way to get around having to compile all of them (eventually, when you deploy; sometimes you're only working on one page and really do only need one to compile in the short term). You could set up grunt tasks to compile each of your pages individually so you at least have something to run when you only need to compile a single .scss file.
The best thing to do in your case might be to think outside the box here...what if that partial WASN'T required by a lot of .scss files? What if it was only imported into one main.scss file that compiled into a minified main.css that was included on every page of your project (as the first script on the page, so its styles would get overwritten by any more specific page styles)? We have one script that includes our generic styles for things like buttons, forms, panels...stuff that's on pretty much every page, and isn't too large a burden to load in on pages that don't have a form or a button, especially if minified.
For the cases where modifying a partial only needs to prompt compilation of a few Sass files, we have figured out a solution using the Gruntfile. You can use grunt-contrib-watch to run different tasks depending on where a change was detected. For example, we have the following 2 tasks set up for grunt-contrib-sass:
sass: {
dev_mainstyles: {
options: {
sourcemap: true,
trace: true,
style: 'expanded',
compass: true,
lineNumbers: true
},
files: {
'...css/main.css': '...sass/main.scss',
},
},
dev_customerstyles: {
options: {
sourcemap: true,
trace: true,
style: 'expanded',
compass: true,
lineNumbers: true
},
files: [{
expand: true,
cwd: '.../sass/',
src: ['customers/**/*.scss'],
dest: '.../css/',
ext: '.css'
}],
},
}
I have set up the following tasks for grunt-contrib-watch:
watch: {
sassmain: {
files: ['.../sass/*.scss'],
tasks: ['sass:dev_mainstyles'],
},
sasscustomers: {
files: ['.../sass/customers/**/*.scss'],
tasks: ['sass:dev_customerstyles'],
},
}
By listing both files and directories you can get as specific as you need to and hopefully you'll be able to set up watch tasks that only compile what is needed whenever something changes! Good luck!
We're still looking for suggestions on how to make this whole process even faster, by the way, this is by no means a definitive answer, it's just some tricks we've figured out so far.
I encountered the following code when reading a project's gruntfile.js , as the comment indicates, the code is used for Renames files for browser caching purposes, but how? What will be the new names for those files?
// Renames files for browser caching purposes
rev: {
dist: {
files: {
src: [
'<%= config.dist %>/assets/js/{,*/}*.js',
'<%= config.dist %>/assets/css/{,*/}*.css',
'<%= config.dist %>/images/{,*/}*.*',
'<%= config.dist %>/styles/fonts/{,*/}*.*',
'<%= config.dist %>/*.{ico,png}'
]
}
}
},
You appear to be using grunt-rev based upon the Gruntfile.js snippet.
As the project GitHub page describes, the rev task will change file names so that browsers are forced to download fresh copies (as opposed to use stale cached copies).
In the project docs on 'Basic Asset Revving', you'll see that the task simply renames the file to an eight character hash. In the docs, they give the example of js/9becff3a.app.js.
Thus, each time you run a grunt task that includes the revving, a new set of 'cache-busting' file names will be generated using the 8-character hashed rename.
The command grunt imagemin output the following to a random file.
Fatal error: ENOENT, no such file or directory 'app/public/assets/img/epg/recordseries.png'
What's funny is that each time I run the command grunt imagemin again, it manages to process a few more files and ends by outputting the same error about another file.
I'm using
node v0.10.24
npm 1.3.21
grunt#0.4.2
grunt-contrib-imagemin#0.5.0 node_modules/grunt-contrib-imagemin
+-- filesize#2.0.0
+-- async#0.2.9
+-- chalk#0.4.0 (has-color#0.1.2, ansi-styles#1.0.0, strip-ansi#0.1.1)
+-- image-min#0.1.2 (mkdirp#0.3.5, cache-file#0.1.2, mout#0.7.1, optipng-bin#0.3.1, jpegtran-bin#0.2.3, gifsicle#0.1.4)
Here is my grunt config for imagemin task:
grunt.config('imagemin', {
options: {
optimizationLevel: 3, // 0 to 7, default =7)
// pngquant: true
},
dynamic: { // Multiple target
files: [{
expand: true, // Enable dynamic expansion
cwd: '<%= context.source %>/assets/img/', // equal to app/wesource/assets/img/
src: ['!**/*-'+arrayToRegexStr(platformIgnoreList)+'**', '**/*.{png,jpg,jpeg,gif}'], // Actual patterns to match //
dest: '<%= context.public %>/assets/img/' // equal to app/public/assets/img/
}]
}
});
Uninstalling version 0.5.0 and going back to version 0.3.0 with the following commands should restore the prior functionality:
npm uninstall grunt-contrib-imagemin
npm install --save-dev grunt-contrib-imagemin#0.3.0
There is an issue, https://github.com/gruntjs/grunt-contrib-imagemin/issues/140, that is being worked on, and when it is fixed it should be safe to upgrade.
The following solutions works on...
Ubuntu Linux 13.10 x64
npm --version = 1.3.11
node --version = v0.10.21
grunt-contrib-imagemin = 0.5.0
This is a hack of a solution, but I found the task fails when it looks at the the target directory to see if the PNG image already exists and is optimized. The task would consistently finish when I ran it over and over, each time it would complete a few more images. And I could repeat the problem by running grunt clean, then grunt imagemin over and over.
The error I saw was:
bash
Fatal error: ENOENT, no such file or directory 'build-production/path-to/some-image.png'
Solution
Copy the images to the target dir immediately before optimizing them. This way, the check passes and unoptimized images that are copied are replaced by their optimized equivalent.
task
grunt.task.run(
'copy:imagemin',
'imagemin'
);
copy configuration
copy: {
imagemin: {
files: [{
expand: true,
cwd: '<%= exponential.client.src %>',
src: ['images/**/*.{png,jpg,gif}'],
dest: '<%= exponential.client.buildProduction %>'
}]
}
}
imagemin configuration
imagemin: {
buildProduction: {
files: [{
expand: true,
cwd: '<%= exponential.client.src %>',
src: ['images/**/*.{png,jpg,gif}'],
dest: '<%= exponential.client.buildProduction %>'
}]
}
}
Try to use
cache: false
worked for me.
I was able to solve the problem by uninstalling optipngthat I had accidentally installed system wide.
I had the same issue with grunt-contrib-imagemin and it was because I was running grunt with sudo.
My fix was to do a chown and a chmod on the entire structure then run grunt without sudo...
what worked for me was a clean install of the node modules
I remove the node_modules dir and did npm install
after that it worked again for me
I am using grunt and I'm trying to get the watch/livereload task to run on my local server (MAMP) but with no success.
I'm calling the task based on HTML5 Boilerplate grunt files (https://github.com/h5bp/html5boilerplate.com/blob/master/Gruntfile.js, https://github.com/h5bp/html5boilerplate.com/blob/master/package.json).
I have also tried implementing Tiny-lr (https://github.com/mklabs/tiny-lr) without success either.
My connect and watch options right now are this
connect: {
options: {
hostname: 'localhost',
livereload: 35729,
port: 8888
},
livereload: {
options: {
base: '../',
open: true
}
},
},
watch: {
files: '<%= settings.dir.src %>/**',
less: {
files: ['src/less/*.less'],
tasks: ['less'],
},
options: {
livereload: '<%= connect.options.livereload %>'
},
scripts: {
files: ['<%= settings.dir.src %>/js/*.js', 'css/**/*.scss' ],
tasks: 'default',
options: {
spawn: false,
}
}
}
And here I declare the dev task:
// development task
grunt.registerTask('dev', [
'connect:livereload',
'watch'
]);
When I run 'grunt dev' my browser opens at http://127.0.0.1:8888/ and displays only this: Cannot GET /
I need my browser to open http://localhost:8888/ctrl/ (ctrl being the name of the folder project on MAMP, could be anything), I thought that changing the "base" option was the way to go but nope, it is not, and I cannot add "/ctrl" to host name either, nor to the port.
Any ideas?
Thank you
Here is a link to my whole code: https://github.com/zolitariuz/ctrl
i think you are misunderstanding 2 tasks in grunt,
the connect task is used to create a http server spawned by node js, so no php nor mysql support, you DON'T want to run you WP site thru that.
the watch task is looking for changes in files on YOUR computer, launching the according task after a file change, then trigger the live reload.
you should remove connect completely after you copied the live reload object in your watch task.
the you should run your local lamp stack for running wp then start the watch task for file changes.
on the wp side you should enqueue the live reload script, or use a browser extension that will inject it for you.
Here is my Gruntfile.js
watch: {
options: { livereload: true },
compass: {
files: ['assets/sass/*.{scss,sass}'],
tasks: ['compass']
},
// js: {
// files: '<%= jshint.all %>',
// tasks: ['jshint', 'uglify']
// },
livereload: {
// files: ['*.html', '*.php', 'assets/stylesheets/**/*.{css}']
files: ['*.html', '*.php', 'assets/stylesheets/custom.css']
}
},
// compass and scss
compass: {
dist: {
options: {
config: 'config.rb',
force: true
}
}
},
and this is output from grunt watch :
Done, without errors.
... Reload assets/sass/custom.scss ...
... Reload assets/stylesheets/custom.css ...
Completed in 11.033s at Fri Dec 06 2013 14:20:48 GMT+0100 (CET) - Waiting...
OK
>> File "assets/stylesheets/custom.css" changed.
>> File "assets/sass/custom.scss" changed.
Running "compass:dist" (compass) task
overwrite assets/stylesheets/custom.css (0.701s)
identical assets/stylesheets/app.css (3.452s)
Compilation took 4.158s
Done, without errors.
... Reload assets/sass/custom.scss ...
... Reload assets/stylesheets/custom.css ...
Completed in 10.719s at Fri Dec 06 2013 14:21:53 GMT+0100 (CET) - Waiting...
..so, why is livereload taking so much time for refreshing the page,
10secs to preview any change in my .scss file, also how it would be
possible not to refresh page completely but only inject .css changes
in page?
..another thing i would like to know is how to avoid that
compilation lag on app.css, which took almost 4 secs, and it is not
even changed?
I am using livereload browser extension with this configuration.
Thanks.
1a: to speed things up in a watch task try the option spawn:false. This might make things unstable, but it's worth a try. If it seems ok go for it. It might cause you problems later though if you add a lot of different tasks to the watch task. But you can worry about that then and disable it potentially.
1b:
First of all don't enable livereload on for the compass task. (you have it globally, take in only in the css) Because of this it will trigger a livereload event for the scss file as well. But since the livereload client doesn't know this file then it will reload the whole page. Make sure the only reported file is the compiled css.
Secondly the watch task will trigger livereload for previously changed files as well. This is a known but, I believe it is fixed in master, but no published yet.
https://github.com/gruntjs/grunt-contrib-watch/issues/205
2:
Well it have to compile it to compare it, then it just reports that it is identical.
To only inject .css changes:
watch: {
compass: {
files: ['assets/sass/*.{scss,sass}'],
tasks: ['compass']
},
livereload: {
files: ['assets/stylesheets/*.css'],
options: { livereload: true }
}
}
Unfortunately, I am also getting slow and similar compilation times (it must be compass).