I have configured GruntJS in Visual Studio 2015 to minify my JavaScript files using UglifyJS. Works fine.
However, I'd like this to happen only when I have Visual Studio in Release mode. In Debug mode I'd like to debug my JavaScript files and minified JavaScript is hard (impossible) to debug.
I used the following to solve this problem using the ASP.Net 5 task runner.
My solution has the following folder hierarchy.
Solution
->wwwroot
->Scripts
->app.js
->Controllers
->controller1.js
->controller2.js
1.) A file watcher watches the Scripts directory and all sub folders.
2.) When a file change is detected all *.js files are copied from the script folder to my wwwroot directory in it's script folder.
3.) Then an uglify task runs on the script folder in the wwwroot directory, this minifies it into a single app.js file which is referenced by the html application.
The uglify task has the sourceMap option turned to turn which allows javascript debuggers to reference the scrips while in debug mode but when running not in debug mode the minified script is used.
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.initConfig({
copy: {
main: {
files: [
{
expand: true,
src: ['Scripts/app.js', 'Scripts/Controllers/**'],
dest: 'wwwroot'
}
]
}
},
uglify: {
my_target: {
files: { 'wwwroot/app.js': ['wwwroot/Scripts/app.js', 'wwwroot/Scripts/**/*.js'] },
options : {sourceMap : true}
}
},
watch: {
scripts: {
files: ['Scripts/app.js','Scripts/**/*.js'],
tasks: ['copy:main', 'uglify']
}
}
});
grunt.registerTask('default', ['copy:main', 'uglify', 'watch:scripts']);
};
Related
Hello people of the world. I've been trying to automate my grunt workspace for a static web app. An example of my file structure is below. My current grunt setup watches for changes in files in the src folder, and if there is a change, it processes and updates only the files that have changed using grunt-newer, and puts them in the minified folder.
Let's say that I delete styles.scss from the src folder. Then I also need the corresponding styles.css to get deleted. Is there any way that I can automate this with Grunt? As shown in the problem above, I also need it to know that styles.css in the minified folder corresponds to styles.scss in the src folder.
File structure:
src
styles.scss
index.haml
minified
styles.css
file.html
Edit: Something like this: https://github.com/tschaub/grunt-newer/issues/15
Note that there is no solution to that issue
You can do something like this on your GruntFile:
sass: {
dist: {
files: {
'style/style.css' : 'sass/style.scss'
}
}
},
watch: {
css: {
files: '**/*.scss',
tasks: ['clean','sass'],
options: {
event: ['deleted'],
},
}
},
clean: {
dist: {
files: [{
src: [
'dist/*.css'
]
}]
}
}
As it, if you delete (and only deleted) a .saas file, your dist folder will be automaticly cleaned and your sass file rebuild.
It use:
grunt watch: https://github.com/gruntjs/grunt-contrib-watch
grunt saas: https://github.com/gruntjs/grunt-contrib-sass
grunt clean: https://github.com/gruntjs/grunt-contrib-clean
A nice tutorial: http://ryanchristiani.com/getting-started-with-grunt-and-sass/
Hope this help!
I'm completely new at Grunt, Bower etc. and have spent the evening playing around with a basic Gruntfile.js that contains the following:
module.exports = function(grunt){
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jshint: {
all: ['Gruntfile.js']
},
bower_concat: {
all: {
dest: 'assets/libs/<% pkg.name %>-bower.js',
mainFiles: {
'flux': ['dist/Flux.js']
}
}
}
});
require('load-grunt-tasks')(grunt);
grunt.registerTask('default', ['jshint', 'bower_concat']);
};
However, when I run grunt bower_concat I get
Running "bower_concat:all" (bower_concat) task
Done, without errors.
but no JavaScript file is outputted in the destination folder (and I've tried running jshint, which does not complain).
I've tried lots of things, from e.g. removing mainFiles to including bowerOptions: { relative: false }.
The structure of my project is
Web
assets
libs
bower_components
flux
node_modules
grunt
grunt-bower_concat
grunt-contrib-jshint
load-grunt-tasks
In the Web folder, I have bower.json, Gruntfile.js and package.json and it's from this folder that I run the command grunt bower_concat.
Does anyone have any idea what I'm doing wrong?
I have a less compile grunt task where relative path to less files from grunt installed folder is raw/less/source_map/
here is the grunt file.
Gruntfile: (EDIT: changed to #Yogesh Khatri's code still same issue)
module.exports = function(grunt) {
grunt.initConfig({
less: {
files: { "raw/less/source_map/style.css" : "raw/less/source_map/style.less" }
},
watch: {
js: {
files: ['raw/less/source_map/style.less'],
tasks: ['default'],
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less']);
};
on running it the command line displays
^CMacPro:grunt sagiavinashvarma$ grunt watch
Running "watch" task
Waiting...
>> File "raw/less/source_map/style.less" changed.
Running "less:files" (less) task
Done, without errors.
Completed in 1.862s at Tue Dec 09 2014 15:03:37 GMT+0530 (IST) - Waiting...
but there is no style.css output. I have written the simplest grunt task without any options.
can anyone point out whats wrong with this.
Edit:
I got the problem. It isn't working because less task need a specific target to work.
Try to change the code like this
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
files: { "raw/less/source_map/style.css" : "raw/less/source_map/style.less" }
}
},
watch: {
js: {
files: ['raw/less/source_map/style.less'],
tasks: ['default'],
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less']);
};
I got the error by running grunt --verbose which shows lot more information about the tasks. It gave me the output like
Verifying property less.files exists in config...OK
File: [no files]
Options: report="min", banner=""
>> Destination not written because no source files were provided.
of which searching led me to this :- grunt-contrib-less cannot find source files even though path is correct
I am trying to take my front-end workflow a step higher with Grunt tasks.
I have set up a couple of tasks in my Gruntfile.js. For now there are only grunt-contrib-sass and grunt-contrib-watch so that .css files are automatically recompiled whenever I make a change to my .sass files.
What I want to achieve is the following:
I want to add a task that would listen to my local server that was started with UniServerZ/XAMPP/WAMP or any other provider. I want to trigger a reload each time I edit any file in the server base directory.
I know that it is quite easy to set up such a task with, e.g. 'grunt-express' which starts a local server for you, but I really want to listen to a server started with UniServerZ/XAMPP/WAMP.
I will be grateful to see example configuration for such scenario if it is possible to achieve it.
Here is how I did it with Wamp 2.2 on Windows 7.
First, you need grunt-contrib-watch properly setup with livereload. I also use grunt-sass and not grunt-contrib-sass, because grunt-sass use Libsass. LibSass is a C/C++ port of the Sass engine, and it is faster.
To install them, use these commands :
npm install grunt-contrib-watch --save-dev
npm install grunt-sass --save-dev
Here is an example of Gruntfile :
module.exports = function(grunt) {
grunt.initConfig({
watch: {
sass: {
files: 'folder/to/your/sass/**/*.sass',
tasks: ['sass:dist'],
options: {
livereload: true,
},
},
//Watch your theme files
livereload: {
files: ['pathToTheme/*.php', 'pathToTheme/img/**/*.{png,jpg,jpeg,gif,webp,svg}'],
options: {
livereload: true
},
}
},
sass: {
options: {
includePaths: ['where/to/find/additional/#import/scss/files'],
outputStyle: 'nested',
imagePath: 'how/to/rewrite/image/path',
sourceMap: true
},
dist: {
files: {
'output/file.css': 'input/file.scss'
}
}
},
});
// Default task
grunt.registerTask('default', ['watch']);
// Load NpmTask
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass');
};
You could save yourself some time with load-grunt-tasks, and remove the manual loading of task :
require('load-grunt-tasks')(grunt); // npm install --save-dev load-grunt-tasks
Then I use the livereload plugin for firefox (or chrome or safari).
Start the grunt watch task, open your site on localhost, and click on the icon in your browser. Now if you edit a watched file, the page should update accordingly.
A solution exist to add the livereload js in your Wordpress automatically (in function.php):
if (in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'))) {
wp_register_script('livereload', 'http://localhost:35729/livereload.js?snipver=1', null, false, true);
wp_enqueue_script('livereload');
}
I want to use watch mode in my development environment. It works fine with single less file. But I have so many less files which are imported to app.less. My app.less looks
#import "variables";
#import "mixins";
It seems I can not use watch mode in this setting. Is there any other ways?
Upd. This syntax is for old grunt versions so it should not be used.
You need to use LiveReload app for this. Or maybe another software that can reload page with LiveReload browser extension (maybe Sublime Text editor with a plugin).
Possible setup is Node.js with Grunt which has grunt-contrib-less and grunt-reload modules installed.
Your grunt.js config should look like this:
module.exports = function(grunt) {
grunt.initConfig({
// Start LiveReload server
reload: {
port: 35729,
liveReload: {}
},
// Simple css compilation
less: {
src: 'less/app.less',
dest: 'css/app.css'
},
// Reload files on change
watch: {
less: {
files: ['less/*.less'],
tasks: 'less'
},
reload: {
files: ['*.html',
'css/app.css',
'js/*.js'],
tasks: 'reload'
}
}
});
// Third party modules
grunt.loadNpmTasks('grunt-reload');
grunt.loadNpmTasks('grunt-contrib-less');
// Register default task
grunt.registerTask('default', 'less');
};
Then you need to run
$ grunt watch:less
and
$ grunt watch:reload
in two separate terminal windows.
I'm totally agree with this comment
Refresh less css which has other imported less files without page load .
Thanks, thevasya.
But there's no need to start several terminals.
watch: {
less: {
files: ['less/*.less'],
tasks: 'less'
},
reload: {
files: ['*.html',
'css/app.css',
'js/*.js'],
tasks: 'reload'
}
}
after that you can start watching by
$ grunt watch
and that's it. If you change any less file, it will start only less task.
P.S.: This answer was updated for proper work with grunt 0.4.