I'm using usemin and I generally like it, but I really dislike the fact that usemin overwrites my original index.html file. I have a pretty typical setup in my Gruntfile:
useminPrepare: {
html: '<%= yeoman.app %>/index.html',
options: {
root: '<%= yeoman.root %>',
staging: '<%= yeoman.tmp %>',
dest: '<%= yeoman.dist %>',
flow: {
html: {
steps: {
js: ['concat', 'uglifyjs'],
css: ['cssmin']
},
post: {}
}
}
}
},
Whenever I build using grunt everything in the end gets dumped into a dist directory. Most other tasks that need to do 'temporary' modifications copy and modify files in a .tmp directory.
usemin mucks with the actual index.html file though. I particularly don't like this because it makes Github think the file has changed every time I check in new code.
Is there a way to tell usemin to use the .tmp directory like most other grunt plugins?
I do specify my temp directory with:
staging: '<%= yeoman.tmp %>'
but that doesn't seem to prevent the index.html file from being overwritten.
Thanks.
UPDATE (per the comment below)
Here is the usemin task itself:
// Performs rewrites based on filerev and the useminPrepare configuration
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
options: {
assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/images']
}
},
and here is the grunt task that uses both useminPrepare and usemin:
grunt.registerTask('build', [
'clean:dist',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin',
'bridge:dist'
]);
just do not perform filerev task. This is the task that modify the original html files.
Related
I am new to Grunt and all the tasks so bear with me on this one. I'm developing an AngularJS application, that I initially created through Yeoman. Since theres lot's of views I thought it would be a good idea to include all the views in the templatecache. So I installed html2js and configured it according to their GitHub read. It's working almost perfectly, except from one thing. My templates contain some references to local images. When running grunt build all those images's names are getting changed by revfile. Looking at the dist/views folder with all the templates, I can see that the paths is correct (the path has been replaced with the new one). However, those changes to the paths doesn't make it into the js-file that html2js generates.
How can I make Grunt replace the paths correctly in the generated html2js js-file as well? Here is the grunt initConfig parts that I think is relevant
filerev: {
dist: {
src: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/styles/fonts/*'
]
}
},
useminPrepare: {
html: '<%= yeoman.app %>/index.html',
options: {
dest: '<%= yeoman.dist %>',
flow: {
html: {
steps: {
js: ['concat', 'uglifyjs'],
css: ['cssmin']
},
post: {}
}
}
}
},
// Performs rewrites based on filerev and the useminPrepare configuration
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
options: {
assetsDirs: ['<%= yeoman.dist %>', '<%= yeoman.dist %>/images']
}
},
****************************
grunt.registerTask('build', [
'clean:dist',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'html2js:main',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);
May I suggest that you use grunt-angular-templates instead? It is designed precisely to insert views into the $templateCache.
I have never had any problems with relative paths.
You can even pair it with https://github.com/mgcrea/grunt-nginclude to inline "partials".
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']
]
}
}
}
I'm a bit confused of why the yeoman angular generator has the concat tasks inside the useminPrepare task since the concat and uglify are run later in the build task.
// Reads HTML for usemin blocks to enable smart builds that automatically
// concat, minify and revision files. Creates configurations in memory so
// additional tasks can operate on them
useminPrepare: {
html: '<%= yeoman.app %>/index.html',
options: {
dest: '<%= yeoman.dist %>',
flow: {
html: {
steps: {
js: ['concat', 'uglifyjs'],
css: ['cssmin']
},
post: {}
}
}
}
},
grunt.registerTask('build', [
'clean:dist',
'bowerInstall',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngmin',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'rev',
'usemin',
'htmlmin'
]);
can someone enlighten me?
The useminPrepare task does not actually do any minification, but instead it parses HTML and sets the appopriate configuration for other tasks. For example, if you have this in your HTML:
<!-- build:js js/app.js -->
<script src="js/app.js"></script>
<script src="js/controllers/thing-controller.js"></script>
<script src="js/models/thing-model.js"></script>
<script src="js/views/thing-view.js"></script>
<!-- endbuild -->
The useminPrepare task will set the following configuration:
{
concat: {
'.tmp/concat/js/app.js': [
'app/js/app.js',
'app/js/controllers/thing-controller.js',
'app/js/models/thing-model.js',
'app/js/views/thing-view.js'
]
},
uglifyjs: {
'dist/js/app.js': ['.tmp/concat/js/app.js']
}
}
And the block in the HTML will then be replaced with with:
<script src="dist/js/app.js"></script>
For more information, see https://github.com/yeoman/grunt-usemin.
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!
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