css/js file path update in the html file using grunt - gruntjs

I have a folder structure, when I create the build folder using grunt, a hash need to be prefixed with .css file and that name need to be updated in the link tag in index.php.
sitename/css/main.css
sitename/index.php
After executing grunt command build folder need to be created with following structure
build/sitename/css/2ed6bccd.main.css
build/sitename/index.php
In the index.php
<link rel="stylesheet" href="main.css">
need to be replaced with
<link rel="stylesheet" href="2ed6bccd.main.css">
How can I achieve this?

You can use either grunt-rev or grunt-filerev tasks together with grunt-usemin for cache busting of static files in your index.php
example:
grunt.initConfig({
config: {
app: 'sitename',
dist: 'build/sitename'
},
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= config.dist %>/*',
'!<%= config.dist %>/.git*'
]
}]
}
},
rev: {
dist: {
files: {
src: [
'<%= config.dist %>/scripts/{,*/}*.js',
'<%= config.dist %>/styles/{,*/}*.css'
]
}
}
},
useminPrepare: {
html: '<%= config.app %>/index.php',
options: {
dest: '<%= config.dist %>'
}
},
usemin: {
html: ['<%= config.dist %>/{,*/}*.php'],
css: ['<%= config.dist %>/styles/{,*/}*.css'],
js: '<%= config.dist %>/scripts/*.js',
options: {
dirs: [
'<%= config.dist %>',
'<%= config.dist %>/styles'
]
}
},
htmlmin: {
dist: {
options: {
},
files: [{
expand: true,
cwd: '<%= config.dist %>',
src: ['*.html', 'views/*.html'],
dest: '<%= config.dist %>'
}]
}
},
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= config.app %>',
dest: '<%= config.dist %>',
src: [
'{,*/}*.php',
'*.{ico,png,txt}',
'.htaccess',
'bower_components/**/*',
'images/{,*/}*.{gif,webp}',
'fonts/*',
'data/*'
]
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= config.dist %>/images',
src: [
'generated/*'
]
}]
},
styles: {
expand: true,
cwd: '<%= config.app %>/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
}});
Your grunt build task:
grunt.registerTask('build', [
'clean:dist',
'useminPrepare',
'concat:generated',
'cssmin:generated',
//'uglify:generated',
'copy:dist',
'rev',
'usemin'
]);
And then in your index.php, put your css ref in the following block
<!-- build:css styles/main.css -->
<link rel="stylesheet" href="styles/main.css">
<!-- endbuild -->
This will rename sitename/css/main.css with an 8 character long hash prefix. For example sitename/css/9becff3a.main.css

Related

Grunt Build: CSS not looking in right image directory

I have an angular application generated via yeoman.
When I run grunt build, main.css is looking for files in the /assets/images directory, which is my project structure. The file locations are not getting changed in the css.
My dist directory project structure:
dist/
bower_components/
images/
scripts
styles/
index.html
The Problem
main.css is looking for /assets/images instead of /images. I'm not sure which plugin is causing this.
Specifically, I'm using background image.
.landing-container {
background-image:
linear-gradient(to bottom, rgba(0,0,0,1) 0%,rgba(0,0,0,0.25) 52%,rgba(0,0,0,1) 100%),
url('/assets/images/bg_landing.jpg');
}
Here is my package.json:
"devDependencies": {
"grunt": "^0.4.5",
"grunt-autoprefixer": "^2.0.0",
"grunt-concurrent": "^1.0.0",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-compass": "^1.0.0",
"grunt-contrib-concat": "^0.5.0",
"grunt-contrib-connect": "^0.9.0",
"grunt-contrib-copy": "^0.7.0",
"grunt-contrib-cssmin": "^0.12.0",
"grunt-contrib-htmlmin": "^0.4.0",
"grunt-contrib-imagemin": "^1.0.0",
"grunt-contrib-jshint": "^0.11.0",
"grunt-contrib-uglify": "^0.7.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-filerev": "^2.1.2",
"grunt-google-cdn": "^0.4.3",
"grunt-karma": "*",
"grunt-newer": "^1.1.0",
"grunt-ng-annotate": "^0.9.2",
"grunt-svgmin": "^2.0.0",
"grunt-usemin": "^3.0.0",
"grunt-wiredep": "^2.0.0",
"jshint-stylish": "^1.0.0",
"karma-jasmine": "*",
"karma-phantomjs-launcher": "*",
"load-grunt-tasks": "^3.1.0",
"time-grunt": "^1.0.0"
}
Here are my grunt file tasks:
// Empties folders to start fresh
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= yeoman.dist %>/{,*/}*',
'!<%= yeoman.dist %>/.git{,*/}*'
]
}]
},
server: '.tmp'
},
// Add vendor prefixed styles
autoprefixer: {
options: {
browsers: ['last 1 version']
},
server: {
options: {
map: true,
},
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
// Automatically inject Bower components into the app
wiredep: {
app: {
src: ['<%= yeoman.app %>/index.html'],
ignorePath: /\.\.\//
},
test: {
devDependencies: true,
src: '<%= karma.unit.configFile %>',
ignorePath: /\.\.\//,
fileTypes:{
js: {
block: /(([\s\t]*)\/{2}\s*?bower:\s*?(\S*))(\n|\r|.)*?(\/{2}\s*endbower)/gi,
detect: {
js: /'(.*\.js)'/gi
},
replace: {
js: '\'{{filePath}}\','
}
}
}
},
sass: {
src: ['<%= yeoman.app %>/assets/styles/{,*/}*.{scss,sass}'],
ignorePath: /(\.\.\/){1,2}bower_components\//
}
},
// Compiles Sass to CSS and generates necessary files if requested
compass: {
options: {
sassDir: '<%= yeoman.app %>/assets/styles',
cssDir: '.tmp/styles',
generatedImagesDir: '.tmp/images/generated',
imagesDir: '<%= yeoman.app %>/assets/images',
javascriptsDir: '<%= yeoman.app %>/scripts', // ????
fontsDir: '<%= yeoman.app %>/styles/fonts',
importPath: './bower_components',
httpImagesPath: '/images',
httpGeneratedImagesPath: '/images/generated',
httpFontsPath: '/styles/fonts',
relativeAssets: false,
assetCacheBuster: false,
raw: 'Sass::Script::Number.precision = 10\n'
},
dist: {
options: {
generatedImagesDir: '<%= yeoman.dist %>/images/generated'
}
},
server: {
options: {
sourcemap: true
}
}
},
// Renames files for browser caching purposes
filerev: {
dist: {
src: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
//'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/styles/fonts/*'
]
}
},
// 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: {}
}
}
}
},
// 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 %>/styles',
'<%= yeoman.dist %>/scripts',
'<%= yeoman.dist %>/images'
]
}
},
// The following *-min tasks will produce minified files in the dist folder
// By default, your `index.html`'s <!-- Usemin block --> will take care of
// minification. These next options are pre-configured if you do not wish
// to use the Usemin blocks.
// cssmin: {
// dist: {
// files: {
// '<%= yeoman.dist %>/styles/main.css': [
// '.tmp/styles/{,*/}*.css'
// ]
// }
// }
// },
uglify: {
dist: {
files: {
'<%= yeoman.dist %>/scripts/scripts.js': [
'<%= yeoman.dist %>/scripts/scripts.js'
]
}
}
},
// concat: {
// dist: {}
// },
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/assets/images',
src: '{,*/}*.{png,jpg,jpeg,gif}',
dest: '<%= yeoman.dist %>/images'
}]
}
},
svgmin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/assets/images',
src: '{,*/}*.svg',
dest: '<%= yeoman.dist %>/images'
}]
}
},
htmlmin: {
dist: {
options: {
collapseWhitespace: true,
conservativeCollapse: true,
collapseBooleanAttributes: true,
removeCommentsFromCDATA: true,
removeOptionalTags: true
},
files: [{
expand: true,
cwd: '<%= yeoman.dist %>',
src: ['*.html', 'scripts/**/*.html'],
dest: '<%= yeoman.dist %>'
}]
}
},
// ng-annotate tries to make the code safe for minification automatically
// by using the Angular long form for dependency injection.
ngAnnotate: {
dist: {
files: [{
expand: true,
cwd: '.tmp/concat/scripts',
src: '*.js',
dest: '.tmp/concat/scripts'
}]
}
},
// Replace Google CDN references
cdnify: {
dist: {
html: ['<%= yeoman.dist %>/*.html']
}
},
// Copies remaining files to places other tasks can use
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'*.html',
'scripts/**/*.html',
'assets/images/{,*/}*.{webp}',
'assets/styles/fonts/{,*/}*.*'
]
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= yeoman.dist %>/images',
src: ['generated/*']
}, {
expand: true,
cwd: '.',
src: 'bower_components/bootstrap-sass-official/assets/fonts/bootstrap/*',
dest: '<%= yeoman.dist %>'
}]
},
styles: {
expand: true,
cwd: '<%= yeoman.app %>/assets/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
},
// Run some tasks in parallel to speed up the build process
concurrent: {
server: [
'compass:server'
],
test: [
'compass'
],
dist: [
'compass:dist', // Good - I think
'imagemin', // Good
'svgmin' // Good
]
},
// Test settings
karma: {
unit: {
configFile: 'test/karma.conf.js',
singleRun: true
}
}
You can try to change compass option
httpImagesPath: '/images',
to
httpImagesPath: '../images',
imagesDir probably make the issue:
// Compiles Sass to CSS and generates necessary files if requested
compass: {
options: {
sassDir: '<%= yeoman.app %>/assets/styles',
cssDir: '.tmp/styles',
generatedImagesDir: '.tmp/images/generated',
imagesDir: '<%= yeoman.app %>/assets/images',
be aware that when you make grunt watch it uses .tmp directory
probably grunt build makes the dist catalog.
bdw. I use gulp and libsass which is much faster.
you need to give the pattern for changing the references.
options: {
assetsDirs: [
'<%= yeoman.dist %>',
'<%= yeoman.dist %>/images',
'<%= yeoman.dist %>/styles'
],
patterns: {
js: [[/(images\/[^''""]*\.(png|jpg|jpeg|gif|webp|svg))/g, 'Replacing references to images']]
}
}

Shopify livereload grunt

Has anyone got Shopify LiveReload to work for their workflow development to work with grunt? Please bare in mind, when viewing a live preview of the development, it's not stored locally, but instead through shopify's custom url's.
If anyone knows how to get livereload to work on shopify, I would be more than thankful.
Thanks in advance.
My Gruntfile:
'use strict';
// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to match all subfolders:
// 'test/spec/**/*.js'
module.exports = function (grunt) {
// load all grunt tasks
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
// configurable paths
var yeomanConfig = {
app: '.',
dist: 'fahey-rodriguez4877-7509645'
};
grunt.initConfig({
yeoman: yeomanConfig,
watch: {
compass: {
files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
tasks: ['compass:live'],
options: {
livereload: true
}
},
css: {
files: ['.tmp/styles/*.css'],
tasks: ['cssmin'],
options: {
livereload: true
}
},
js: {
files: ['<%= yeoman.app %>/scripts/*.js'],
tasks: ['concat:live'],
options: {
livereload: true
}
},
update: {
files: ['<%= yeoman.app %>/{layout,templates,snippets}/*.liquid'],
tasks: ['sync'],
options: {
livereload: true
}
},
config: {
files: ['<%= yeoman.app %>/config/*.{html,json}'],
tasks: ['copy']
},
},
clean: {
dist: [
'.tmp',
'<%= yeoman.dist %>/*'
]
},
jshint: {
options: {
jshintrc: '.jshintrc'
},
all: [
'Gruntfile.js',
'<%= yeoman.app %>/scripts/{,*/}*.js'
]
},
compass: {
options: {
sassDir: '<%= yeoman.app %>/styles',
cssDir: '.tmp/styles',
imagesDir: '<%= yeoman.app %>/assets',
javascriptsDir: '<%= yeoman.app %>/scripts',
fontsDir: '<%= yeoman.app %>/assets',
importPath: 'components',
relativeAssets: true
},
dist: {},
live: {
options: {
debugInfo: true,
}
}
},
uglify: {
dist: {
files: {
'<%= yeoman.dist %>/assets/custom.modernizr.js': [
'<%= yeoman.app %>/components/foundation/js/vendor/custom.modernizr.js'
],
'<%= yeoman.dist %>/assets/main.js': [
'<%= yeoman.app %>/components/foundation/js/vendor/jquery.js',
'<%= yeoman.app %>/components/foundation/js/foundation/foundation.js',
'<%= yeoman.app %>/components/foundation/js/foundation/foundation.*.js',
'<%= yeoman.app %>/scripts/{,*/}*.js'
],
}
},
},
concat: {
live: {
files: {
'<%= yeoman.dist %>/assets/custom.modernizr.js': [
'<%= yeoman.app %>/components/foundation/js/vendor/custom.modernizr.js'
],
'<%= yeoman.dist %>/assets/main.js': [
'<%= yeoman.app %>/components/foundation/js/vendor/jquery.js',
'<%= yeoman.app %>/components/foundation/js/foundation/foundation.js',
'<%= yeoman.app %>/components/foundation/js/foundation/foundation.*.js',
'<%= yeoman.app %>/scripts/{,*/}*.js'
],
}
}
},
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/assets',
src: '{,*/}*.{png,jpg,jpeg}',
dest: '<%= yeoman.dist %>/assets'
}]
}
},
cssmin: {
dist: {
files: {
'<%= yeoman.dist %>/assets/main.css': [
'.tmp/styles/{,*/}*.css',
'<%= yeoman.app %>/styles/{,*/}*.css'
]
}
}
},
sync: {
main: {
files: [{
cwd: '<%= yeoman.app %>',
src: [
'assets/*',
'config/*',
'layout/*',
'snippets/*',
'templates/*',
],
dest: '<%= yeoman.dist %>',
}]
}
},
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'assets/*',
'config/*',
'layout/*',
'snippets/*',
'templates/*',
]
},{
expand: true,
cwd: '<%= yeoman.app %>/components/font-awesome/font',
dest: '<%= yeoman.dist %>/assets',
src: [
'*'
]
}]
},
}
});
grunt.renameTask('regarde', 'watch');
grunt.registerTask('live', [
'clean:dist',
'compass:live',
'cssmin',
'concat:live',
'copy',
'watch'
]);
grunt.registerTask('build', [
'clean:dist',
'compass:dist',
'cssmin',
'imagemin',
'uglify',
'copy'
]);
grunt.registerTask('default', [
'jshint',
'build'
]);
};
Hey this would be awesome too as I use LiveReload for all my projects, but I think it's really for local web development servers rather than live servers, or in this case shopify which doesn't give you any kind of server level control in that respect.
However, there is this awesome grunt task!
it essentially watches any file changes when editing files locally, then automatically uploads them to the respective shopify store/theme, I've not had any issues with it at all and it's been a huge timesaver.
Hope that helps :)

yeoman grunt build task

I am using the Compass framework to build my css files.
I created a new .scss file test.scss in app/styles separate from main.scss.
While using grunt build, all of my .scss files have been compiled to css and created in the .tmp folder, but only main.css is moved to dist/style. My test.css file is not moving.
Gruntfile:
// Generated on 2014-04-01 using generator-webapp 0.4.7
'use strict';
// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'
module.exports = function (grunt) {
// Load grunt tasks automatically
require('load-grunt-tasks')(grunt);
// Time how long tasks take. Can help when optimizing build times
require('time-grunt')(grunt);
// Define the configuration for all the tasks
grunt.initConfig({
// Project settings
yeoman: {
// Configurable paths
app: 'app',
dist: 'dist'
},
// Watches files for changes and runs tasks based on the changed files
watch: {
js: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
tasks: ['jshint'],
options: {
livereload: true
}
},
jstest: {
files: ['test/spec/{,*/}*.js'],
tasks: ['test:watch']
},
gruntfile: {
files: ['Gruntfile.js']
},
compass: {
files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
tasks: ['compass:server', 'autoprefixer']
},
styles: {
files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
tasks: ['newer:copy:styles', 'autoprefixer']
},
livereload: {
options: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'<%= yeoman.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',
'<%= yeoman.app %>/images/{,*/}*.{gif,jpeg,jpg,png,svg,webp}'
]
}
},
// The actual grunt server settings
connect: {
options: {
port: 9000,
livereload: 35729,
// Change this to '0.0.0.0' to access the server from outside
hostname: 'localhost'
},
livereload: {
options: {
open: true,
base: [
'.tmp',
'<%= yeoman.app %>'
]
}
},
test: {
options: {
port: 9001,
base: [
'.tmp',
'test',
'<%= yeoman.app %>'
]
}
},
dist: {
options: {
open: true,
base: '<%= yeoman.dist %>',
livereload: false
}
}
},
// Empties folders to start fresh
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= yeoman.dist %>/*',
'!<%= yeoman.dist %>/.git*'
]
}]
},
server: '.tmp'
},
// Make sure code styles are up to par and there are no obvious mistakes
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: [
'Gruntfile.js',
'<%= yeoman.app %>/scripts/{,*/}*.js',
'!<%= yeoman.app %>/scripts/vendor/*',
'test/spec/{,*/}*.js'
]
},
// Mocha testing framework configuration options
mocha: {
all: {
options: {
run: true,
urls: ['http://<%= connect.test.options.hostname %>:<%= connect.test.options.port %>/index.html']
}
}
},
// Compiles Sass to CSS and generates necessary files if requested
compass: {
options: {
sassDir: '<%= yeoman.app %>/styles',
cssDir: '.tmp/styles',
generatedImagesDir: '.tmp/images/generated',
imagesDir: '<%= yeoman.app %>/images',
javascriptsDir: '<%= yeoman.app %>/scripts',
fontsDir: '<%= yeoman.app %>/styles/fonts',
importPath: '<%= yeoman.app %>/bower_components',
httpImagesPath: '/images',
httpGeneratedImagesPath: '/images/generated',
httpFontsPath: '/styles/fonts',
relativeAssets: false,
assetCacheBuster: false
},
dist: {
options: {
generatedImagesDir: '<%= yeoman.dist %>/images/generated'
}
},
server: {
options: {
debugInfo: true
}
}
},
// Add vendor prefixed styles
autoprefixer: {
options: {
browsers: ['last 2 version', 'ie 8', 'ie 9']
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
// Automatically inject Bower components into the HTML file
'bower-install': {
app: {
html: '<%= yeoman.app %>/index.html',
ignorePath: '<%= yeoman.app %>/'
}
},
// Renames files for browser caching purposes
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
'<%= yeoman.dist %>/images/{,*/}*.{gif,jpeg,jpg,png,webp}',
'<%= yeoman.dist %>/styles/fonts/{,*/}*.*'
]
}
}
},
// 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: {
options: {
dest: '<%= yeoman.dist %>'
},
html: '<%= yeoman.app %>/index.html'
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
options: {
assetsDirs: ['<%= yeoman.dist %>']
},
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
},
// The following *-min tasks produce minified files in the dist folder
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.{gif,jpeg,jpg,png}',
dest: '<%= yeoman.dist %>/images'
}]
}
},
svgmin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.svg',
dest: '<%= yeoman.dist %>/images'
}]
}
},
htmlmin: {
dist: {
options: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
removeCommentsFromCDATA: true,
removeEmptyAttributes: true,
removeOptionalTags: true,
removeRedundantAttributes: true,
useShortDoctype: true
},
files: [{
expand: true,
cwd: '<%= yeoman.dist %>',
src: '{,*/}*.html',
dest: '<%= yeoman.dist %>'
}]
}
},
// By default, your `index.html`'s <!-- Usemin block --> will take care of
// minification. These next options are pre-configured if you do not wish
// to use the Usemin blocks.
cssmin: {
dist: {
files: {
'<%= yeoman.dist %>/styles/main.css': [
'.tmp/styles/{,*/}*.css',
'<%= yeoman.app %>/styles/{,*/}*.css'
]
}
}
},
// uglify: {
// dist: {
// files: {
// '<%= yeoman.dist %>/scripts/scripts.js': [
// '<%= yeoman.dist %>/scripts/scripts.js'
// ]
// }
// }
// },
// concat: {
// dist: {}
// },
// Copies remaining files to places other tasks can use
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'images/{,*/}*.webp',
'{,*/}*.html',
'styles/fonts/{,*/}*.*',
'bower_components/' + (this.includeCompass ? 'sass-' : '') + 'bootstrap/' + (this.includeCompass ? 'fonts/' : 'dist/fonts/') +'*.*'
]
}]
},
styles: {
expand: true,
dot: true,
cwd: '<%= yeoman.app %>/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
},
// Generates a custom Modernizr build that includes only the tests you
// reference in your app
modernizr: {
devFile: '<%= yeoman.app %>/bower_components/modernizr/modernizr.js',
outputFile: '<%= yeoman.dist %>/bower_components/modernizr/modernizr.js',
files: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
'!<%= yeoman.dist %>/scripts/vendor/*'
],
uglify: true
},
// Run some tasks in parallel to speed up build process
concurrent: {
server: [
'compass:server',
'copy:styles'
],
test: [
'copy:styles'
],
dist: [
'compass',
'copy:styles',
'imagemin',
'svgmin'
]
}
});
grunt.registerTask('serve', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'concurrent:server',
'autoprefixer',
'connect:livereload',
'watch'
]);
});
grunt.registerTask('server', function () {
grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
grunt.task.run(['serve']);
});
grunt.registerTask('test', function(target) {
if (target !== 'watch') {
grunt.task.run([
'clean:server',
'concurrent:test',
'autoprefixer',
]);
}
grunt.task.run([
'connect:test',
'mocha'
]);
});
grunt.registerTask('build', [
'clean:dist',
'compass:dist',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'cssmin',
'uglify',
'copy:dist',
'modernizr',
//'rev',
'usemin'
//'htmlmin'
]);
grunt.registerTask('default', [
'newer:jshint',
'test',
'build'
]);
};
The main.css you see in your dist folder is actually a file concatenation.
If you want your test.scss to be in there, look at your index.html file.
You will see the following:
```
<!-- build:css({.tmp,app}) styles/main.css -->
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="styles/test.css">
<!-- endbuild -->
```
When you build, yeoman will look for all those files and create a main.css from them.

grunt bower-install does nothing?

I'm very new with grunt/bower. What I'm trying to do is install dependencies on my application and have them injected into my source directly.
I do something like:
bower install socket.io-client
followed by;
grunt bower-install
Since I want the newly installed dependencies in my index.html, and indeed my grunt serve shows:
>> File "app/index.html" changed.
... Reload app/index.html ...
Completed in 0.000s at Wed Mar 19 2014 15:06:11 GMT+0100 (CET) - Waiting...
And then I check my index.html file to see that nothing has changed. Also, I can check on my browser console that io isn't available.
What am I doing wrong here? Doesn't grunt bower-install work out of the box, or do I need to change it? What is grunt bower-install doing that triggers a change on the grunt serve output?
EDIT (Gruntfile.js)
// Generated on 2014-03-06 using generator-angular 0.7.1
'use strict';
// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'
module.exports = function (grunt) {
// Load grunt tasks automatically
require('load-grunt-tasks')(grunt);
// Time how long tasks take. Can help when optimizing build times
require('time-grunt')(grunt);
// Define the configuration for all the tasks
grunt.initConfig({
// Project settings
yeoman: {
// configurable paths
app: require('./bower.json').appPath || 'app',
dist: 'dist'
},
// Watches files for changes and runs tasks based on the changed files
watch: {
js: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
tasks: ['newer:jshint:all'],
options: {
livereload: true
}
},
jsTest: {
files: ['test/spec/{,*/}*.js'],
tasks: ['newer:jshint:test', 'karma']
},
compass: {
files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
tasks: ['compass:server', 'autoprefixer']
},
gruntfile: {
files: ['Gruntfile.js']
},
livereload: {
options: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'<%= yeoman.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
},
// The actual grunt server settings
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: '0.0.0.0',
livereload: 35729
},
livereload: {
options: {
open: true,
base: [
'.tmp',
'<%= yeoman.app %>'
]
}
},
test: {
options: {
port: 9001,
base: [
'.tmp',
'test',
'<%= yeoman.app %>'
]
}
},
dist: {
options: {
base: '<%= yeoman.dist %>'
}
}
},
// Make sure code styles are up to par and there are no obvious mistakes
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: [
'Gruntfile.js',
'<%= yeoman.app %>/scripts/{,*/}*.js'
],
test: {
options: {
jshintrc: 'test/.jshintrc'
},
src: ['test/spec/{,*/}*.js']
}
},
// Empties folders to start fresh
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= yeoman.dist %>/*',
'!<%= yeoman.dist %>/.git*'
]
}]
},
server: '.tmp'
},
// Add vendor prefixed styles
autoprefixer: {
options: {
browsers: ['last 1 version']
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
// Automatically inject Bower components into the app
'bower-install': {
app: {
html: '<%= yeoman.app %>/index.html',
ignorePath: '<%= yeoman.app %>/'
}
},
// Compiles Sass to CSS and generates necessary files if requested
compass: {
options: {
sassDir: '<%= yeoman.app %>/styles',
cssDir: '.tmp/styles',
generatedImagesDir: '.tmp/images/generated',
imagesDir: '<%= yeoman.app %>/images',
javascriptsDir: '<%= yeoman.app %>/scripts',
fontsDir: '<%= yeoman.app %>/styles/fonts',
importPath: '<%= yeoman.app %>/bower_components',
httpImagesPath: '/images',
httpGeneratedImagesPath: '/images/generated',
httpFontsPath: '/styles/fonts',
relativeAssets: false,
assetCacheBuster: false,
raw: 'Sass::Script::Number.precision = 10\n'
},
dist: {
options: {
generatedImagesDir: '<%= yeoman.dist %>/images/generated'
}
},
server: {
options: {
debugInfo: true
}
}
},
// Renames files for browser caching purposes
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/styles/fonts/*'
]
}
}
},
// 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 %>'
}
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
options: {
assetsDirs: ['<%= yeoman.dist %>']
}
},
// The following *-min tasks produce minified files in the dist folder
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.{png,jpg,jpeg,gif}',
dest: '<%= yeoman.dist %>/images'
}]
}
},
svgmin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.svg',
dest: '<%= yeoman.dist %>/images'
}]
}
},
htmlmin: {
dist: {
options: {
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeCommentsFromCDATA: true,
removeOptionalTags: true
},
files: [{
expand: true,
cwd: '<%= yeoman.dist %>',
src: ['*.html', 'views/{,*/}*.html'],
dest: '<%= yeoman.dist %>'
}]
}
},
// Allow the use of non-minsafe AngularJS files. Automatically makes it
// minsafe compatible so Uglify does not destroy the ng references
ngmin: {
dist: {
files: [{
expand: true,
cwd: '.tmp/concat/scripts',
src: '*.js',
dest: '.tmp/concat/scripts'
}]
}
},
// Replace Google CDN references
cdnify: {
dist: {
html: ['<%= yeoman.dist %>/*.html']
}
},
// Copies remaining files to places other tasks can use
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'*.html',
'views/{,*/}*.html',
'bower_components/**/*',
'images/{,*/}*.{webp}',
'fonts/*'
]
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= yeoman.dist %>/images',
src: ['generated/*']
}]
},
styles: {
expand: true,
cwd: '<%= yeoman.app %>/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
},
// Run some tasks in parallel to speed up the build process
concurrent: {
server: [
'compass:server'
],
test: [
'compass'
],
dist: [
'compass:dist',
'imagemin',
'svgmin'
]
},
// By default, your `index.html`'s <!-- Usemin block --> will take care of
// minification. These next options are pre-configured if you do not wish
// to use the Usemin blocks.
// cssmin: {
// dist: {
// files: {
// '<%= yeoman.dist %>/styles/main.css': [
// '.tmp/styles/{,*/}*.css',
// '<%= yeoman.app %>/styles/{,*/}*.css'
// ]
// }
// }
// },
// uglify: {
// dist: {
// files: {
// '<%= yeoman.dist %>/scripts/scripts.js': [
// '<%= yeoman.dist %>/scripts/scripts.js'
// ]
// }
// }
// },
// concat: {
// dist: {}
// },
// Test settings
karma: {
unit: {
configFile: 'karma.conf.js',
singleRun: true
}
}
});
grunt.registerTask('serve', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'bower-install',
'concurrent:server',
'autoprefixer',
'connect:livereload',
'watch'
]);
});
grunt.registerTask('server', function () {
grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
grunt.task.run(['serve']);
});
grunt.registerTask('test', [
'clean:server',
'concurrent:test',
'autoprefixer',
'connect:test',
'karma'
]);
grunt.registerTask('build', [
'clean:dist',
'bower-install',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngmin',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'rev',
'usemin',
'htmlmin'
]);
grunt.registerTask('default', [
'newer:jshint',
'test',
'build'
]);
};
You need to be sure to save your installed dependencies to bower.json (bower install --save __). grunt-bower-install uses that file to know what dependencies your app has.

Grunt-rev doesn't modify the img src of my html file

I am using grunt-rev with grunt-usemin for cache busting. The issue is that grunt rev modify the name of my pictures : logo.png to 45475_logo.png but there is only the root files (/index.php header.php footer.php) who are modify for get the new url. All my other php files link the wrong img.
Here my Gruntfile.js :
module.exports = function(grunt) {
var gruntConfig = {
app: 'app',
dist: 'dist'
};
// Project configuration.
grunt.initConfig({
grunt: gruntConfig,
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= grunt.dist %>/*',
'!<%= grunt.dist %>/.git*'
]
}]
},
server: '.tmp'
},
useminPrepare: {
html: ['<%= grunt.app %>/**/*.php'],
options: {
dest: '<%= grunt.dist %>/'
}
},
usemin: {
html: ['<%= grunt.dist %>/**/*.php'],
css: ['<%= grunt.dist %>/**/*.css'],
options: {
dirs: ['<%= grunt.dist %>']
}
},
imagemin: {
dynamic: {
options: {
optimizationLevel: 7,
pngquant: true
},
files: [{
expand: true, // Enable dynamic expansion
cwd: '<%= grunt.app %>/img/', // Src matches are relative to this path
src: ['**/*.{png,jpg}'], // Actual patterns to match
dest: '<%= grunt.dist %>/img' // Destination path prefix
}]
}
},
copy: {
main: {
files: [
{expand: true, cwd: '<%= grunt.app %>/', src: ['**'], dest: '<%= grunt.dist %>/'} // makes all src relative to cwd
]
},
font: {
expand: true,
cwd: '<%= grunt.app %>/css/fonts/font-awesome/font/',
src: ['**'],
dest: '<%= grunt.dist %>/font/'
},
htaccess: {
src: '<%= grunt.app %>/.htaccess',
dest: '<%= grunt.dist %>/.htaccess'
}
},
htmlcompressor:{
dist: {
files: [{
expand: true,
cwd: '<%= grunt.dist %>',
src: [ '**/*.php'],
dest: '<%= grunt.dist %>'
}]
}
},
rev: {
options: {
encoding: 'utf8',
algorithm: 'md5',
length: 8
},
assets: {
files: [{
src: [
'<%= grunt.dist %>/js/{,*/}*.js',
'<%= grunt.dist %>/css/{,*/}*.css',
'<%= grunt.dist %>/library/{,*/}*.css',
'<%= grunt.dist %>/library/{,*/}*.js',
'<%= grunt.dist %>/img/**/*.{jpg,jpeg,gif,png}',
'<%= grunt.dist %>/**/*.{eot,svg,ttf,woff}'
]
}]
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-htmlmin');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-processhtml');
grunt.loadNpmTasks('grunt-usemin');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-htmlcompressor');
grunt.loadNpmTasks('grunt-rev');
grunt.registerTask('build', [
'clean:dist',
'copy:main',
'imagemin',
'useminPrepare',
'concat',
'cssmin',
'uglify',
'rev',
'usemin',
'htmlcompressor',
'copy:font',
'copy:htaccess',
'clean:server'
]);
grunt.registerTask('default', [
'build'
]);
};
I don't know the origin of the issue.

Resources