grunt-requirejs - how to optimize CSS? - css

I'm using Yeoman, and are trying to setup requirejs to optimise my CSS files.
I have this in my Gruntfile.js:
requirejs: {
css: {
options: {
optimizeCss: 'standard',
cssIn: 'app/styles/main.css',
out: 'app/styles/main.min.css'
}
}
}
When I run the build command I get an error:
grunt build
Running "requirejs:css" (requirejs) task
>> Error: TypeError: new path must be a string
>> at Object.fs.renameSync (fs.js:439:18)
Warning: Task "requirejs:css" failed
I'm not really sure what's happening there, or how to debug that.
Does anyone know what the problem could be?

Never mind, I worked it out.
The silly useminPrepare task that ships with Yeoman stuffs around with the grunt-requirejs configuration. Kind of annoying, esp. since the point of me wanting to use grunt-requirejs was because I didn't like how usemin worked to begin with.
UPDATE:
This is my configuration that works:
//index.html:
<!-- build:js scripts/scripts.js -->
<script data-main="scripts/main" src="components/requirejs/require.js"></script>
<!-- endbuild -->
//Gruntfile.js:
requirejs: {
js: {
options: {
baseUrl: '<%= yeoman.tmp %>/scripts',
out: '<%= yeoman.dist %>/scripts/scripts.js',
name: 'main',
optimize: 'none',
mainConfigFile: '<%= yeoman.app %>/scripts/main.js',
useStrict: true,
wrap: true
}
},
css: {
options: {
optimizeCss: 'standard',
cssIn: '<%= yeoman.app %>/styles/main.css',
out: '<%= yeoman.dist %>/styles/main.css'
}
}
},
useminPrepare: {
html: '<%= yeoman.app %>/index.html',
options: {
dest: '<%= yeoman.dist %>'
}
},
usemin: {
html: '<%= yeoman.dist %>/index.html',
options: {
dirs: ['<%= yeoman.dist %>']
}
}
grunt.registerTask('build', [
'requirejs:js',
'requirejs:css',
'useminPrepare', //must be after requirejs:css as it breaks its config params
'usemin'
]);
NOTE: There is still an underlying bug in grunt-usemin where it (incorrectly) tries to alter the requirejs config for the requirejs:css configuration. I've reported that here

Related

Stop grunt from changing names on fonts

So I'm in the situation where I have added a font to my Yeoman project. There is however a small problem. Whenever I run grunt build the file name of my font is changed, but it doesn't change in my CSS causing it to not work.
How can I fix this. I know that I have to look inside my Gruntfile.js but I have no idea where to look.
I already tried this:
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
html: ['<%= yeoman.dist %>/public/{,*/}*.html'],
css: ['<%= yeoman.dist %>/public/{,*/}*.css'],
js: ['<%= yeoman.dist %>/public/{,*/}*.js'],
options: {
assetsDirs: [
'<%= yeoman.dist %>/public',
'<%= yeoman.dist %>/public/assets/images',
'<%= yeoman.dist %>/public/assets/fonts'
],
// This is so we update image references in our ng-templates
patterns: {
js: [
[/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the JS to reference our revved images']
],
css: [
[/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the CSS to reference our revved images']
]
}
}
},
Because I figured that if I could have it change the name in my CSS aswell it might work. But this doesn't really fix anything :-(
UPDATE
As requested here is the changes in the file name
Before:
ITCEDSCR.TTF
After
20118b60.ITCEDSCR.TTF
According to https://github.com/yeoman/generator-webapp/issues/459 ->
{
usemin: {
options: {
assetsDirs: [
'<%%= config.dist %>',
'<%%= config.dist %>/images',
'<%%= config.dist %>/styles'
]
},
html: ['<%%= config.dist %>/{,*/}*.html'],
css: ['<%%= config.dist %>/styles/{,*/}*.css']
}
}
Getting rid of the fonts should help I guess ?
ACTUAL SOLUTION !
Thanks to Fer To's link I found a solution. It is kinda what he suggested, just had to change the code somewhere else as well.
This was my solution:
// Renames files for browser caching purposes
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/public/{,*/}*.js',
'<%= yeoman.dist %>/public/{,*/}*.css',
//'<%= yeoman.dist %>/public/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
//'<%= yeoman.dist %>/public/assets/fonts/*'
]
}
}
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
html: ['<%= yeoman.dist %>/public/{,*/}*.html'],
css: ['<%= yeoman.dist %>/public/{,*/}*.css'],
js: ['<%= yeoman.dist %>/public/{,*/}*.js'],
options: {
assetsDirs: [
'<%= yeoman.dist %>/public',
'<%= yeoman.dist %>/public/assets/images'
],
// This is so we update image references in our ng-templates
patterns: {
js: [
[/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the JS to reference our revved images']
]
}
}
},

LESS/Grunt is not writing the sourcemap reference to the end of the compiled CSS

I am using grunt-contrib-less to compile my .less files in to a single CSS stylesheet. Everything is working, except the source map, which I cannot get to work under any circumstances!
Here is my Gruntfile:
'use strict';
module.exports = function(grunt) {
// Force use of Unix newlines
grunt.util.linefeed = '\n';
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
project: {
// Add entries to this array to create variables for use by Grunt
app: ['app'],
server: 'http://mysite.app',
// Components
bower: ['<%= project.app %>/bower_components'],
bootstrap: ['<%= project.bower %>/bootstrap'],
// Custom Assets
assets: ['<%= project.app %>/assets'],
css: ['<%= project.assets %>/css'],
less: ['<%= project.assets %>/less'],
js: ['<%= project.assets %>/js']
},
less: {
production: {
options: {
ieCompat: true,
sourceMap: true,
sourceMapFilename: '<%= project.css %>/style.css.map',
sourceMapURL: '<%= project.server %>/assets/css/style.css.map',
sourceMapBasepath: 'app',
sourceMapRootpath: '<%= project.server %>'
},
files: {
'<%= project.css %>/style.css': '<%= project.less %>/style.less'
}
}
},
autoprefixer: {
dist: {
files: {
'<%= project.assets %>/css/style.css': '<%= project.assets %>/css/style.css'
}
}
},
concat: {
options: {
separator: ';\n',
sourceMap: true
},
plugins_head: {
// Add further Javascript plugins to this array and they will be
// concatenated in to the plugins-built-head.js file
src: [
'<%= project.bower %>/modernizr/modernizr.js'
],
dest: '<%= project.js %>/built/plugins-built-head.js'
},
plugins: {
// Add further Javascript plugins to this array and they will be
// concatenated in to the plugins-built.js file
src: [
'<%= project.bootstrap %>/js/dropdown.js'
],
dest: '<%= project.js %>/built/plugins-built.js'
},
custom: {
// Add further custom-written javascript files to this array and
// they will be concatenated in to the scripts-built.js file
src: [
'<%= project.js %>/scripts.js'
],
dest: '<%= project.js %>/built/scripts-built.js'
}
},
watch: {
css: {
files: [
'<%= project.bootstrap %>/less/*.less',
'<%= project.less %>/*.less'
],
tasks: [
'less',
'autoprefixer'
],
options: {
livereload: true
}
},
js: {
files: [
'<%= project.js %>/scripts.js'
],
tasks: ['concat']
},
html: {
files: [
'<%= project.app %>/*.html'
],
options: {
livereload: true
}
}
}
});
grunt.loadNpmTasks('grunt-run-grunt');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.registerTask('default', [
'watch'
]);
};
What's happening is that Grunt is writing a proper and correct style.css.map file, but it's not writing the following line to the end of the compiled style.css file:
/*# sourceMappingURL=http://mysite.app/assets/css/style.css.map */
That's the one line that's missing. Everything else is getting compiled and written correctly. If I manually add that line to the end of the compiled CSS, Chrome picks up on the source map properly, but it's not being written in.
Additionally, trying options like sourceMapFileInline seems to make no difference - the file is never written inline.
Any ideas?
Hopefully you have found a solution by now. This is for other people with the same issue:
Make sure the soourcemap will be placed in the same folder as css.
Set sourceMapUrl to only the name of the map file.
This will add the following line to your .css file: /*# sourceMappingURL=default.css.map */
Here are the sourcemap settings in my grunt file:
sourceMap: true,
sourceMapFilename: "src/assets/css/default.css.map",
sourceMapURL: "default.css.map"

Grunt (Yeoman, Grunt-usemin, Grunt-rev): The "rev'ed" font path isn't reflected in my .CSS?

Background
I am using Yeoman webapp to scaffold my frontend.
Within the gruntfile, they are using grunt-rev and grunt-usemin
Grunt-rev will "rev'ed" my assets and grunt-usemin will update the asset path.
Problem
I have a webfont that I am using. I placed the fonts folder in my styles directory as mentioned in the gruntfile.js ( 'styles/fonts/{,/}.*' ) Grunt serve is showing my fonts properly but after I built the file, it no longer works because the font filename has been prefixed with some weird gibberish characters. eg: 63b122ab.fontname.ttf instead of fontname.ttf
This is for cache busting.
But my .css file isn't updating the path to pick it up.
In my usemin block within gruntfile.js
What should I do? I have this currently but it is not working.
usemin: {
options: {
assetsDirs: ['<%= config.dist %>', '<%= config.dist %>/images', '<%= config.dist %>/styles/fonts']
},
html: ['<%= config.dist %>/{,/}.html'],
css: ['<%= config.dist %>/styles/{,/}.css']
},
It is picking up everything else but not the fonts. I manually created the fonts folder. So I am guessing the gruntfile.js has to be updated to reflect the change.
I had the same problem with grunt in css file. I changed the usemin config in Gruntfile.js like this:
usemin: {
html: ['<%= yeoman.dist %>/<%= yeoman.client %>/{,!(bower_components)/**/}*.html'],
css: ['<%= yeoman.dist %>/<%= yeoman.client %>/!(bower_components){,*/}*.css'],
js: ['<%= yeoman.dist %>/<%= yeoman.client %>/!(bower_components){,*/}*.js'],
options: {
assetsDirs: [
'<%= yeoman.dist %>/<%= yeoman.client %>',
'<%= yeoman.dist %>/<%= yeoman.client %>/assets/images'
],
// This is so we update image and font references in our ng-templates
patterns: {
js: [
[/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the JS to reference our revved images']
],
css: [
[/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the CSS to reference our revved images'],
[/(assets\/fonts\/.*?\.(?:woff|ttf|svg|eot))/gm, 'Update the CSS to reference our revved fonts']
]
}
}
}

Template var in gruntfile doesn't always work

In my gruntfile I noticed that I can't always get a template variable to work. Below is a very simple small grunt file to show the issue. The copy task will understand <%= yeoman.app %>, but the less task does not.
I suppose this has something to do with the files syntax, but I dont understand why. Can someone elaborate? And.. how can I get less to work?
'use strict';
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
var yeomanConfig = {
app: 'app',
dist: 'dist'
};
grunt.initConfig({
yeoman: yeomanConfig,
copy: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: '404.html'
}]
}
},
less: {
dist: {
files: {
'<%= yeoman.dist %>/styles/main.css': ['<%= yeoman.app %>/styles/main.less']
}
}
}
});
};
grunt copy: works
grunt less: Warning: An error occurred while processing a template (_ is not defined). Use --force to continue.
note, I'm using grunt 0.4.2 and node 0.10.13

Where to add css files using the Yeoman workflow

I have an angular setup using Yeoman. Under my main.html (a view loaded onto index.html), I have added a referenced a css file in my styles folder.
I surrounded it with the build comments so that it can be picked up by grunt while minimizing:
<!-- build:css({.tmp,app}) styles/calendar.css -->
<link rel="stylesheet" href="styles/fullcalendar.css" />
<!-- endbuild -->
However, when I build using grunt (with the basic yeoman grunt configuration), it does not seem to create the calendar.css file. I suspect that this may be because the main.html file is within views/main.html.
From my grunt file:
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
options: {
dirs: ['<%= yeoman.dist %>']
}
},
...
cssmin: {
// By default, your `index.html` <!-- Usemin Block --> will take care of
// minification. This option is pre-configured if you do not wish to use
// Usemin blocks.
// dist: {
// files: {
// '<%= yeoman.dist %>/styles/main.css': [
// '.tmp/styles/{,*/}*.css',
// '<%= yeoman.app %>/styles/{,*/}*.css'
// ]
// }
// }
},
It does not look to within the views directory. I suspect that I am using the workflow incorrectly.
How does one include a css file that is specific to a view?
Also, what does the comments in cssmin block mean?
Thanks!
I've got the answer!
A bit more configuration is required in Gruntfile.js, since you're using a custom workflow. (Ignore if you've already done these).
First, the copy task needs to be updated to copy your app/views directory to dist/views. That's an easy enough fix:
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'images/{,*/}*.{webp,gif}',
'styles/fonts/*',
'views/*'
]
}]
},
// ...
}
Cool cool. Now, useminPrepare, which runs before your stuff is copied over, needs to know about the views directory, as well.
useminPrepare: {
options: {
dest: '<%= yeoman.dist %>'
},
html: [
'<%= yeoman.app %>/index.html',
'<%= yeoman.app %>/views/*.html'
]
},
Woot woot! That's it!
Let me know if you get stuck anywhere!

Resources