I am looking for fastest livereload result (sass into css + browerssync)
Grunt or Gulp is better fastest result?
I was experimenting with Grunt,
When save css file we get livereload without nothing delay but when sass compile sass into css its working with 1 or 2 seconds delay
This is my grunt code
module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
watch: {
sass: {
files: "app/scss/*.scss",
tasks: "sass:dev"
}
},
sass: {
dev: {
files: {
"app/css/styles.css": "app/scss/styles.scss"
}
}
},
browserSync: {
default_options: {
bsFiles: {
src: [
"css/*.css",
"*.html"
]
},
options: {
watchTask: true,
proxy: "yourvhost.dev"
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-browser-sync');
// Launch BrowserSync + watch task
grunt.registerTask('default', ['browserSync', 'watch']);
};
Gulp has traditionally been a bit quicker since it uses node streams. A more in-depth read about the node stream subject and the Gulp/Grunt compiling of Sass you find here.
edit: if you're thinking of using Grunt, you should check out grunt-sass. Seems to be the fastest one and pretty close to the Gulp one.
Related
I'm currently using browser-refresh to restart my node server every time I make a change to my server file. I want to take this further and have my browser refresh/reload every time I make a change to an HTML file. I'm using handlebars for the client, so I have .hbs files in my views directory. I thought browser-refresh was supposed to be able to refresh the browser as well, but it's not working for me.
For grunt, I have the following tasks installed:
grunt.loadNpmTasks('grunt-express-server');
grunt.loadNpmTasks('grunt-express');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-exec');
grunt.loadNpmTasks('grunt-open');
grunt.loadNpmTasks('grunt-express-runner');
I don't think I need all of these, but I want to find something that works. I'm able to restart my server with grunt-exec, but I already have an alias for browser-refresh, so I don't really need that.
I should also note that in my app.js server file, I'm using app.use('/', routes); where var routes = require('./routes/index');. So, when my app loads (using node app.js), it goes directly to http://localhost:3000/users/login.
Thanks in advance.
Using the grunt-contrib-watch and setting the Live reload option to true, will enable live reloads and grunt auto rebuild.
For example, in your gruntfile.js:
watch: {
css: {
files: '**/*.sass',
tasks: ['sass'],
options: {
livereload: true,
},
},
},
For the rebuild of your site, (using the grunt-contrib-watch plugin), simply type
grunt watch
To auto rebuild your website on changes, have a look at an example usage of the grunt watch command below:
gruntfile.js
module.exports = function (grunt) {
grunt.initConfig({
exec: {
server: 'node server'
},
// Other JS tasks here
// ...
watch: {
css: {
files: ['scss/**/*.scss'],
tasks: ['sass'],
options: {
spawn: false
}
},
javascript: {
files: ['js/*.js'],
tasks: ['uglify']
},
options: {
livereload: true,
},
},
});
grunt.registerTask('server', ['exec:server']);
// Minify JS and create CSS files
grunt.registerTask('build', ['uglify', 'sass']);
// Do what you expect the default task to do
grunt.registerTask('default', ['build', 'exec:server']);
};
More info here: https://github.com/gruntjs/grunt-contrib-watch/blob/master/docs/watch-examples.md#enabling-live-reload-in-your-html
I have a web app in node.js that I want to start with nodemon, so everytime the main script changes, the webapp can start again.
At the same time, I have my coffeescript files that I need to recompile everytime any of them changes.
I've set up a grunt-contrib-watch task to listen just for app/frontend/*.coffee files, to dispatch the coffee parser.
However, this doesn't seem to be hapenning, since the nodemon task is also listening.
I set up app/frontend/ folder in nodemon ignore.
I also set up nodemon and watch as concurrent.
Still, everytime I edit a coffee script, the coffee task is not bein executed.
This is my Gruntfile
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
concurrent: {
dev: [
'nodemon',
'watch'
],
options: {
logConcurrentOutput: true
}
},
coffee: {
compile: {
files: {
'app/public/app.js': ['app/frontend/*.coffee']
}
}
},
nodemon: {
dev: {
script: 'app/index.js',
options: {
ignore: ['app/frontend/**', 'app/public/**']
}
}
},
watch: {
scripts: {
files: 'app/frontend/*.coffee',
tasks: ['coffee'],
options: {
spawn: false
}
}
}
});
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-nodemon');
// Default task(s).
grunt.registerTask('default', ['coffee', 'nodemon', 'watch']);
};
Your Gruntfile instructs Grunt to run nodemon and watch sequentially as the default task (and thus watch is never run as nodemon never finishes).
You need to explicitly include the concurrent task in the last line:
grunt.registerTask('default', ['coffee', 'concurrent']);
I'm new to using gruntjs and nodejs. I wanted to know how can I setup the gruntfile so that it watches both the sass files and the js files compiles using watch.
This is what I have so far:
module.exports = function ( grunt ) {
"use strict";
require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
compass: {
dist: {
options: {
config: 'config.rb',
watch: true
}
}
}
});
grunt.registerTask('default', []);
};
Any help will be much appreciated. Thank you!
Try grunt-contrib-watch with grunt-contrib-sass. They're both Grunt plugins specifically for this kind of thing:
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'css/build/global.css': 'scss/screen.scss'
}
}
},
watch: {
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false
}
}
},
The watch plugin configuration above will watch for changes in any .scss files, and will run the sass tasked (also defined above). You can even hook into livereload this way. You can also have multiple watches (the above only defines a css watch); creating a second watch to minify JS would be easy with grunt-contrib-uglify
I have an example you can look at that also concatenates JavaScript and does some minification with grunt-contrib-uglify. Here is the example.
I followed the instructions on the grunt.option page to create different configurations for different environments/targets such as development, staging, and production in my Gruntfile. However, upon doing so I found that my tasks silently fail.
I've reduced the problem to a very simple example. The following Gruntfile fails to build the file:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
less: {
dev: {
options: {
compress: true
},
build: {
src: ['src/css/test.less'],
dest: 'build/css/test.css'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less:dev']);
};
The output in my terminal is the following:
$ grunt
Running "less:dev" (less) task
Done, without errors.
If, however, I use the following Gruntfile, the build output is as expected:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
less: {
options: {
compress: true
},
build: {
src: ['src/css/test.less'],
dest: 'build/css/test.css'
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less']);
};
The terminal output for this Gruntfile reflects the built file:
$ grunt
Running "less:build" (less) task
File build/css/test.css created.
Done, without errors.
What am I doing wrong in the first Gruntfile? What is it that I am missing about this task:target convention?
Your first Gruntfile - If you want per-target options, you need to specify the files object. So your code would be something like this:
less: {
dev: {
files: {
"build/css/test.css": "src/css/test.less"
}
},
production: {
options: {
compress: true
},
files: {
"build/css/test.css": "src/css/test.less"
}
},
}
Basically in your first Gruntfile build is an unknown object. Your target is named dev and grunt-contrib-less doesn't have an option called build so Grunt doesn't know where to write the files. Your second Gruntfile works because you set the options as a global. Use the above code if you want per-target options.
When running grunt, I get the following error:
Warning: Unable to write "client/dist/js/build.js" file (Error code: undefined). Use --force to continue.
The config of uglify in my Gruntfile.js :
uglify: {
build: {
src: ['client/src/js/*.js'],
dest:['client/dist/js/build.js']
}
}
I'm using grunt-contrib-uglify.
Any ideas why this is happening?
Assuming your Grunt Version is 0.4.0, AFAIK you are not using the most recent Syntax (See https://github.com/gruntjs/grunt-contrib-uglify#usage-examples).
Try
uglify: {
build: {
files: {
'client/dist/js/build.js': ['client/src/js/*.js']
}
}
}
I am also not sure if the wildcards are handled properly.
I know this is marked as solved, but I still prefer this answer from a similar question because you can easily use the files again for an other command without writing them twice.
In short, answer says
//Does not work
src: ['client/src/js/*.js'],
dest: ['client/dist/js/build.js']
//Works
src: ['client/src/js/*.js'],
dest: 'client/dist/js/build.js'
Tested working example without writing files twice:
'use strict';
module.exports = function(grunt) {
grunt.initConfig({
uglify: {
build: {
src: ['client/src/js/*.js'],
dest: 'client/dist/js/build.js'
}
},
watch: {
js: {
files: '<%= uglify.build.src %>',
tasks: ['uglify']
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', [
'uglify',
]);
grunt.registerTask('dev', [
'watch'
]);
};
Notice that '<%= uglify.build.src %>' is very handy ;)
Execution
$ grunt watch
Running "watch" task
Waiting...OK
>> File "client/src/js/hello.js" changed.
Running "uglify:build" (uglify) task
File "client/dist/js/build.js" created.
Uncompressed size: 15 bytes.
Compressed size: 32 bytes gzipped (15 bytes minified).
Done, without errors.