I've installed bootstrap-sass and grunt-sass, and want to customise the bootstrap components included in my build.
I've created a copy of _bootstrap.scss in my app/styles/ folder and need to override the default import paths - what changes do I need to make to my Gruntfile for this to work?
I've tried including the full path the Bootstrap partials in my _bootstrap.scss file, but that doesn't compile. Gruntfile extract below.
Gruntfile
// Compiles Sass to CSS and generates necessary files if requested
sass: {
options: {
sourceMap: true,
sourceMapEmbed: true,
sourceMapContents: true,
includePaths: ['.']
},
dist: {
files: [{
expand: true,
cwd: '<%= config.app %>/styles',
src: ['*.{scss,sass}'],
dest: '.tmp/styles',
ext: '.css'
}]
},
server: {
files: [{
expand: true,
cwd: '<%= config.app %>/styles',
src: ['*.{scss,sass}'],
dest: '.tmp/styles',
ext: '.css'
}]
}
},
Here is what I did using Grunt and Bower along with Bootstrap to make a custom install including / excluding bootstrap components which might help you.
Once I had Grunt and Bower set up I added bootstrap-sass using bower install boostrap-sass --save-dev so that my bower.json file was updated.
Modifying Bootstrap
I imported bower_components/bootstrap-sass/assets/stylesheets/_bootstrap.scss into my my styles.scss file.
Then edited _bootstrap.scss commenting out which ever components I didn't want or need.
Next, created a file called _main.scss and stored this in a subdirectory (partials) of where my styles.scss file was, then imported _main.scss below the _bootstrap.scss.
This way I could override bootstrap if need be with my own custom styles by editing _main.scss.
Here's a starter grunt setup I used which might help explain the file structure.
Styles.scss file
// Bootstrap
#import 'bower_components/bootstrap-sass/assets/stylesheets/bootstrap';
// Custom styles
#import 'partials/main';
Gruntfile.js
module.exports = function(grunt){
// Configure task(s)
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// setup uglify task
uglify: {
build: {
files: {
'js/scripts.min.js': ['bower_components/jquery/dist/jquery.min.js', 'bower_components/bootstrap-sass/assets/javascripts/bootstrap.min.js', 'src/js/*.js']
},
},
dev: {
options: {
beautify: true,
mangle: false,
compress: false,
preserveComments: 'all'
},
files: {
'js/scripts.min.js': ['bower_components/jquery/dist/jquery.js', 'bower_components/bootstrap-sass/assets/javascripts/bootstrap.js', 'src/js/*.js']
},
},
},
// setup watch task
watch: {
js: {
files: ['bower_components/**/*.js', 'src/js/*.js'],
tasks: ['uglify:dev']
},
css: {
files: ['src/scss/**/*.scss'],
tasks: ['sass:dev']
},
},
// setup sass
sass: {
dev: {
options: {
outputStyle: 'expanded'
},
files: {
'css/styles.min.css' : 'src/scss/styles.scss'
},
},
build: {
options: {
outputStyle: 'compressed'
},
files: {
'css/styles.min.css' : 'src/scss/styles.scss'
},
},
},
});
// Load the plugins
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass');
// Register task(s)
grunt.registerTask('default', ['uglify:dev','sass:dev']);
grunt.registerTask('build', ['uglify:build', 'sass:build']);
};
From there you should be able to add your own custom bootstrap styles and / or remove components from bootstrap you don't want. Then just run grunt or grunt build depending on whether you want a development output (non minified or not). Or grunt watch while you are editing for instant compile. Add in livereload chrome extension and the app and you'll have live updates across all files.
A couple of months late.. but hope this helps!
Related
I am facing an issue with grunt-contrib-less plugin.
Problem Explanation
I have multiple less partials files which i am including in a main.less file. My grunt watch listen for changes in less files and run the less task. The problem is grunt contrib less is compiling the partials individually which throws error as some variable not define (which is actually defined in _var.less file).
I tried to negate the partials in my grunt file, but its not working.
here is my grunt config.
less: {
development: {
options: {
compress: false,
yuicompress: false/*,
optimization: 2*/
},
files: [
{
expand: true,
cwd: 'css/less',
//src: ['*.less'],
src: ['*.less', "!_*.less"],
// dest: 'dest/css/',
dest: 'css/',
ext: '.css'
}
]
}
},
watch: {
styles: {
files: ['css/less/*.less'], // which files to watch
tasks: ['less'],
options: {
nospawn: true
}
}
}
Please tell me what is wrong here.
I have installed Grunt, Node and updated npm. I am trying to minify all js files into one single file using "grunt uglify". The above command creating new js files with minified code. I placed all JS files in js and also tried with src folders. Below is my code please help With this, I am new to Grunt:
module.exports = function(grunt){
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
my_target: {
files: [{
expand: true,
cwd: 'src/js',
src: '**/*.js',
dest: 'dest/.min.js'
}]
}
},
cssmin: {
my_target:{
files : [{
expand: true,
cwd: 'css/',
src: ['*.css', '.min.css'],
//src: '*.css',
dest: 'css/',
ext: '.min.css'
}]
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
}
I know it's been a year since the question was asked, but I'd like to contribute anyway for the sake of googling and finding this thread.
To achieve what you're trying to do you should NOT use expand param. Just set src and dest ones. Like this:
module.exports = function(grunt){
grunt.initConfig({
uglify: {
my_target: {
files: [{
src: "js/src/*.js",
dest: "js/main.min.js"
}]
},
},
});
grunt.loadNpmTasks('grunt-contrib-uglify');
};
Hope this helps.
I'm having trouble using grunt-contrib-imagemin, insofar as I can't get it to compress any images.
Here's my Gruntfile.js
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
dist: {
src: [
'css/{base,global,medium,large}.css', // All CSS in the CSS folder
],
dest: 'css/build/production.css',
}
},
cssmin: {
build: {
src: 'css/build/production.css',
dest: 'css/build/production.min.css'
}
},
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'if3/images',
src: ['**/*.{png,jpg,gif}'],
dest: 'images/build'
}]
}
}
});
// 3. Where we tell Grunt we plan to use this plug-in.
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-imagemin');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['concat', 'cssmin', 'imagemin']);
}
When I run grunt from the command line, each of concat and cssmin run fine, whereas imagemin - although running without errors - returns the following message.
Running "imagemin:dynamic" (imagemin) task
Minified 0 images (saved 0 B)
For info, my folder structure is as follows.
if3\
css\
*.css
images\
*.png
*.jpg
js\
*.js
node_modules\
etc.
Gruntfile.js
package.json
*.html
The image folder currently contains 7 PNG and 2 JPG files, but I can't figure out why it's not doing anything with them.
Any help much appreciated.
Thanks
your src-properties in your concat and cssmin tasks do not contain if3. your imagemin config does. removing that should probably help...
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'images',
src: ['**/*.{png,jpg,gif}'],
dest: 'images/build'
}]
}
}
you don't need use: dynamic {} or static {} and will works perfect.
see: Grunt imagemin running but not minifying
I am trying to automate my workflow with the help of Grunt. I have everything set up, but the watch task is not working - I can start it, but it doesn't detect changes. The problem really must be in the watch task, as I can trigger the sass task by hand and it compiles correctly without problems.
My Gruntfile looks like this:
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
options: {
'style': 'compressed'
},
expand: true,
cwd: './sass/',
src: 'style.scss',
dest: './css/',
ext: '.css'
},
dev: {
options: {
'style': 'expanded',
},
expand: true,
cwd: './sass/',
src: 'style.scss',
dest: './css/',
ext: '.css'
}
},
watch: {
sass: {
files: ['<%= sass.dev.src %>'],
tasks: ['default']
}
}
});
grunt.registerTask('default', ['sass:dev']);
};
The structure in the project directory looks like this:
Gruntfile.js
index.html
package.json
css
> style.css (created by sass task)
node_modules
> all required modules
sass
> style.scss
To me everything looks good, but as it is not working something must be wrong. My guess it that the paths following the 'expand' option are off, although I already tried other structures that didn't work either.
Because sass.dev.src equals src: 'style.scss'. The watch task configured with files: ['<%= sass.dev.src %>'] will try and watch ./style.scss and not ./sass/style.scss.
The watch task has a cwd option (options:{cwd:'./sass'}) but probably easier to just set it to watch files: ['sass/*.scss'] instead.
I am trying to achieve a smooth workflow.
my problem:
My JS modifications are shown and minified and the live reload works fine. When I make changes to my SCSS files they do not run under the run command:
grunt
or the grunt plugin:
grunt watch
It only works when I invoke:
grunt sass
This was the output from the 'grunt sass' console window:
Macintosh:grunt-test Neil$ grunt sass
Running "sass:dist" (sass) task
File "css/global.css" created.
Done, without errors.
Notes:
When I run 'grunt watch' on a sass file I have noticed that grunt runs the minification on the javascript for no reason. Surely this be invoked when that file or one of its dependencies is effected?
Gruntfile.js Contents:
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
options: {
files: ['css/*.css'],
livereload: true
},
css: {
files: ['css/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
},
scripts: {
files: ['js/*.js', 'scss/*.scss'],
tasks: ['concat', 'uglify'],
options: {
spawn: false,
}
}
},
sass: {
dist: {
options: {
style: 'compressed'
},
expand: true,
cwd: 'scss/',
src: ['*.scss'],
dest: 'css/',
ext: '.css'
}
},
concat: {
// 2. Configuration for concatinating files goes here.
dist: {
src: [
'js/libs/*.js', // All JS in the libs folder
'js/global.js' // This specific file
],
dest: 'js/build/production.js',
}
},
uglify: {
build: {
src: 'js/build/production.js',
dest: 'js/build/production.min.js'
}
},
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'images-lossy/',
src: ['**/*.{png,jpg,gif}'],
dest: 'images/'
}]
},
png: {
options: {
optimizationLevel: 7
}
},
jpg: {
options: {
progressive: true
}
}
}
});
// 3. Where we tell Grunt we plan to use this plug-in.
// CONCATENATION PLUGIN
grunt.loadNpmTasks('grunt-contrib-concat');
// MINIFY PLUGIN
grunt.loadNpmTasks('grunt-contrib-uglify');
// IMG CRUSH PLUGIN
grunt.loadNpmTasks('grunt-contrib-imagemin');
// GRUNT WATCH PLUGIN
grunt.loadNpmTasks('grunt-contrib-watch');
// SASS LIBARY PLUGIN
grunt.loadNpmTasks('grunt-contrib-sass');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['sass','concat', 'uglify', 'imagemin', 'watch']);
};
I hope the above information helps. I have previously used Codekit, and it a really great app. I want to move to grunt but maybe my configuration file is incorrect I am close.
Any help would be greatly appreciated.
Neil
It looks like both of your issues occur within the watch configuration.
First, the reason the SASS task isn't working during watch is due to the files entry pointing to the wrong location. Your current files entry points to the "css" folder, but it should point to the "scss" folder, according to what you've specified in the actual "sass" task. In other words, your entry should be: files: ['scss/*.scss'].
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
}
Second, the JavaScript minification occurs during the watch whenever a SASS file changes because you have it listed here:
scripts: {
files: ['js/*.js', 'scss/*.scss'], // <-- scss is covered here
tasks: ['concat', 'uglify'],
options: {
spawn: false,
}
}
Change it to files: ['js/*.js'], instead to have the watch task kick in for JavaScript files only.
Once you address those issues, if things are slightly working you might want to expand the patterns so that it covers all files in the subdirectories for your JavaScript, CSS, SASS, etc. For example, js/*.js includes all .js files under the js folder, while js/**/*.js covers the js folder and its subfolders. You can read more under the GruntJS "globbing patterns" documentation.
EDIT: here's how the updated watch should look like...
watch: {
options: {
livereload: true
},
// css is really for Sass
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
},
// scripts will detect js changes
scripts: {
files: ['js/**/*.js'],
tasks: ['jshint', 'concat', 'uglify'],
options: {
spawn: false,
}
}
},
As mentioned, your individual tasks might need to use the ** pattern similar to what I've done with the "scripts" entry above: js/**/*.js