grunt: uglify css files with uglifyjs - gruntjs

I'm using grunt to uglify my static files (using grunt v0.4.0). I have configured it to uglify one file, but I can't figure out how to get it to do two files - despite reading this question and the usage examples.
Here's what I have currently:
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
mangle: true
},
build: {
src: 'dist/main.js',
dest: 'dist/main.min.js'
}
}
I'd like to uglify dist/main.css as well. How can I add it? I tried this, following the usage examples:
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
mangle: true
},
build: {
files: {
'dist/main.min.js': ['dist/main.js'],
'dist/main.min.css': ['dist/main.css']
}
}
}
But this gives me the following error:
WARN: ERROR: Unexpected token: punc ({) [dist/main.css:7,41]
Warning: Uglification failed. Use --force to continue.
Aborted due to warnings.
Seems like it's choking on the first { - why would that happen? It is valid CSS.

Uglify is for Javascript not CSS. Try using http://github.com/gruntjs/grunt-contrib-cssmin to minify CSS using Grunt.

Uglify is for Javascript only, but YUI Compressor can do both Javascript and CSS: YUI Compressor

There is a similar solution called UglifyCSS (https://github.com/fmarcia/UglifyCSS):
shell: uglifycss "source.css" > "output.min.css"
Where behaves much like UglifyJS.

Related

How to include third party library with Grunt

New to Grunt, and have been using it for the first time to combine/minify JS files for a project.
Currently have this (relevant section) in Gruntfile.js:
concat:
{
options:
{
banner: '<%= banner %>',
stripBanners: true
},
dist:
{
src:
[
'build/js/sample_file',
'build/js/another_file.js'
],
dest: 'dist/<%= pkg.build_name %>-<%= pkg.version %>.js'
}
},
uglify:
{
options:
{
banner: '<%= banner %>'
},
dist:
{
src: '<%= concat.dist.dest %>',
dest: 'dist/<%= pkg.build_name %>-<%= pkg.version %>.min.js'
}
},
That's working fine, but I'm not sure how to do the next thing I need. My project requires Hammer.js.
I could just include the library in the concat, but this doesn't seem right to me for 2 reasons. It's already minified (I could get un-minified, but seems a bit of a waste of time when minified already), and it would seem Grunt would be a bit cleverer than this, and could be used to download the latest Hammer library for me?
How do I get Grunt to include a third-party JS library in the uglified code it builds?
use bower for your dependency-management of vendor libraries
use grunt for linting, testing, building
it's not possible to tell you on how to combine these two, as your question is to unspecific.
in general i would use yeoman and some generator to get my project setup. if none of them satisfies your needs, try to learn from them!

Grunt command always run the same Gruntfile

i'm trying to learn Grunt and i create a file, cd to there, and use the grunt command, but doesn't execute my file, but executes other that belongs to a personal project made with yeoman, and no matter the place in the terminal, always run that project. I use:
$ grunt --base "/Users/user/Documents/Ejercicios angular/Ui-routes-tutorial/"
and it shows me:
Warning: Task "newer:jshint" not found. Use --force to continue.
Aborted due to warnings.
Execution Time (2014-04-18 13:41:21 UTC)
loading tasks 3ms ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 60%
default 2ms ▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 40%
Total 5ms
Here is my file:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
}
}
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task(s).
grunt.registerTask('default', ['uglify']);
};
The error shows Task "newer:jshint" not found, but in my file i don't use that! Can you help me please?
Have you tried CD to the directory of the project, then do a npm install to ensure all the modules defined in the package file are installed, and then run your grunt command?

Grunt uglify not finding files

I have the following directory structure:
--development
-js
-pages
--js
-pages
I'm trying to take all files in development/js/pages and output them js/pages and minify them using grunt uglify but still keep seperate files - I don't want to combine all the files together. I've tried the following:
build: {
src: 'development/js/pages/*.js',
dest: 'js/page',
options: {
sourceMap: true,
compress: true,
mangle: true
}
}
but this gives me an error: unable to write js/page file
Then I tried this, which is on the uglify documentation:
build : {
files: [{
cwd: 'development/js/pages',
src: '*.js',
dest: 'js/page'
}],
options : {
sourceMap: true,
compress: true,
mangle: true
}
}
but this just gives me this error for each file in development/js/pages:
source File "filename.js" not found
and then another error saying Destination (js/page) not written because the source files are empty.
Any ideas why?
For anyone else looking the second option above almost worked but I needed to remove the options block and include expand in the files block:
pages: {
files: [{
expand: true,
cwd: 'development/js/page',
src: '*.js',
dest: 'js/page/',
ext : '.min.js',
}]
}
I wanted to answer with another option.
Here is how I write my Uglify Grunt task incase you want to keep your options. It's setup to read as (dest : src), I also concat all my library files in task prior to Uglify.
-
uglify: {
options: {
// the banner is inserted at the top of the output
banner: '/* \n Site: <%= pkg.name %> \n Version: <%= pkg.version %> \n Build Date: <%= grunt.template.today("mm-dd-yyyy") %> \n */\n \n'
},
site: {
files: {
'./_build/js/lib/lib.min.js': ['<%= concat.site.dest %>'],
'./_build/js/app/app.min.js': ['./_build/js/app/app.js']
}
}
},

usemin define custom step options

I have a Gruntfile running concat and uglify with specific options (i.e. mangle toplevel variables) and then I use sed to update the references to the minified files in index.html. This solution works but is not very maintainable because of sed. I was trying to use usemin instead but I could not figure out how to define my own custom steps with the right options for uglifyjs and the doco lacks in examples to do that. I tried to use the same uglify task I had written before:
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
mangle: {
except: ['$', 'd3'],
toplevel: true
}
},
build: {
src: 'demo/js/<%= pkg.name %>.js',
dest: 'demo/js/<%= pkg.name %>.min.js'
}
},
useminPrepare : {
html : 'src/index.html',
options: {
flow: {
steps: {'js' : ['uglify'] }
}
}
}
but I am getting this error:
Warning: Cannot find module 'path-to-module\node_modules\grunt-usemin\lib\config\uglify' Use --force to continue.
Is it possible to do this and if so, what am i doing wrong here?
Try replacing uglify with uglifyjs in your flow options.

Refresh less css which has other imported less files without page load

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.

Resources