Cannot compile Bootstrap 3 LESS main file (bootstrap.less) using Grunt? - node.js

I'm not able to compile the "main" bootstrap.less into '<%= pkg.name %>.css'. I'm getting this error running grunt less:
Running "less:dist" (less) task
>> ParseError: Syntax Error on line 643 in bower_components\bootstrap\less\mixins.less:643:25
>> padding-right: (#grid-gutter-width / 2);
>> &:extend(.clearfix all);
>> }
Warning: Error compiling LESS. Use --force to continue.
Aborted due to warnings.
My configuration for less task is fairly simple:
less: {
options: {
strictMath: true
},
dist: {
files: {
'dist/assets/css/<%= pkg.name %>.css': [
'<%= bootstrap_less %>/bootstrap.less',
'src/assets/less/style.less'
]
}
}
},
// Arbitrary properties used in task configuration templates.
bower_components: 'bower_components',
bootstrap_less: '<%= bower_components %>/bootstrap/less'
Error line in mixins.less (not modified by me in any way):
// Centered container element
.container-fixed() {
margin-right: auto;
margin-left: auto;
padding-left: (#grid-gutter-width / 2);
padding-right: (#grid-gutter-width / 2);
&:extend(.clearfix all);
}
Please also not I'm new to Grunt and maybe I'm missing something.

Perhaps your version of less is outdated? :extend() is a new-ish feature of Less.

Related

Grunt css Purge no output file

In the gruntfile.js i wrote:
// Css Purge
css_purge: {
options: {
"verbose": false,
"no_duplicate_property": true,
},
files: {
src: 'css/bigfile.css',
dest: 'css/purged.css'
},
}
Just to test the bigFile.css is :
body {color: red;}
body, p {color:red;}
p {color: red; font-size: 24px;}
#test p {color: red;}
So terminal message is:
Running "css_purge:files" (css_purge) task
"css/" has been created
Thu May 12 2016 01:33:27 GMT-0400 (EDT) Success! css/bigfile.css : css/purged.css
But the new file purged.css is the same as bigFile.css
Ok just figure it out. It removed only identical rules. So if I have exactly same rule it will be removed in output file. Is there a tool that remove extra css like in my exemple file body,p {color:red;} is extra code since I already have body {color:red;} ?

Grunt: How do I run seperate processes for CSS (sass, concat, minify) and JS (concat, minify)

I'm looking at the grunt watch documentation but I can see how to run a separate process for my javascript files. Below is what I have for CSS:
GruntFile.js
module.exports = function(grunt) {
grunt.initConfig({
// running `grunt sass` will compile once
sass: {
dist: {
options: {
style: 'expanded'
},
files: {
'./public/css/sass_styles.css': './src/sass/sass_styles.scss' // 'destination': 'source'
}
}
},
// bring in additonal files that are not part of the sass styles set
concat: {
dist: {
src: [
'public/css/datepicker.css',
'public/css/jquery.tagsinput.css',
'public/css/sass_styles.css',
'application/themes/japantravel/style.css'
],
dest: 'public/css/all.css',
},
},
// running `grunt cssmin` will minify code to *.min.css file(s)
cssmin: {
minify: {
expand: true,
cwd: "public/css/",
src: ["all.css", "!*.min.css"],
dest: "public/css/",
ext: ".min.css"
}
},
// running `grunt watch` will watch for changes
watch: {
files: ["./src/sass/*.scss", "./src/sass/partials/*.scss"],
tasks: ["sass", "concat", "cssmin"]
}
});
// load tasks
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-watch");
};
As you can see I have tasks for CSS ["sass", "concat", "cssmin"], but I want to do separate tasks for separate files (js) - concat and minify - and listen for changes (watch). Can someone point me in the correct direction, I'm not really sure what I should be searching for. Is this something that watch can handle, or is there another plugin? I'm a little new to grunt so still trying to figure out how to use it. Thanks
You can use 'grunt-concurrent' for that, you can define multiple tasks with it. In combination with watch sets you will have the proper solution. https://github.com/sindresorhus/grunt-concurrent
# to install:
npm install grunt-concurrent --save-dev
And this will be your adjusted function then.
Remember, you still have to set some uglify and jshint properties! But I believe that's not the issue here.
module.exports = function(grunt) {
grunt.initConfig({
/* .. */
// running `grunt watch` will watch for changes
watch: {
// Use 'sets' like this, just make up a name for it:
watchCss: {
files: ["./src/sass/*.scss", "./src/sass/partials/*.scss"], // Directory to look for changes
tasks: ["concurrent:taskCss"] // Tasks you want to run when CSS changes
},
watchJs: {
files: ["./src/js/**/*.js"], // Directory to look for changes
tasks: ["concurrent:taskJs"] // Tasks you want to run when JS changes
}
},
concurrent: {
taskCss: ["sass", "concat", "cssmin"], // define the CSS tasks here
taskJs: ["jshint", "concat", "uglify"] // define the JS tasks here
},
});
// load tasks
grunt.loadNpmTasks("grunt-contrib-sass");
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks('grunt-contrib-jshint'); // Added
grunt.loadNpmTasks('grunt-contrib-uglify'); // Added
grunt.loadNpmTasks("grunt-concurrent"); // Added
// register tasks (note: you can execute sets from concurrent)
grunt.registerTask('default', ["concurrent:taskCss", "concurrent:taskJs"]);
grunt.registerTask('css', ["concurrent:taskCss"]);
grunt.registerTask('js', ["concurrent:taskJs"]);
};
To watch for changes:
grunt watch
# if a css file is changed, only the css tasks are performed
You can also execute a task from the prompt directly, for example:
grunt js
# This will only execute the registered task 'js'
# In this case that task points to 'concurrent:taskJs' wich will run jshint, concat and uglify
To install uglify and jshint:
https://github.com/gruntjs/grunt-contrib-uglify
https://github.com/gruntjs/grunt-contrib-jshint
npm install grunt-contrib-uglify --save-dev
npm install grunt-contrib-jshint --save-dev

SVG and Grunt turning output partially black

I've just installed Grunt and grunt-svgstore and am using it to compile my folder of SVG's into one application.svg where each icon has a unique id that I can reference using:
It works fine for some icons, but for others, part of their shapes turn black. In the case of the ruby logo I am linking to above, it shows like: http://cl.ly/image/0X2J0f3i0C1X/Screen%20Shot%202014-08-03%20at%2011.02.47.png
The actually SVG file can be found here: http://cl.ly/2k012T020d2S/ruby-logo.svg
If I open the ruby-logo.svg file in illustrator, it looks fine. I have rexported it, ensured all settings are correct and it still happens.
Any suggestions?
Thanks,
Neil
Solved by adding the following styles to the application.svg import at the top of my document:
width: 0;
height: 0;
visibility: hidden;
Use the "style" option instead..
eg:
svgstore: {
options: {
prefix : 'icon-', // This will prefix each ID
svg: {
viewBox : '0 0 100 100',
xmlns: 'http://www.w3.org/2000/svg',
style: 'display:none;' // This line might help you!
},
cleanup: ['fill','stroke']
},
default: {
files: {
'<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.svg': '<%= app_files.svgIcons %>'
}
}
},

Grunt won't find any tasks

Im fairly new to the whole "front end workflow" stuff, and im trying to learn how to use grunt, and ive set up a task to minify my css but Grunt wont find any tasks whatsoever
this is my grunt file
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
min:{
dist:{
src: 'public/stylesheets/*.css',
dest: 'public/stylesheets/builds'
}
}
});
grunt.registerTask('default', ['min']);
}
minify is installed globally and in the project
ive tried running the default
grunt
and
grunt min
minify is in my package.json as
"minify": "~0.6.1",
Several potential issues here, all of which are likely causing the issues.
Problem: You are using minify which isn't a grunt plugin.
Solutions: npm install grunt-contrib-uglify and/or grunt-contrib-cssmin as makes sense for your needs.
Problem: You aren't loading any plugins/tasks...at least not in the code you posted.
Solution: Load tasks with grunt.loadNpmTasks before you register tasks. For example, if you use uglify and cssmin, you would need these lines before grunt.registerTask:
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
Possible complete solution for this specific issue
1) npm install grunt-contrib-uglify
2) npm install grunt-contrib-cssmin
3) Update your gruntfile to resemble this.
You will need to edit the directories to match your project specifics...this is almost guaranteed to fail if you don't edit it first. See the docs for grunt-contrib-uglify or -cssmin for full details on options, paths, etc...:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
},
cssmin: {
minify: {
expand: true,
cwd: 'release/css/',
src: ['*.css', '!*.min.css'],
dest: 'release/css/',
ext: '.min.css'
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default', ['uglify', 'cssmin']);
};

Ember.js - Handlebars not recognized if required via Grunt (Node.js)

is anybody else using Grunt as build tool for the Ember web application and is experiencing the same behaviour as I do? At this time, I'm using the framework in version RC3 and I can use my build tool without hassle and import all necessary libraries, uglify and compress them and everything works like a charm.
Anyhow, at least since Ember RC5 I'm not able to use Grunt for building my application anymore as Ember would not recognize Handlebars anymore!. It's always complaining that Ember Handlebars requires Handlebars version 1.0.0-rc.4. Include a SCRIPT tag in the HTML HEAD linking to the Handlebars file before you link to Ember. and right afterwards it says Cannot read property 'COMPILER_REVISION' of undefined which leads me to the assumption that Ember is not recognizing the included Handlebars library.
I haven't changed anything in my app.js (the order of the libraries/frameworks is untouched) except the references to the js files (using Ember RC5/6 instead of RC3 and Handlebars RC4 instead of RC3). But it seems that something breaks the initialization of Ember.Handlebars since then...
Do I get something wrong here? Is there a solution out there so that I can continue using Grunt as build tool?
EDIT
Here's my Gruntfile.js:
/*jshint camelcase: false */
/*global module:false */
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
meta: {
dev: {
buildPath: '.'
},
prod: {
buildPath: '.'
}
},
/*
Task for uglifyng the application javascript file in production environment
*/
uglify: {
options: {
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */'
},
prod: {
files: [
{
src: '<%= meta.prod.buildPath %>/js/application.js',
dest: '<%= meta.prod.buildPath %>/js/application.min.js'
}
]
}
},
/*
Task for creating css files out of the scss files
*/
compass: {
prod: {
options: {
environment: 'production',
noLineComments: true,
outputStyle: 'expanded',
cssDir: '<%= meta.prod.buildPath %>/css',
fontsDir: '<%= meta.prod.buildPath %>/fonts',
imagesDir: '<%= meta.prod.buildPath %>/images',
javascriptsDir: '<%= meta.prod.buildPath %>/js'
}
},
dev: {
options: {
environment: 'development',
noLineComments: false,
outputStyle: 'expanded',
cssDir: '<%= meta.dev.buildPath %>/css',
fontsDir: '<%= meta.dev.buildPath %>/fonts',
imagesDir: '<%= meta.dev.buildPath %>/images',
javascriptsDir: '<%= meta.dev.buildPath %>/js'
}
}
},
/*
Task to minify all css files in production mode.
All css files will end with '.min.css' instead of
just '.css'.
*/
cssmin: {
minify: {
expand: true,
cwd: '<%= meta.prod.buildPath %>/css/',
src: ['*.css', '!*.min.css'],
dest: '<%= meta.prod.buildPath %>/css/',
ext: '.min.css'
}
},
/*
Clean up the production build path
*/
clean: {
cssd: ['<%= meta.prod.buildPath %>/css/**/*']
},
/*
A simple ordered concatenation strategy.
This will start at app/app.js and begin
adding dependencies in the correct order
writing their string contents into 'application.js'
Additionally it will wrap them in evals
with # sourceURL statements so errors, log
statements and debugging will reference
the source files by line number.
This option is set to false for production.
*/
neuter: {
prod: {
options: {
includeSourceURL: false
},
files: [
{
src: 'app/app.js',
dest: '<%= meta.prod.buildPath %>/js/application.js'
}
]
},
dev: {
options: {
includeSourceURL: true
},
files: [
{
src: 'app/app.js',
dest: '<%= meta.dev.buildPath %>/js/application.js'
}
]
}
},
/*
Watch files for changes.
Changes in dependencies/ember.js or application javascript
will trigger the neuter task.
Changes to any templates will trigger the ember_templates
task (which writes a new compiled file into dependencies/)
and then neuter all the files again.
*/
watch: {
application_code: {
files: ['js/dependencies/ember.js', 'app/**/*.js'],
tasks: ['neuter:dev']
},
compass: {
files: [
'styles/**/*.scss'
],
tasks: ['compass:dev']
}
},
/*
Runs all .html files found in the test/ directory through PhantomJS.
Prints the report in your terminal.
*/
qunit: {
all: ['test/**/*.html']
},
/*
Reads the projects .jshintrc file and applies coding
standards. Doesn't lint the dependencies or test
support files.
*/
jshint: {
all: ['Gruntfile.js', 'app/**/*.js', 'test/**/*.js', '!js/dependencies/*.*', '!test/support/*.*'],
options: {
jshintrc: '.jshintrc'
}
},
/*
Generate the YUI Doc documentation.
*/
yuidoc: {
name: '<%= pkg.name %>',
description: '<%= pkg.description %>',
version: '<%= pkg.version %>',
options: {
paths: '<%= meta.dev.buildPath %>/app/',
outdir: '<%= meta.dev.buildPath %>/yuidocs/'
}
},
/*
Find all the <whatever>_test.js files in the test folder.
These will get loaded via script tags when the task is run.
This gets run as part of the larger 'test' task registered
below.
*/
build_test_runner_file: {
all: ['test/**/*_test.js']
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-neuter');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-yuidoc');
/*
A task to build the test runner html file that get place in
/test so it will be picked up by the qunit task. Will
place a single <script> tag into the body for every file passed to
its coniguration above in the grunt.initConfig above.
*/
grunt.registerMultiTask('build_test_runner_file', 'Creates a test runner file.', function () {
var tmpl = grunt.file.read('test/support/runner.html.tmpl');
var renderingContext = {
data: {
files: this.filesSrc.map(function (fileSrc) {
return fileSrc.replace('test/', '');
})
}
};
grunt.file.write('test/runner.html', grunt.template.process(tmpl, renderingContext));
});
/*
A task to run the application's unit tests via the command line.
It will
- convert all the handlebars templates into compile functions
- combine these files + application files in order
- lint the result
- build an html file with a script tag for each test file
- headlessy load this page and print the test runner results
*/
grunt.registerTask('test', ['neuter', 'jshint', 'build_test_runner_file', 'qunit']);
/*
Configures all tasks which will be executed with production setup
*/
grunt.registerTask('prod_tasks', ['clean', 'compass:prod', 'cssmin', 'neuter:prod', 'uglify:prod']);
/*
Setup for the production build. Sets the production build path.
*/
grunt.registerTask('prod', 'Production Build', function () {
grunt.task.run('prod_tasks');
});
/*
Configures all tasks which will be executed with development setup
*/
grunt.registerTask('dev_tasks', ['compass:dev', 'neuter:dev', 'watch']);
/*
Setup for the development build. Sets the development build path.
*/
grunt.registerTask('dev', 'Development Build', function () {
grunt.task.run('dev_tasks');
});
// Default task
grunt.registerTask('default', 'dev');
/*
Configures all tasks which will be executed with doc setup
*/
grunt.registerTask('doc_tasks', ['yuidoc']);
/*
Setup for the YUI doc generation.
*/
grunt.registerTask('doc', 'Generate YuiDoc Documentation for the App', function () {
grunt.task.run('doc_tasks');
});
};
EDIT 2
I took the ember-1.0.0-rc.6.js and handlebars-1.0.0-rc.4.js files from the starter kit at the Ember.js website and tried to run the Grunt tasks on it. Here's what Chrome is telling me:
EDIT 3
Just in case if anybody cares, here's the link to the raised issue over at the Ember.js Github page: https://github.com/emberjs/ember.js/issues/2894
EDIT 4
Finally, the issue was identified to be a Handlebars inconsistency when dealing with global exports, like #Tao reported in his answer. Here's the link to the Issue on GitHub if you want to follow: https://github.com/wycats/handlebars.js/issues/539
It looks like this issue is being addressed in the next version of Handlebars: https://github.com/wycats/handlebars.js/issues/539 Stay tuned.
You have a mismatch in the version used to compile the Handlebars templates and the version included via the script tag.
If you are using grunt-contrib-handlebars, it uses the npm module handlebars to compile the the templates. The handlebars module/project is independent of Ember and has its own revisions that may or not be compatible with Ember.
To maintain compatibility with Handlebars Ember needs specific versions of handlebars which it is warning you about.
The tricky part here is you need to ensure that grunt-contrib-handlebars is forced to use that specific version of handlebars.
Solution 1: Use shrinkwrap to change grunt-contrib-handlebars's handlebars dependency version.
Solution 2: This is what I am currently using. I have switched to Emblem. The emblem grunt task asks for your handlebars file explicitly so you don't have to drop down to node sub dependency management. And your build includes the same file into your script tags, thus avoiding duplication/mismatch for future revisions.
Edit: After Gruntfile edit
Looking at the Gruntfile I don't see anything amiss. Looks like a standard build process, js -> neuter -> (if prod) -> uglify etc.
I think you need to try refreshing both emberjs and handlebars js files. Try using the files from the starter kit itself, those definitely work together.
And verify this for your index.html by looking at the unminified source in Chrome/Inspector. Handlebars has the revision numbers below the banner something like Handlebars.VERSION and Handlebars.COMPILER_REVISION. Match those with what you see in the ember.js file, somewhere below #submodule ember-handlebars-compiler in the Ember.assert.

Resources