Grunt remove unused CSS recursively - css

I have a project which has multiple directories in which css is stored (slightly different css for different languages)
Example Directory Structure:
/sass
- /latin
- /hindi
- /chinese
Inside each of those directories is an index.scss file.
I then have a mustache template which pulls in css from the correct directory based on the language set.
I have tried using purify css and unCSS they both work great with a single .css file but do not seem to work when you have multiple directories and files.
I would like each file in each directory to have the unused css removed and a new file created in each directory.
Now grunt supports this sort of recursive task using this format for a task:
files: [
{
expand: true, // Enable dynamic expansion.
cwd: 'lib/', // Src matches are relative to this path.
src: ['**/*.js'], // Actual pattern(s) to match.
dest: 'build/', // Destination path prefix.
ext: '.min.js', // Dest filepaths will have this extension.
extDot: 'first' // Extensions in filenames begin after the first dot
},
But it seems that the two unused css tasks I have tried do not support this.
Does anyone have any suggestions?
Thanks.

Related

Grunt Assemble is resolving relative paths in build files (want to keep relative paths)

This is an interesting question, I've already searched Google so my hopes of reaching someone with an answer are slim.
I'm building a Grunt project, everything is great with my project except for one little thing I just noticed regarding relative paths ( ../../ ) when using the Assemble site generator. I am using a layout file in my project, fyi.
I need to use relative paths to link to files that are two levels lower than the root level of my Grunt project. But when I run my build the output HTML is resolving the relative paths to root.
For example, my HTML code in the dev file...
Hotels
is resolved to the following in the build file...
Hotels
It completely ignores the "../../" when I need that relative path to stay. I eventually plan on dumping this build folder into another project and taking advantage of it's resources that reside two levels lower than this build.
Any help is appreciated. So the gist of my questions... I want to maintain "../../" relative paths in my output HTML files after I run the Assemble task.
Here is the assemble task I've created...
assemble: {
options: {
layoutDir: './templates/layouts',
data: './templates/app/json/**/*.{json,yml}',
flatten: true
},
main: {
options: {
layout: './templates/layouts/default.html',
partials: './templates/app/partials/**/*.html'
},
src: './templates/app/*.html',
dest: './_build/'
}
}

Grunt select all files of a certain filetype

How do I select all files of a certain file type? Like so;
src: '**/*.(js|rb|html|...)'
Is there a way of doing this, or do I have to make an array ['**/*.js', '**/*.rb', '**/*.html', ...]?
You can supply a extglob:
**/*.+(js|rb|html)
This is mentioned in the documentation of minimatch (used by Grunt).

Using grunt-manifest to generate appcache manifests with relevant paths based on the root

I have a number of backbone apps all hosted on the same site. I am attempting to use grunt-manifest to generate appcache manifests for them. It generates the manifest file, but the links are wrong. I want each app to have a separate manifest file.
For example say I have an app called 'hello', it would be accessed via this url:
mydomain.com/apps/hello
so the main js and css files would be at:
mydomain.com/apps/hello/app.js
mydomain.com/apps/hello/style.css
etc.
There are also some shared components, found at say:
mydomain.com/shared/shared.js
(I dynamically load these with require.js so don't want to concat into the main app.js)
I specify the manifest in grunt like this:
manifest: {
generate: {
options: {
basePath: '<%= gconf.dist_dir %>/',
timestamp: true,
network: ['*'],
},
files: [
{
cwd: 'public/',
src: [
'apps/hello/*',
'shared/*',
// etc
],
dest: '<%= gconf.dist_dir %>/public/apps/hello/manifest.appcache' },
]
}
},
I believe the issue is I am trying to get grunt-manifest to generate an appcache manifest for a portion of a site not the root site. The manifest i get looks like this:
CACHE
apps/hello/app.js
apps/hello/style.css
shared/shared.js
When I load the page - the manifest retrieval fails because it is trying to access links like this:
mydomain.com/apps/hello/apps/hello/app.js
If I manually edit the manifest files and add a '/' in front of everything so it looks like this:
CACHE
/apps/hello/app.js
/apps/hello/style.css
/shared/shared.js
...then it all works.
The issue obviously being the manifest creating relative links, when I want them from the root.
I cannot for the life of me figure out how to get grunt-manifest to create these for me with a '/' in front.
I've tried experimenting with 'basePath' on its own, 'cwd' on its own, a combination of the two. If I leave the '/' off the end of say basePath or cwd and try adding it in the 'src' it doesn't work and I get an empty CACHE section.
I'm sure there must be an easy way of doing this with the grunt globing patterns, but I just can't work it out.
Any ideas?
(also - not enough rep to create a new tag, but a 'grunt-manifest' tag might be useful for others in the future)
I just ecnountered the same issue.
I've forked the module here: https://github.com/killfish/grunt-manifest
If you pass in the option absolutePath : true, it will prepend a '/'
options: {
**absolutePath: true,**
network: ['http://*', 'https://*'],
preferOnline: true,
verbose: true,
timestamp: true
},

Grunt cssmin rebasing a relative URI?

I'm currently setting up grunt-usemin for our project but I'm running in a small issue with the cssmin task.
Our project depends on a few external libraries, some which bring a long some extra assets (like images or fonts). The problem is these libraries do not have the same folder structure.
This is an example of the different folder structures
lib
|--lib1
| |--style1.css
| +--image1.png
+--lib2
|--styles
| +--style2.css
+--images
+--image2.png
In the index.html all the stylesheets are referenced and put inside a build block. As such, when the usemin task executes, the stylesheets of the libraries are concatenated in one minified file and put inside the output folder. The corresponding assets (images) are copied over to this output folder as well and flatened in the img folder. The output folder structure looks like
out
|--allstyles.min.css
|--image1.png
+--image2.png
As you can guess, the concatenated stylesheets has (in this example) two different relative URIs:
image1.png
..\images\image2.png
This is causing an issue where some of the images cannot be found. I need a solution to rebase all relative URIs to the out folder. I tried using the target and root options of the cssmin task but to no avail. Could someone point me to a correct configuration of this task or to another Grunt task that could achieve what I'm looking for?
Thanks in advance!
I have a grunt file in C:\web\project and CSS files in C:\web\project\www\css. The following snippet is from my grunt file and it rebases URLs correctly for me.
var cssFiles = [
'www/css/layout/Header.css',
'www/css/layout/Footer.css',
'www/css/vendor/chosen/chosen.css'
// ...
];
cssmin: {
concat: {
options: {
keepBreaks: true, // whether to keep line breaks (default is false)
debug: true, // set to true to get minification statistics under 'stats' property (see test/custom-test.js for examples)
noAdvanced: true, // set to true to disable advanced optimizations - selector & property merging, reduction, etc.
//relativeTo: 'http://online-domain-tools.com/'
noRebase: false, // whether to skip URLs rebasing
root: 'www'
},
nonull: true,
src: cssFiles,
dest: 'www/temp/application.css'
},
minify: {
options: {},
nonull: true,
src: ['www/temp/application.css'],
dest: 'www/temp/application.min.css'
}
},
// ...
grunt.registerTask('default', ['cssmin:concat', 'cssmin:minify']);
Can you post your gruntfile to compare it?
Related reading: https://stackoverflow.com/a/21415649/99256
look in the cssmin documentation/options:
rebase: set to false to skip URL rebasing
That solves the issue.

Watching multiple "file arrays" in gruntjs

So in my config file, I'm statically defining the css files to watch, along with some html partials. (eventually I will minimatch with exclusions .. I'm just going with first pass right now)
Originally I was storing these in the grunt config object, but struggled to get the output I wanted, so I moved them out of the initConfig method and into the wrapping function:
Original pass:
grunt.initConfig({
cssFiles: [ ... list of files ... ],
htmlFiles: [ ... list of files ...],
watch: {
reload: {
files: ['<%= cssFiles.concat(htmlFiles).join(",") %>']
}
}
});
I tried several variations of this (with and without join), as an example.
Current "Working" version:
module.exports = function(grunt) {
var cssFiles = ['someFile.css',...'lastFile.css'],
htmlFiles = [ ... ];
grunt.initConfig({
watch: {
reload: {
files: cssFiles.concat(cshtmlFiles)
}
}
});
};
I feel like I should be able to do this without having to move my array's out of the grunt config (although I don't know WHY I feel they should stay there ... I guess I just haven't seen many Gruntfile's with code outside of initconfig)
I'm using a system that stores all the paths I need in a single config object, like so:
grunt.initConfig({
pathTo: {
distcss : './dist/css/master.css',
srcstyles : './lib/styles/**/*.scss',
vendor : './lib/vendor'
},
// tasks...
});
Then, I load those in via underscore templates like in your first example. If your project is structured in a good way then usually just having one minimatch pattern is enough. All my CSS ends up in lib/styles, and any misc. third party stuff is usually in lib/vendor as that is managed through Bower.
With the right directory structure and pattern you shouldn't need a large array of paths. A sample JavaScript project could look like this:
lib
└── src
├── app
└── tests
Then your minimatch pattern to lint your application and test code would just be lib/src/**/*.js, for example.
But what works for you works for you; if you've written a system that you're happy with, regardless of whether you've seen it elsewhere or not, there's no reason to change it. :-)

Resources