Single config files for all tasks - gruntjs

I'd like to make configuration of grunt tasks a bit easier. Currently I've got a lot of different configuration files, like a .csslintrc, jshintrc, bower.json and so on.
It would be really cool if I could concatenate all these configuration files into one single file. This configuration file could look something like
{
"csslint": {
"important": 1,
// ...
},
"jshint": {
//...
},
"bower": {
//...
}
}
My only solution so far would be using a preprocessor and simply insert the options in the tasks (I couldn't figure out how to insert options otherwise). But this doesn't seem to be a very beautiful way...

Most (all?) grunt tasks let you define options in the Gruntfile itself instead of their respective .*rc files.
So if you do that, you nearly get your one single configuration file for free.
For example:
jshint: {
dist: {
options: {
curly: true,
eqeqeq: true,
},
src: ['path/to/**/*.js']
}
},
csslint: {
dist: {
options: {
import: 2
},
src: ['path/to/**/*.css']
}
},
bower: {
install: {
options: {
targetDir: './lib',
layout: 'byType',
install: true,
verbose: false,
cleanTargetDir: false,
cleanBowerDir: false,
bowerOptions: {}
}
}
}

Related

Grunt uglify. How to minify and replace original file with result?

We're using grunt for dev and prod. For dev we don't perform uglify but for prod we do. Unfortunately I can't change references to script from something like this "script.js" to "script.min.js".
I've tried grunt task like this for prod environment but it is not work:
// uglify
uglify: {
options: {
drop_console: true
},
componet: {
src: [componet.path + 'script.js'],
dest: componet.path + 'script.js'
},
}
What is the best workflow to change content "script.js" with uglified version?
Try with this:
uglify: {
options: {
},
main: {
files: [{
expand: true,
src: ['yourpath/**/*.js'],
dest: ''
}]
}
}
There are different possibilities to define the grunt task, here some examples:
uglify: {
options: {
drop_console: true
},
componet: {
files: [
// map one to one
{ 'path/to/minimized01.min.js': 'path/to/source01.js' },
{ 'path/to/minimized02.min.js': 'path/to/source02.js' },
// concat several sources into a minimized destination
{ 'path/to/minimized03and04.min.js': [ 'path/to/source03.js', 'path/to/source04.js' ]},
// map all files in a folder, one to one into a destination
{ expand: true,
cwd: 'path/to/a/source/folder',
src: [ '**/*.js', '!excludeThisFile.js' ],
dest: 'path/to/a/destination/folder',
ext: 'min.js' // if you want to change each extension to min.js
}
]
}
}
And then you can run it as grunt uglify:component... I always set separate tasks for development and production, for development I'd suggest using uglify, without dropping console, and use beautify option... Even better if you use source mapping, its very useful for debugging in browsers.

Importance of names 'development' and 'production' in grunt-contrib-less

The example from grunt-contrib-less:
less: {
development: {
options: {
paths: ["assets/css"]
},
files: {
"path/to/result.css": "path/to/source.less"
}
},
production: {
options: {
paths: ["assets/css"],
plugins: [
new require('less-plugin-autoprefix')({browsers: ["last 2 versions"]}),
new require('less-plugin-clean-css')(cleanCssOptions)
],
modifyVars: {
imgPath: '"http://mycdn.com/path/to/images"',
bgColor: 'red'
}
},
files: {
"path/to/result.css": "path/to/source.less"
}
}
}
It provides two entries in the dictionary for less: development and production.
I don't know what to call these entries, perhaps smth like "sub-tasks for less".
Does the naming of these matter?
Is it possible to only run one of these. I've tried $ grunt less development, but that does not work.
The names matter and it's something you configure. These are like more like arguments than sub-tasks. Reference: http://gruntjs.com/api/grunt.task
Try grunt less:development

Sass - Complex folder structure with a lot of css files

Hi everyone,
I have a lot of css files in my project with a very complex structure so I had to replicate the structure of the folders containing css files at the root of the project.
So every time I save a scss file, grunt has to check each 160+ lines of config I gave him.
Is there a way to optimize this this configuration? Maybe an option to tell contrib-sass to compile the scss file with the same structure he's in?
Here is a simplified example of my code :
...
sass: {
dist: {
options: {
style: 'expanded',
sourcemap: 'none',
trace: true,
},
files: {
'./css/laptop.css': './scss/css/laptop.scss',
....
... (160 more lines)
....
'./css/player.css': './scss/css/player.scss'
}
}
},
...
Thanks!
You can pass parameters to your Grunt task using grunt.option. Take a look.
You can pass params to grunt using this syntax:
$grunt [task] myparam=myvalue
Then, from any place in your gruntfile (or sub-files) you can do that:
var myoption = grunt.option("myparam") || defaultvalue;
With that, you can create a task for compile only one scss file passing the name in the param for example or even if the param doesn't exist compile all.
...
var myoption = grunt.option("myparam") || defaultvalue;
sass: {
dist: {
options: {
style: 'expanded',
sourcemap: 'none',
trace: true,
},
files: {
if ( myoption == defaultvalue ) {
'./css/laptop.css': './scss/css/laptop.scss',
....
... (160 more lines)
....
'./css/player.css': './scss/css/player.scss'
} else {
}
}
}
},
...
After some research I discovered grunt-newer which can be used this way:
css:{
files: [
'./scss/**'
],
tasks: ['newer:sass'],
livereload: {
options: { livereload: true },
files: ['./**'],
},
}
It's not what I was trying to do exactly but It optimised perfectly the grunt process.
Really nice plugin!!

Grunt concat no errors but doesn't works

Hi Grunt concat doesn't shows errors, but it doesn't concentrate my styles.css file. Here is a screenshot of it:
link: http://i.imgur.com/gHlbROe.png
And here is a screenshot of my css file, which still isn't being concatenated(also you can see my folder structure here below):
link: http://i.imgur.com/UlGWQv1.png
And here is my gruntfile.js (Maybe I should have a different separator in concat_css.):
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
compress: true,
yuicompress: true,
optimization: 2,
css: ['concat']
},
files: {
"css/styles.css": "css/styles.less" // destination file and source file
}
}
},
concat_css: {
options: {
// Task-specific options go here.
separator: '}'
},
all: {
src: ["css/styles.css"],
dest: "css/styles.css"
},
},
watch: {
styles: {
files: ['css/styles.less'], // which files to watch
tasks: ['less', 'concat_css'],
options: {
nospawn: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-concat-css');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less', 'watch', 'concat_css']);
};
I'm pretty sure the task is called concat, not concat_css. You're config will need to match that name (that is, you should not be using concat_css at all). Aside from that, why would you make the separator the closing brace (})? If you ever have more than one file that will almost certainly cause a syntax error in the concatenated CSS file. I would leave out that option unless you have a specific need for it.
concat: { // <-- change this to match the name of the task: "concat"
all: {
src: ["css/styles.css"],
dest: "css/styles.css"
},
},

How to configure sourceMaps for LESS using Grunt?

I'm using grunt 0.4.2 and grunt-contrib-less 0.9.0. I want my LESS to be compiled into CSS with support for source maps.
My LESS files are in public/less, and the main one is called main.less.
The compiling of public/less/main.less into public/css/main.css works, but source maps don't work.
What is wrong with my Grunt config below?
{
less: {
dev: {
options: {
compress: true,
yuicompress: true,
optimization: 2,
sourceMap: true,
sourceMapFilename: "public/css/main.css.source-map.json", //Write the source map to a separate file with the given filename.
sourceMapBasepath: "public/less", //Sets the base path for the Less file paths in the source map.
sourceMapRootpath: "/"//Adds this path onto the Less file paths in the source map.
},
files: {
"public/css/main.css": "public/less/main.less"
}
}
},
watch: {
styles: {
files: ["public/less/*"],
tasks: ['less'],
options: {
livereload: true,
nospaces: true
}
}
}
}
I don't want to have my CSS created in my /public/less folder; I want to put it into /public/css. Otherwise, I could use this other config, which works:
{
less: {
dev: {
options: {
compress: true,
yuicompress: true,
optimization: 2,
sourceMap: true,
sourceMapFilename: "public/less/main.css.map", //I DO NOT WANT THE CSS MAP HERE
sourceMapBasepath: "public/less", //Sets the base path for the Less file paths in the source map.
},
files: {
"public/less/main.css": "public/less/main.less"//I DO NOT WANT THE CSS HERE
}
}
},
watch: {
styles: {
files: ["public/less/*"],
tasks: ['less'],
options: {
livereload: true,
nospaces: true
}
}
}
}
I found the LESS site documentation to be more clear regarding params used by grunt-contrib-less.
LESS: Command Line Usage
http://lesscss.org/usage/#command-line-usage-installing-lessc
NPM: grunt-contrib-less
https://www.npmjs.org/package/grunt-contrib-less
File structure:
laravel/gruntfile.js
laravel/public/less/main.less
laravel/public/css/main.css
laravel/public/css/main.css.map
File 'main.css.map' note:
If you wish, you can rename to: main.css.source-map.json
I guess you have some server rule setup that doesn't server *.map files properly from the 'css' folder
Compression notes:
cleancss: true = will remove sourceMappingURL comment from main.css
yuicompress: true = will NOT remove sourceMappingURL comment from main.css
Gruntfile.js
less: {
dev: {
options: {
compress: true,
yuicompress: true,
optimization: 2,
sourceMap: true,
sourceMapFilename: 'public/css/main.css.map', // where file is generated and located
sourceMapURL: '/css/main.css.map', // the complete url and filename put in the compiled css file
sourceMapBasepath: 'public', // Sets sourcemap base path, defaults to current working directory.
sourceMapRootpath: '/', // adds this path onto the sourcemap filename and less file paths
},
files: {
'public/css/main.css': 'public/less/main.less',
}
}
},
watch: {
styles: {
files: ["public/less/*"],
tasks: ['less'],
options: {
livereload: true,
nospaces: true
}
}
},
laravel/public/css/main.css
.class{ compiled css here } /*# sourceMappingURL=/css/main.css.map */
laravel/public/css/main.css.map
{"version":3,"sources":["/less/main.less"], etc...
If you're still having trouble with it try setting the SourceMapURL to the full path, for example:
http://www.yourdomain.com/assets/css/styles.css.map
Obviously this is a bit of a pain as it's not relative, so when you move your site it will need to be changed. I had the same issue as you and this got it working for me.
Another point I discovered is that you cannot load the SourceMaps from the file system. It has to be from a web server. To get around the file system issue I believe you can inline the SourceMap.
This thread on GitHub has a lot of information.
https://github.com/less/less.js/issues/1050#issuecomment-25621390

Resources