I'm using Yeoman template to develop a static web site. grunt serve nicely works with the auto reload plugin.
For repeating elements I started to use {{mustache}} partials and it works like a blast. Now I want the auto reload to assemble my page, so I can look at the resulting page when editing one of the mustache files (either a main file or a partial).
I found a grunt task for it, but stitching it together eludes me. My config looks like this:
grunt.initConfig({
sass: {
dev: {
src: ['src/sass/*.sass'],
dest: 'dest/css/index.css',
},
},
watch: {
sass: {
// We watch and compile sass files as normal but don't live reload here
files: ['src/sass/*.sass'],
tasks: ['sass']
},
mustache: {
files: '**/*.mustache',
tasks: ['mustache_render'],
options: {
interrupt: true
},
},
livereload: {
options: { livereload: true },
files: ['dest/**/*']
}
},
mustache_render: {
options: {
{data: 'common-data.json'}
},
your_target: {
files: [
{expand: true,
template: '**/*.mustache',
dest: 'dest/'}
]
}
}
});
I must be missing something since the html files are not updated when I save the file.
You can add the livereload option directly to your mustache target options.
grunt.initConfig({
watch: {
mustache: {
files: '**/*.mustache',
tasks: ['mustache_render'],
options: {
interrupt: true,
livereload: true
},
}
},
mustache_render: {
options: {
{data: 'common-data.json'}
},
main: {
files: [
{expand: true,
template: '**/*.mustache',
dest: 'dest/'}
]
}
}
});
Also, if you're using grunt-contrib-connect to serve your files, don't forget to add the livereload option to it:
connect: {
http: {
options: {
hostname: "*",
port: process.env.PORT || 80,
livereload: true
}
}
}
Related
I'm setting a grunt file for a task. My goal is to create a css file from a sass file (scss) and add an autoprefix to all the proprieties which require so. Initially I used the propriety multifiles but it didn't work, so now I'm using the target propriety that works fine, but my problem is, even if I target the very same file, it will create another file in my folder where I put all my sass files.
So far my file is the following:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dev: {
options: {
style: 'expanded',
sourcemap: 'none',
},
files: {
'../style.css': 'scss/style.scss'
}
},
dist: {
options: {
style: 'compressed',
sourcemap: 'none',
},
files: {
'../style-min.css': 'scss/style.scss'
}
}
},
autoprefixer: {
options: {
browsers: ['last 6 versions']
},
target: {
expand: true,
flatten: true,
src: '../style.css',
dest: ''
}
},
watch: {
css: {
files: '**/*.scss',
tasks: ['sass', 'autoprefixer']
}
},
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.registerTask('default', ['watch']);
}
My goal is to set up a global task for all my css files, like so:
target: {
expand: true,
flatten: true,
src: '*.css',
dest: ''
}
but it is not working even if I try something like:
target: {
expand: true,
flatten: true,
src: '../*.css',
dest: ''
}
Does anyone know why?
Use cwd (stands for current working directory) which is the path where grunt looks for the files matching the pattern in src. Also define the dest so that it would create the destination file in the same folder.
target: {
expand: true,
flatten: true,
cwd: '../',
src: [ '**/*.css' ],
dest: '../'
}
I keep running into this problem everytime I try to use the live reload option of grunt watch.
No matter which port I use, I keep getting the "Fatal error: Port xxxx is already in use by another process."
I listed all ports in use, and choosing a random number that doesn't appear in the list doesn't help: it substitues xxxx with whatever port was last used in the gruntfile.
My gruntfile itself:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
options: {
livereload: true
},
js: {
files: ['.dev/**/*.js'],
tasks: ['concat', 'uglify', 'watch'],
},
scss: {
files: ['./dev/scss/*.scss'],
tasks: ['sass', 'concat', 'watch'],
options: {
reload: true,
livereload: false,
}
},
html: {
files: ['./dev/**/*.html', 'watch'],
tasks: ['copy', 'watch'],
},
grunt: {
files: ['Gruntfile.js'],
tasks: ['watch'],
},
},
concat: {
js: {
src: ['dev/js/script1.js', 'dev/js/script2.js'],
dest: 'dev/js/script.js',
},
css: {
src: ['./dev/css/nav.css', './dev/css/anim.css', './dev/css/style.css'],
dest: './dist/css/style.css',
},
},
uglify: {
build: {
src: 'dev/js/script.js',
dest: 'dist/js/script.min.js'
}
},
sass: { // Task
dev: { // Target
files: { // Dictionary of files
'./dev/css/style.css': './dev/scss/style.scss', // 'destination': 'source'
},
tasks: ['copy'],
}
},
copy: {
main: {
expand: true,
cwd: './dev/html',
src: '*.html',
dest: './dist/html/'
},
},
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-sass');
// Default task(s).
grunt.registerTask('default', ['concat', 'uglify', 'sass', 'copy', 'watch']);
};
I'm still new to npm, grunt etc, and have had this issue using Yeoman as well.
Is there some application that might automatically listen to every port (I'm using Webstorm)?
However, when I close it down and use sublime and a terminal, it keeps on saying every random port is already in use
Looks like you're recursively calling watch..
Take this portion of your gruntfile for example:
watch: { // hey grunt, you now know of a task called 'watch'
....
html: {
files: ['./dev/**/*.html', 'watch'], // here are the files to watch
tasks: ['copy', 'watch'], // and oh, hey, when you run watch, make
// sure to run watch again, recursively, forever
}
I think you can see where this is going. Your port is in use because your watch task is already running when it tries to run again. You don't need to register 'watch' as a task on each subsection of watch. Hope that helps :)
I have this setup in my Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
compress: false,
yuicompress: false,
optimization: 0
},
files: {
// target.css file: source.less file
"assets/css/main.css": "assets/css/main.less"
},
}
},
watch: {
styles: {
// Which files to watch (all .less files recursively in the less directory)
files: ['assets/css/*.less', 'assets/less/*.less'],
tasks: ['less'],
},
// Live reload CSS
css: {
files: ['assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true,
},
},
},
});
// Watch
grunt.loadNpmTasks('grunt-contrib-watch');
// Less Complile
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less','watch']);
};
My sylesheet is loaded like this:
<link rel="stylesheet" href="http://project.dev/wp-content/themes/project/style.css">
Whenever I change the css file the I get a 404 error in the browser for this url
http://project.dev/assets/css/main.css?livereload=1392748371895
Which is of course right because the css file lives in:
http://project.dev/wp-content/themes/project/assets/css/main.css
How do I get live reload to get the right URL?
You have to set the base so that Grunt knows where to run the application from. The files the tasks output should be set to reflect the structure Wordpress expects. Its all in the path configuration.
You can achieve a more flexible path structure if you configure it early on Grunt's configuration. Assuming that the Gruntfile.js is in the root of your site (besides the wp-content directory), you could do the following configuration:
grunt.initConfig({
// configurable paths
cfg: {
dist: './wp-content/themes/project'
},
// tasks configurations come here...
});
Then on the watch task, you'd set:
livereload: {
files: ['<%= cfg.dist %>/assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true
}
}
The resulting Gruntfile.js would look like:
module.exports = function(grunt) {
grunt.initConfig({
// configurable paths
cfg: {
dist: './wp-content/themes/project'
},
less: {
development: {
options: {
compress: false,
yuicompress: false,
optimization: 0
},
files: {
'<%= cfg.dist %>/assets/css/main.css': '<%= cfg.dist %>/assets/css/main.less'
}
}
},
watch: {
styles: {
files: ['<%= cfg.dist %>/assets/css/*.less', '<%= cfg.dist %>/assets/less/*.less'],
tasks: ['less']
},
css: {
files: ['<%= cfg.dist %>/assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less','watch']);
};
You'd still have to adjust the above to fit your needs, but the principle is there.
I don't have a setup I can test this on, but I think you need to set the base option:
// Project configuration.
grunt.initConfig({
connect: {
server: {
options: {
base: 'www-root'
}
}
}
});
See doc here: https://github.com/gruntjs/grunt-contrib-connect/blob/master/README.md#basic-use
Read down through multiple servers if relevant.
I am trying to use TypeScript inside a Yeoman / Grunt project. To compile TypeScript I use a grunt plugin called grunt-ts, the compilation of the .ts files works just fine, but the live reload doesn't works:
When I run grunt server I correctly get this:
Running "ts:dev" (ts) task
Compiling.
Success: 3.37s for 2 typescript files
Watching all Typescript files under : /home/mimo/webroot/tsyong/app/scripts
But then the liveReload task is not loaded.
This is how I configured my Gruntfile.js about grunt-ts.
grunt.initConfig({
...
ts: {
options: { // use to override the default options, http://gruntjs.com/configuring-tasks#options
target: 'es3', // es3 (default) / or es5
module: 'commonjs', // amd , commonjs (default)
sourcemap: true, // true (default) | false
declaration: false, // true | false (default)
nolib: false, // true | false (default)
comments: false // true | false (default)
},
dev: { // a particular target
src: ['<%= yeoman.app %>/scripts/{,*/}*.ts'], // The source typescript files, http://gruntjs.com/configuring-tasks#files
reference: '<%= yeoman.app %>/scripts/reference.ts', // If specified, generate this file that you can use for your reference management
out: '<%= yeoman.app %>/scripts/out.js', // If specified, generate an out.js file which is the merged js file
watch: '<%= yeoman.app %>/scripts/', // If specified, configures this target to watch the specified director for ts changes and reruns itself.
options: { // override the main options, http://gruntjs.com/configuring-tasks#options
sourcemap: true,
declaration: true
},
},
build: { // another target
src: ['<%= yeoman.app %>/scripts/*.ts'],
options: { // overide the main options for this target
sourcemap: false,
}
},
},
...
...
grunt.task.run([
...
'ts',
...
]);
...
grunt.registerTask('build', [
...
'ts',
...
]);
You can have a look at the full Gruntfile.js: https://github.com/mimo84/tsyong/blob/master/Gruntfile.js
Short answer: remove the watch config line https://github.com/mimo84/tsyong/blob/master/Gruntfile.js#L46 and add something like https://github.com/mimo84/tsyong/blob/master/Gruntfile.js#L60
But for ts. i.e.
ts: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.ts'],
tasks: ['ts:dev']
},
Reason: That's because when you ask grunt-ts to watch a folder, grunt-ts marks itself as an async task. This means that then no other tasks can execute afterwards. Its the same with grunt-contrib-watch I think which is why you must have it as the last task:
grunt.task.run([
'clean:server',
'concurrent:server',
'ts',
'connect:livereload',
'open',
'watch' // last task
]);
In short you can only have one task do your watching :) In your case it would have to be grunt-contrib-watch.
I use a very fast and simple way, using browserify & typescriptifier (<2s reload):
module.exports = function (grunt) {
grunt.initConfig({
clean: {
dev: ['dest/**/*.*']
},
browserify: {
dev: {
src: ['src/root.ts'],
dest: 'dest/App.js',
options: {
external: ['angular'],
transform: ['typescriptifier'],
debug: true,
bundleOptions: { debug: true },
browserifyOptions: { debug: true }
}
}
},
express: {
dev: {
options: {
bases: ['src'],
port: 5000,
hostname: '0.0.0.0',
livereload: false
}
}
},
watch: {
ts: {
files: ['src/**/*.ts', '!src/**/*.d.ts'],
tasks: ['dest'],
options: {
livereload: true,
debug: false,
debounceDelay: 100
}
},
html: {
files: ['src/**/*.css', 'src/**/*.html'],
options: {
livereload: true,
debug: false,
debounceDelay: 100,
spawn: false
}
}
}
});
grunt.loadNpmTasks('grunt-express');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.registerTask('dev', ['rebuild', 'express:dev', 'watch' ]);
grunt.registerTask('build', ['browserify:dev']);
grunt.registerTask('rebuild', ['clean:dev', 'build']);
};
See
https://www.npmjs.org/package/typescriptifier
Not exactly the answer but goes to the underlying point: fast workflow.
I am having a little trouble with Grunt, it's compiling my Sass/SCSS files (.scss I am using) but it won't LiveReload. I'm using the 'watch' dependency which integrates the LiveReload functionality.
Watch: https://github.com/gruntjs/grunt-contrib-watch
Sass/SCSS: https://github.com/gruntjs/grunt-contrib-sass
Here's my config below (relevant piece), can anyone advise as to where I'm going wrong? It live reloads for everyother file and folder.
grunt.initConfig({
connect: {
options: {
port: 9000,
hostname: 'localhost'
},
livereload: {
options: {
middleware: function ( connect ) {
return [
mountFolder(connect, 'app'),
lrSnippet
];
}
}
}
},
open: {
server: {
path: 'http://localhost:<%= connect.options.port %>'
}
},
sass: {
app: {
files: {
'./app/css/style.min.css': 'app/css/scss/style.scss'
}
}
},
watch: {
options: {
nospawn: true
},
css: {
files: './app/css/scss/*.scss',
tasks: ['sass'],
options: {
livereload: true,
},
},
livereload: {
options: {
livereload: LIVERELOAD_PORT
},
files: [
'app/{,*/}*.html',
'app/css/{,*/}*.{css,scss,sass}',
'app/js/{,*/}*.js',
'app/img/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
}
});
Instead of using the connect middleware, try using something like this in your watch task (coffeescript Gruntfile syntax below):
watch:
livereload:
files: "path/to/generated/css"
options:
livereload: true