Grunt CSS min - Issue with minifying different CSS files - node.js

I'm having issue with minifying multiple CSS files using grunt cssmin I'm not looking to minify all files into single file. I would like to have the files having same name with min.css extension.
My gruntfile.js is as follows.
module.exports = function (grunt) {
grunt.initConfig({
cssmin: {
target: {
files: [{
src: ['assets/css/*.css', '!assets/css/*.min.css'], // source files mask
dest: 'assets/css/', // destination folder
expand: true, // allow dynamic building
flatten: true, // remove all unnecessary nesting
ext: '.min.css' // replace .css to .min.css
}],
/* BELOW IS ONLY A TRICK USED TO MINIFY THE FILES SKIPPED BY THE ABOVE */
/*files: [{
src: ['assets/css/home.css', 'assets/css/institutions.css', 'assets/css/form-elements.css'], // source files mask
dest: 'assets/css/', // destination folder
expand: true, // allow dynamic building
flatten: true, // remove all unnecessary nesting
ext: '.min.css' // replace .css to .min.css
}],*/
}
}
});
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default', [ 'cssmin' ]);
};
As per the code (except the commented out part), it is suppose to minify all the css files. But for some reason it skips few css files from the directory. To minify those, I have to comment out the first files[{}] and uncomment the later.
It doesn't work when both files[{}] are uncommented. I'm clueless on why its happening.
My Nodejs version is: v0.10.25
Thanks in advance.
Note: I used to get warnings & task aborts on grunt cssmin due to node version issue and got it fixed by downgrading nvm version to nvm v0.10.39. Thanks to blindMoe for pointing the solution

Related

I don't understand how to work Bower properly

I'm building a site and I've decided to use a bootstrap template for the back-end (admin tools and whatnot).
I like the look of sb-admin-2 (http://startbootstrap.com/template-overviews/sb-admin-2/) but I'ma bit confused how to practically employ this in my site.
I installed Bower and installed sb-admin using bower install startbootstrap-sb-admin-2
Now I have a folder called bower_components, and it's filled with all the relevant packages... However, these packages include the development files as well.
If I upload this to my site as is, 80% of it will be unnecessary source data.
I'm currently using Gulp with my project, but I don't yet see how the 2 are supposed to interact. Is there a gulp package for compiling the bower_components into 1 concise thing?
I'm new to this kind of workflow and I can't find the answers to the questions despite my efforts. Apologies if I sound like a total noob.
There's no pre-built gulp package that will pull in all your bower source files. You should write a task that pulls in just the files you need. Here's an example from a project I'm working on (simplified):
var scripts = [
'bower_components/timezone-js/src/date.js', // https://github.com/mde/timezone-js
'bower_components/jquery/jquery.min.js', // http://api.jquery.com/
'bower_components/jquery-migrate/jquery-migrate.js', // https://github.com/appleboy/jquery-migrate
'bower_components/jquery-ui/ui/minified/jquery-ui.min.js', // todo: include just the bits we need
'bower_components/jqueryui-touch-punch/jquery.ui.touch-punch.min.js', // https://github.com/furf/jquery-ui-touch-punch
'bower_components/jquery-cookie/jquery.cookie.js', // https://github.com/carhartl/jquery-cookie
'bower_components/jquery.expander/jquery.expander.min.js', // https://github.com/kswedberg/jquery-expander
'bower_components/jquery.transit/jquery.transit.js', // http://ricostacruz.com/jquery.transit/
'bower_components/select2/select2.min.js', // http://ivaynberg.github.io/select2/
'bower_components/fancybox/source/jquery.fancybox.pack.js', // http://fancyapps.com/fancybox/
'bower_components/lodash/dist/lodash.compat.min.js', // https://lodash.com/docs
'bower_components/underscore.string/dist/underscore.string.min.js', // https://github.com/epeli/underscore.string#string-functions
'bower_components/json2/json2.js', // https://github.com/douglascrockford/JSON-js
'bower_components/jquery-validation/dist/jquery.validate.min.js', // http://jqueryvalidation.org/documentation/
'bower_components/jquery-file-upload/js/jquery.iframe-transport.js',
'bower_components/jquery-file-upload/js/jquery.fileupload.js', // https://blueimp.github.io/jQuery-File-Upload/
'bower_components/DataTables/media/js/jquery.dataTables.js', // https://datatables.net/
];
gulp.task('scripts', function () {
return gulp.src(scripts, {base: '.'})
.pipe(plumber())
.pipe(sourcemaps.init({
loadMaps: false,
debug: debug,
}))
.pipe(concat('all_the_things.js', {
newLine:'\n;' // the newline is needed in case the file ends with a line comment, the semi-colon is needed if the last statement wasn't terminated
}))
.pipe(uglify({
output: { // http://lisperator.net/uglifyjs/codegen
beautify: debug,
comments: debug ? true : /^!|\b(copyright|license)\b|#(preserve|license|cc_on)\b/i,
},
compress: { // http://lisperator.net/uglifyjs/compress, http://davidwalsh.name/compress-uglify
sequences: !debug,
booleans: !debug,
conditionals: !debug,
hoist_funs: false,
hoist_vars: debug,
warnings: debug,
},
mangle: !debug,
outSourceMap: true,
basePath: 'www',
sourceRoot: '/'
}))
.pipe(sourcemaps.write('.', {
includeContent: true,
sourceRoot: '/',
}))
.pipe(plumber.stop())
.pipe(gulp.dest('www/js'))
});
I'm cherry-picking the source files I want, combining and minifying them, and dumping them into my public directory so that can be served to the client. You don't need to upload the bower_components folder to your production server; but it probably wouldn't hurt much either (it's not THAT big!).

Grunt: Watch file changes and compile parent directory

I'm working on a project using grunt, I haven't worked with grunt before and currently this is setup as to watch files and when a file has been changed recompile all the files (multiple subdirectories containing hundreds of files) using handlebars into html which is quite slow. I want to improve this to a faster process by only compiling what is needed.
Watching the files with grunt newer doesn't really work because there are dependencies within the directory and thus only recompiling the changed files will not result in a valid page.
I would basically need to recompile the whole parent directory of the file that has changed, but I'm not quite sure on how I would configure something like that.
Any hints where I should look at?
The assemble itself is configured like this:
var _ = require('lodash');
var path = require('path');
// expand the data files and loop over each filepath
var pages = _.flatten(_.map(grunt.file.expand('./src/**/*.json'), function(filepath) {
// read in the data file
var data = grunt.file.readJSON(filepath);
var dest=path.dirname(filepath)+ '/' +path.basename(filepath, path.extname(filepath));
dest=dest.replace("src/","");
var hbs;
if (data.hbs){
hbs=grunt.file.read(path.dirname(filepath)+ '/' + data.hbs)
}
// create a 'page' object to add to the 'pages' collection
return {
// the filename will determine how the page is named later
filename: dest,
// the data from the json file
data: data,
// add the recipe template as the page content
content:hbs
};
}));
return {
options: {
/*postprocess: require('pretty'),*/
marked: {sanitize: false},
data: '<%= options.src %>/**/*.json',
helpers: '<%= options.src %>/helpers/helper-*.js',
layoutdir: '<%= options.src %>/templates',
partials: ['<%= options.src %>/components/**/*.hbs']
},
build: {
options: {
layout: 'base.hbs',
assets: '<%= options.build %>',
pages: pages
},
files: [
{
cwd: '<%= options.src %>',
dest: '<%= options.build %>',
src: '!*'
}
]
},
}
So every time this loads all the pages get scanned down like /src/sites/abc/xyz/foo.json and get compiled, but I only want to have changed files. Watch does detect changed files, but all the files get compiled again and I'm not sure how I could get the changed files that watch has recognized in the config to only process part of the files.
I think what you need is already there in watch.
Check the Using the watch event in grunt doc.
Copying down the content here to satisfy the SO MODS/GODS.
This task will emit a watch event when watched files are modified. This is useful if you would like a simple notification when files are edited or if you're using this task in tandem with another task. Here is a simple example using the watch event:
grunt.initConfig({
watch: {
scripts: {
files: ['lib/*.js'],
},
},
});
grunt.event.on('watch', function(action, filepath, target) {
grunt.log.writeln(target + ': ' + filepath + ' has ' + action);
});
The watch event is not intended for replacing the standard Grunt API for configuring and running tasks. If you're trying to run tasks from within the watch event you're more than likely doing it wrong. Please read configuring tasks.
Compiling Files As Needed
A very common request is to only compile files as needed. Here is an example that will only lint changed files with the jshint task:
grunt.initConfig({
watch: {
scripts: {
files: ['lib/*.js'],
tasks: ['jshint'],
options: {
spawn: false,
},
},
},
jshint: {
all: {
src: ['lib/*.js'],
},
},
});
// on watch events configure jshint:all to only run on changed file
grunt.event.on('watch', function(action, filepath) {
grunt.config('jshint.all.src', filepath);
});
If you need to dynamically modify your config, the spawn option must be disabled to keep the watch running under the same context.
If you save multiple files simultaneously you may opt for a more robust method:
var changedFiles = Object.create(null);
var onChange = grunt.util._.debounce(function() {
grunt.config('jshint.all.src', Object.keys(changedFiles));
changedFiles = Object.create(null);
}, 200);
grunt.event.on('watch', function(action, filepath) {
changedFiles[filepath] = action;
onChange();
});

Grunt.js only watches on change of root js file, not working on change of css or jade files

I am using grunt.js - to watch the changes on my project and reload the browser. In which it's only considering the js file change on root folder. In case if i change on stylesheet/styles.css - not refreshing the browser, same thing happening with jade filest too..
How can i make grunt to refresh the page on change of jade file or any other noted files?
here is my grunt.js:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
watch: {
all: {
options: {
livereload: true
},
files : ['*.js','puplic/stylesheet/*.css', '*.html', '/views/*.jade']
//only on js changes refresh the page!
}
}
});
// Each plugin must be loaded following this pattern
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['watch']);
}
here is my jade file:
doctype html
html
head
link(rel='stylesheet', href='/stylesheet/bootstrap.css')
link(rel='stylesheet', href='/stylesheet/styles.css')
script(src="http://localhost:35729/livereload.js")
body
div.container
h1 Welcome to Social!
Any one help me go sort this issue please?
I updated my grunt file like this, it works fine for me!
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
watch: {
all: {
options: {
livereload: true
},
files: ['**/*']
}
}
});
// Each plugin must be loaded following this pattern
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['watch']);
}
Thanks to all...

How to use yeoman, grunt, usemin 2 and requirejs?

I'm trying to wrap my head around using Grunt, usemin 2, requirejs, and uglify. What I'm observing in my builds is that requirejs is not properly including my dependencies into my single concatenated build file. When I run index.html out of /dist, I see errors when looking for 'jquery', 'app', and some third party js files or sometimes "define is not defined".
I read the following issues on grunt-usemin and removing the require blocks, but some questions still remain in those threads.
Recommended way to handle RequireJS, concat, uglify
How to handle requirejs in v2.0
I followed up my search and came across this post How to integrate Yeoman and Requirejs, which sort of got me there in that I saw the Requirejs optimizer running when I changed from using grunt-contrib-requirejs to grunt-requirejs. Unfortunately, I still see these errors:
Uncaught ReferenceError: define is not defined.
I have the following in my index.html:
<!-- build:js js/main.js -->
<script src="bower_components/requirejs/require.js"></script>
<script src="js/main.js"></script>
<!-- endbuild -->
Here is my Grunt file: http://jsbin.com/futocusu/3/edit?js
There was talk in issue #112 about creating an article on using Yeoman on this topic, but I don't think it's been written yet.
Has anyone figured out the best way to use usemin v2 with grunt and requirejs to output to a single concat+uglify file on build? I'm also not sure what the difference is in using grunt-contrib-requirejs and grunt-requirejs and when to use which one.
It looks as though you are trying to do too much with main.js.
I have the following build tasks in Gruntfile.js
grunt.registerTask('build', [
'copy', // copies the src directory to dist (htdocs)
'requirejs', // do an r.js build to concat modular dependencies
'concat:head', // concats js in the head
'uglify:head', // compresses js in the head
'uglify:foot', // compresses js in the foot
'cssmin', // minifies and concats css
'usemin', // runs through html and inputs minified js and css
'clean:afterBuild' // deletes files that are not required for build
]);
Here are each of the relevant Grunt tasks (for me these are stored in separate files because I use load-grunt-config). If you would like to use these in your gruntfile then all you need to do is grab everything that is in the returned object and stick that in your task value in your gruntfile:
copy
module.exports = function (grunt, options) {
return {
main: {
cwd: 'src/',
src: '**',
dest: 'dist/',
expand: true,
flatten: false
},
};
};
requirejs
module.exports = function(grunt, options) {
return {
compile: {
options: {
appDir: "src/to/require/app",
baseUrl: "./",
mainConfigFile: "src/to/require/app/common",
dir: "dist/to/require/app",
// build a common layer
modules: [
{
"name": "common"
}
]
}
}
};
};
concat
module.exports = function (grunt, options) {
return {
head: {
/* other stuff */
},
foot: {
src: [
'dist/to/require/app/some_other_js.js',
'dist/to/require/app/external/require.js',
'dist/to/require/app/external/require.text.js',
'dist/to/require/app/common.js'
],
dest: 'src/to/require/app/compiled_footer_js.js',
}
};
};
uglify
module.exports = function (grunt, options) {
return {
head: {
/* other stuff *
},
foot: {
files: {
'src/to/require/app/compiled_footer_js.min.js': ['src/to/require/app/compiled_footer_js.js']
}
}
};
};
usemin
module.exports = function (grunt, options) {
return {
html: [
'src/path/to/index.html'
]
};
};

Require JS optimization

I have around 50 JS files and I have to optimize it using r.js and node...
I dont want to specify all the JS files, instead specify the top level folder and somehow let r.js to get all the required js files....
Is there a way to achieve this? Currently I am specifying all the 50 js files in a common js files and referring it in my build.js...I have more files in the coming weeks, and so maintaining a common js file will be a pain.
Please suggest some steps.
here is my build file
({
baseUrl: ".",
mainConfigFile: "../App/main.js",
//modules: [
// //{ name: "../App/Crosspoint/Address/AddressList" }
// { name: "../App/Crosspoint/Office/OfficeDetails" }
//],
//paths: {
// app: '../App',
// jquery: 'jquery'
//},
name: "../App/Crosspoint/Office/OfficeDetails",
deps: ["../App"],
out: "main-built123.js",
rawText: {
'some/id': 'define(["another/id"], function () {});'
},
// dir: "app",
})
Optimizer should include all the dependencies required by main config file. Also if you have nested dependencies then specify:
findNestedDependencies: true

Resources