Grunt usemin Warning: Object has no method 'contains' - grunt-usemin

I am using Grunt task runner, and the Gruntfile.js" is as follows:
'use strict';
module.exports = function(grunt){
require('time-grunt')(grunt);
require('jit-grunt')(grunt, {
useminPrepare: 'grunt-usemin'
});
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: {
src: ['Gruntfile.js', 'app/scripts/{,*/}*.js']
}
},
useminPrepare: {
html: 'app/menu.html',
options: {
dest: 'dist'
}
},
concat: {
options: {
separator: ';'
},
dist:{}
},
uglify:{
dist:{}
},
cssmin: {
dist:{}
},
filerev: {
options: {
encoding: 'utf8',
algorithm: 'md5',
length: 20
},
release: {
files:[{
src: ['dist/scripts/*.js', 'dist/styles/*.css']
}]
}
},
usemin: {
html: ['dist/*.html'],
css: ['dist/styles/*.css'],
options: {
assetsDirs: ['dist', 'dist/styles']
}
},
copy: {
dist: {
cwd: 'app',
src: ['**', '!styles/**/*.css', '!scripts/**/*.js'],
dest: 'dist',
expand: true
},
fonts: {
files: [
{
expand: true,
dot: true,
cwd: 'bower_components/bootstrap/dist',
src: ['fonts/*.*'],
dest: 'dist'
},
{
expand: true,
dot: true,
cwd: 'bower_components/font-awesome',
src: ['fonts/*.*'],
dest: 'dist'
}
]
}
},
clean: {
build:{
src: ['dist/']
}
}
});
grunt.registerTask('build', ['clean', 'jshint', 'useminPrepare', 'concat', 'cssmin', 'uglify', 'copy', 'filerev', 'usemin']);
grunt.registerTask('default', ['build']);
};
The problem is that when the grunt is executing usemin, it shows the following warning and aborts the task:
I cannot figure out exactly where the problem is and therefore I don't know how many more codes do I have to give. I am a beginner.
Update:
here is my own script that I used in the project:
'use strict';
angular.module('confusionApp', []).controller('menuController', function(){
var dishes=[
{
name:'Uthapizza',
image: 'images/uthapizza.png',
category: 'mains',
label:'Hot',
price:'4.99',
description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
comment: ''
},
{
name:'Zucchipakoda',
image: 'images/zucchipakoda.png',
category: 'appetizer',
label:'',
price:'1.99',
description:'Deep fried Zucchini coated with mildly spiced Chickpea flour batter accompanied with a sweet-tangy tamarind sauce',
comment: ''
},
{
name:'Vadonut',
image: 'images/vadonut.png',
category: 'appetizer',
label:'New',
price:'1.99',
description:'A quintessential ConFusion experience, is it a vada or is it a donut?',
comment: ''
},
{
name:'ElaiCheese Cake',
image: 'images/elaicheesecake.png',
category: 'dessert',
label:'',
price:'2.99',
description:'A delectable, semi-sweet New York Style Cheese Cake, with Graham cracker crust and spiced with Indian cardamoms',
comment: ''
}
];
this.dishes = dishes;
this.tab = 1;
this.filtText = '';
this.select = function(setTab){
this.tab = setTab;
if(setTab === 2){
this.filtText = "appetizer";
}
else if(setTab === 3){
this.filtText = "mains";
}
else if(setTab === 4){
this.filtText = "dessert";
}
else{
this.filtText = "";
}
};
this.isSelected = function(isTab){
if(this.tab === isTab){
return true;
}
return false;
};
});
Update
This is the stack trace of the error that I got.
Running "usemin:html" (usemin) task
Warning: Object has no method 'contains' Use --force to continue.
TypeError: Object has no method 'contains'
at replaceWith (E:\Study\Front End JS Framework AngularJS\conFusion\node_modules\grunt-usemin\lib\fileprocessor.js:170:16)
at null.<anonymous> (E:\Study\Front End JS Framework AngularJS\conFusion\node_modules\grunt-usemin\lib\fileprocessor.js:157:45)
at Array.forEach (native)
at replaceBlocks (E:\Study\Front End JS Framework AngularJS\conFusion\node_modules\grunt-usemin\lib\fileprocessor.js:155:15)
at FileProcessor.process (E:\Study\Front End JS Framework AngularJS\conFusion\node_modules\grunt-usemin\lib\fileprocessor.js:239:45)
at E:\Study\Front End JS Framework AngularJS\conFusion\node_modules\grunt-usemin\tasks\usemin.js:141:31
at Array.forEach (native)
at E:\Study\Front End JS Framework AngularJS\conFusion\node_modules\grunt-usemin\tasks\usemin.js:135:13
at Array.forEach (native)
at Object.<anonymous> (E:\Study\Front End JS Framework AngularJS\conFusion\node_modules\grunt-usemin\tasks\usemin.js:130:16)

The problem lies with the usemin version that you are using. It turns out, changing your usemin version from 3.1.1 to 3.0.0 in your package.json solves the problem. My best bet is that there is no problem with your code but with the fileprocessor.js file in your usemin. Changing the version solves the problem.
Change usemin version on your package.json and run npm install.

Related

Grunt CLI crashing trying to compile bootstrap.less

I have been working on my mac for some time on a web app, compiling using Grunt on my mac - never a problem compiling.
I just set the project up on a new ultrabook PC (Acer Spin 5, i5, 8gig RAM, small but capable), but if I don't remove almost all entries in bootstrap.less the compile fails.
I start my compile using:
grunt dev -env=dev -f --verbose
The error I'm getting is:
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
I've read about setting "max-old-space-size" setting for node, but I am not entirely sure how to set it up in my gruntfile.js or package.json (I'm not so well versed in Grunt/Node on the whole).
If I remove all but the first couple of imports in bootstrap.less the compile finishes as expected.
My gruntfile is a bit of a monster too, too long to post in fact ;( I have removed irrelevant parts of it below:
module.exports = function (grunt) {
'use strict';
// Force use of Unix newlines
grunt.util.linefeed = '\n';
RegExp.quote = function (string) {
return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
};
var fs = require('fs');
var path = require('path');
var npmShrinkwrap = require('npm-shrinkwrap');
var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js');
var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
var getLessVarsData = function () {
var filePath = path.join(__dirname, 'less/variables.less');
var fileContent = fs.readFileSync(filePath, {
encoding: 'utf8'
});
var parser = new BsLessdocParser(fileContent);
return {
sections: parser.parseFile()
};
};
var generateRawFiles = require('./grunt/bs-raw-files-generator.js');
var generateCommonJSModule = require('./grunt/bs-commonjs-generator.js');
var configBridge = grunt.file.readJSON('./grunt/configBridge.json', {
encoding: 'utf8'
});
Object.keys(configBridge.paths).forEach(function (key) {
configBridge.paths[key].forEach(function (val, i, arr) {
arr[i] = path.join('./docs/assets', val);
});
});
grunt.loadNpmTasks('grunt-include-replace-more');
grunt.loadNpmTasks('grunt-dev-prod-switch');
grunt.loadNpmTasks('grunt-minify-html');
grunt.loadNpmTasks('grunt-symlink');
// Project configuration.
grunt.initConfig({
// Metadata.
pkg: grunt.file.readJSON('package.json'),
banner: '/*!\n' +
' * Plenty.rdthree.com v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
' * Copyright 2015-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
' */\n',
jqueryCheck: configBridge.config.jqueryCheck.join('\n'),
jqueryVersionCheck: configBridge.config.jqueryVersionCheck.join('\n'),
// Task configuration.
clean: {
dist: 'dist',
docs: 'docs/dist',
pageSpecificJS: ['dist/js/pageScripts/*.js', '!dist/js/pageScripts/*.min.js'],
pageSpecificCSS: ['dist/css/*.css', '!dist/css/*.min.css']
},
jshint: {
options: {
jshintrc: 'js/.jshintrc'
},
grunt: {
options: {
jshintrc: 'grunt/.jshintrc'
},
src: ['Gruntfile.js', 'grunt/*.js']
},
core: {
src: 'js/*.js'
},
test: {
options: {
jshintrc: 'js/tests/unit/.jshintrc'
},
src: 'js/tests/unit/*.js'
},
assets: {
src: ['docs/assets/js/src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
}
},
jscs: {
options: {
config: 'js/.jscsrc'
},
grunt: {
src: '<%= jshint.grunt.src %>'
},
core: {
src: '<%= jshint.core.src %>'
},
test: {
src: '<%= jshint.test.src %>'
},
assets: {
options: {
requireCamelCaseOrUpperCaseIdentifiers: null
},
src: '<%= jshint.assets.src %>'
}
},
symlink: {
prod: {
dest: 'dist/prod',
relativeSrc: '../dist',
options: {
type: 'dir'
} // 'file' by default
},
perf: {
dest: 'dist/perf',
relativeSrc: '../dist',
options: {
type: 'dir'
} // 'file' by default
},
},
concat: {
bootstrap: {
options: {
banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>',
stripBanners: false
},
src: [
'js/vendor/jquery-migrate-3.0.0.js',
'js/bootstrap/transition.js',
'js/bootstrap/alert.js',
'js/bootstrap/button.js',
'js/bootstrap/carousel.js',
'js/bootstrap/collapse.js',
'js/bootstrap/dropdown.js',
'js/bootstrap/modal.js',
'js/bootstrap/tooltip.js',
'js/bootstrap/popover.js',
'js/bootstrap/tab.js'
],
dest: 'dist/js/<%= pkg.name %>.js'
}
},
minifyHtml: {
options: {
cdata: true
},
dist: {
files: [{
expand: true,
cwd: 'dist',
src: ['*.html'],
dest: 'dist'
}]
}
},
dev_prod_switch: {
options: {
environment: grunt.option('env') || 'dev',
env_char: '#',
env_block_dev: 'env:dev',
env_block_prod: 'env:prod'
},
dynamic_mappings: {
files: [{
expand: true,
cwd: 'dist',
src: ['*.html', 'mobile/*.html', 'js/includes.js', 'mobile/js/mobile.js', 'js/includes.min.js', 'js/pageScripts/setup*.js', 'js/touch/touch-support*.js'],
dest: 'dist'
}]
}
},
uglify: {
options: {
preserveComments: 'false'
},
core: {
src: '<%= concat.bootstrap.dest %>',
dest: 'dist/js/<%= pkg.name %>.min.js'
},
includes: {
src: 'dist/js/includes.js',
dest: 'dist/js/includes.min.js'
},
mobile: {
src: 'dist/mobile/js/mobile.js',
dest: 'dist/mobile/js/mobile.min.js'
},
customize: {
src: configBridge.paths.customizerJs,
dest: 'docs/assets/js/customize.min.js'
},
docsJs: {
src: configBridge.paths.docsJs,
dest: 'docs/assets/js/docs.min.js'
},
dashboard: {
src: 'dist/js/pageScripts/dashboard.js',
dest: 'dist/js/pageScripts/dashboard.min.js'
},
setup: {
src: 'dist/js/pageScripts/setup.js',
dest: 'dist/js/pageScripts/setup.min.js'
},
billing: {
src: 'dist/js/pageScripts/billing.js',
dest: 'dist/js/pageScripts/billing.min.js'
},
schedule: {
src: 'dist/js/pageScripts/schedule.js',
dest: 'dist/js/pageScripts/schedule.min.js'
},
},
qunit: {
options: {
inject: 'js/tests/unit/phantom.js'
},
files: 'js/tests/index.html'
},
less: {
compileCore: {
options: {
strictMath: false,
sourceMap: false,
outputSourceFiles: true,
sourceMapURL: '<%= pkg.name %>.css.map',
sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
},
src: 'less/bootstrap.less',
dest: 'dist/css/<%= pkg.name %>.css'
},
},
autoprefixer: {
options: {
browsers: configBridge.config.autoprefixerBrowsers
},
core: {
options: {
map: true
},
src: 'dist/css/<%= pkg.name %>.css'
},
theme: {
options: {
map: true
},
src: 'dist/css/<%= pkg.name %>-theme.css'
},
plenty: {
options: {
map: true
},
src: 'dist/css/plenty.css'
},
docs: {
src: ['docs/assets/css/anchor.css', 'docs/assets/css/src/docs.css']
},
examples: {
expand: true,
cwd: 'docs/examples/',
src: ['**/*.css'],
dest: 'docs/examples/'
}
},
csslint: {
options: {
csslintrc: 'less/.csslintrc'
},
dist: [
'dist/css/bootstrap.css',
'dist/css/bootstrap-theme.css'
],
examples: [
'docs/examples/**/*.css'
],
docs: {
options: {
ids: false,
'overqualified-elements': false
},
src: 'docs/assets/css/src/docs.css'
}
},
cssmin: {
options: {
// TODO: disable `zeroUnits` optimization once clean-css 3.2 is released
// and then simplify the fix for https://github.com/twbs/bootstrap/issues/14837 accordingly
compatibility: 'ie8',
keepSpecialComments: '*',
advanced: false
},
minifyCore: {
src: 'dist/css/<%= pkg.name %>.css',
dest: 'dist/css/<%= pkg.name %>.min.css'
},
minifyTheme: {
src: 'dist/css/<%= pkg.name %>-theme.css',
dest: 'dist/css/<%= pkg.name %>-theme.min.css'
},
minifyPlenty: {
src: 'dist/css/plenty.css',
dest: 'dist/css/plenty.min.css'
},
minifySetup: {
src: 'dist/css/setup.css',
dest: 'dist/css/setup.min.css'
},
minifyDashboard: {
src: 'dist/css/dashboard.css',
dest: 'dist/css/dashboard.min.css'
},
},
usebanner: {
options: {
position: 'top',
banner: '<%= banner %>'
},
files: {
src: 'dist/css/*.css'
}
},
csscomb: {
options: {
config: 'less/.csscomb.json'
},
dist: {
expand: true,
cwd: 'dist/css/',
src: ['*.css', '!*.min.css'],
dest: 'dist/css/'
},
examples: {
expand: true,
cwd: 'docs/examples/',
src: '**/*.css',
dest: 'docs/examples/'
},
docs: {
src: 'docs/assets/css/src/docs.css',
dest: 'docs/assets/css/src/docs.css'
}
},
copy: {
fonts: {
expand: true,
src: 'fonts/*',
dest: 'dist/'
},
docs: {
expand: true,
cwd: 'dist/',
src: [
'**/*'
],
dest: 'docs/dist/'
},
img: {
cwd: 'img', // set working folder / root to copy
src: '**/*', // copy all files and subfolders
dest: 'dist/img', // destination folder
expand: true // required when using cwd
},
ajax: {
cwd: 'ajax', // set working folder / root to copy
src: '**/*', // copy all files and subfolders
dest: 'dist/ajax', // destination folder
expand: true // required when using cwd
},
},
includereplacemore: {
your_target: {
options: {
// Task-specific options go here.
},
// Files to perform replacements and includes with
src: ['*.html', 'ajax/*.html', "mobile/*.html"],
// Destination directory to copy files to
dest: 'dist/'
}
},
connect: {
server: {
options: {
port: 3000,
base: '.'
}
}
},
jekyll: {
options: {
config: '_config.yml'
},
docs: {},
github: {
options: {
raw: 'github: true'
}
}
},
jade: {
options: {
pretty: true,
data: getLessVarsData
},
customizerVars: {
src: 'docs/_jade/customizer-variables.jade',
dest: 'docs/_includes/customizer-variables.html'
},
customizerNav: {
src: 'docs/_jade/customizer-nav.jade',
dest: 'docs/_includes/nav/customize.html'
}
},
htmllint: {
options: {
ignore: [
'Attribute "autocomplete" not allowed on element "button" at this point.',
'Attribute "autocomplete" not allowed on element "input" at this point.',
'Element "img" is missing required attribute "src".'
]
},
src: '_gh_pages/**/*.html'
},
watch: {
src: {
files: '<%= jshint.core.src %>',
tasks: ['jshint:src', 'qunit', 'concat']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'qunit']
},
less: {
files: 'less/**/*.less',
tasks: 'less'
}
},
sed: {
versionNumber: {
pattern: (function () {
var old = grunt.option('oldver');
return old ? RegExp.quote(old) : old;
})(),
replacement: grunt.option('newver'),
recursive: true
}
},
'saucelabs-qunit': {
all: {
options: {
build: process.env.TRAVIS_JOB_ID,
throttled: 10,
maxRetries: 3,
maxPollRetries: 4,
urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'],
browsers: grunt.file.readYAML('grunt/sauce_browsers.yml')
}
}
},
exec: {
npmUpdate: {
command: 'npm update'
}
},
compress: {
main: {
options: {
archive: 'bootstrap-<%= pkg.version %>-dist.zip',
mode: 'zip',
level: 9,
pretty: true
},
files: [{
expand: true,
cwd: 'dist/',
src: ['**'],
dest: 'bootstrap-<%= pkg.version %>-dist'
}]
}
}
});
// These plugins provide necessary tasks.
require('load-grunt-tasks')(grunt, {
scope: 'devDependencies'
});
require('time-grunt')(grunt);
// Docs HTML validation task
grunt.registerTask('validate-html', ['jekyll:docs', 'htmllint']);
var runSubset = function (subset) {
return !process.env.TWBS_TEST || process.env.TWBS_TEST === subset;
};
var isUndefOrNonZero = function (val) {
return val === undefined || val !== '0';
};
// Test task.
var testSubtasks = [];
// Skip core tests if running a different subset of the test suite
if (runSubset('core') &&
// Skip core tests if this is a Savage build
process.env.TRAVIS_REPO_SLUG !== 'twbs-savage/bootstrap') {
testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'csslint:dist', 'test-js', 'docs']);
}
// Skip HTML validation if running a different subset of the test suite
if (runSubset('validate-html') &&
// Skip HTML5 validator on Travis when [skip validator] is in the commit message
isUndefOrNonZero(process.env.TWBS_DO_VALIDATOR)) {
testSubtasks.push('validate-html');
}
// Only run Sauce Labs tests if there's a Sauce access key
if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
// Skip Sauce if running a different subset of the test suite
runSubset('sauce-js-unit') &&
// Skip Sauce on Travis when [skip sauce] is in the commit message
isUndefOrNonZero(process.env.TWBS_DO_SAUCE)) {
testSubtasks.push('connect');
testSubtasks.push('saucelabs-qunit');
}
grunt.registerTask('test', testSubtasks);
grunt.registerTask('test-js', ['jshint:core', 'jshint:test', 'jshint:grunt', 'jscs:core', 'jscs:test', 'jscs:grunt', 'qunit']);
// JS distribution task.
grunt.registerTask('dist-js', ['concat', 'uglify:core', 'commonjs', 'includereplacemore']);
// JS minify page specific scripts
grunt.registerTask('uglify-pageScripts', ['uglify:dashboard', 'uglify:setup', 'uglify:billing', 'uglify:schedule', 'uglify:inventory', 'uglify:grainMarketing', 'uglify:map', 'uglify:organization', 'uglify:plans', 'uglify:schedule', 'uglify:services', 'uglify:servicessetup', 'uglify:timeentry', 'uglify:signin', 'uglify:characterPatterns', "uglify:mobile"]);
grunt.registerTask('uglify-touchScripts', ['uglify:touch_dashboard', 'uglify:touch_setup', 'uglify:touch_billing', 'uglify:touch_schedule', 'uglify:touch_inventory', 'uglify:touch_grainMarketing', 'uglify:touch_map', 'uglify:touch_organization', 'uglify:touch_plans', 'uglify:touch_schedule', 'uglify:touch_services', 'uglify:touch_servicessetup', 'uglify:touch_timeentry', 'uglify:touch_support']);
grunt.registerTask('uglify-mobile-pageScripts', ['uglify:mobile_activityList', 'uglify:mobile_addActivity', 'uglify:mobile_addPhotos', 'uglify:mobile_contactList', 'uglify:mobile_getPrepared', 'uglify:mobile_notes', 'uglify:mobile_schedule', 'uglify:mobile_taskDetail', 'uglify:mobile_taskInProgress', 'uglify:mobile_requirements', 'uglify:mobile_collect', 'uglify:mobile_viewPhoto', 'uglify:mobile_returnProducts', 'uglify:mobile_returnProduct']);
// Compile Page CSS
grunt.registerTask('compile-pageCSS', ['less:compilePlenty', 'less:compileSetup', 'less:compileDashboard', 'less:compileField', 'less:compileSignin', 'less:compileMobile']);
// Mimify CSS
grunt.registerTask('minify-pageCSS', ['cssmin:minifyCore', 'cssmin:minifyTheme', 'cssmin:minifyPlenty', 'cssmin:minifyDashboard', 'cssmin:minifySetup', 'cssmin:minifyField', 'cssmin:minifySignin', 'cssmin:minifyMobile']);
// JS Default Task.
grunt.registerTask('default-js', ['concat', 'uglify:core', 'uglify:includes', 'uglify:mobile', 'uglify-pageScripts', 'uglify-touchScripts', 'uglify-mobile-pageScripts', 'commonjs', 'includereplacemore']);
// CSS distribution task.
grunt.registerTask('less-compile', ['less:compileCore', 'less:compileTheme', 'compile-pageCSS', 'minify-pageCSS']);
grunt.registerTask('dist-css', ['less-compile', 'autoprefixer:core', 'autoprefixer:theme', 'autoprefixer:plenty', 'usebanner', 'csscomb:dist']);
// create symlinks
grunt.registerTask("symlinks", ['symlink:prod', 'symlink:perf']);
// Full distribution task.
grunt.registerTask('dev', ['clean:dist', 'dist-css', 'copy:fonts', 'copy:fontAwesome', 'symlinks', 'copy:weatherIcons', 'copy:intlTelInput', 'copy:phoneLib', 'copy:jquery311', 'copy:charPatterns', 'copy:pageScripts', 'copy:outdatedbrowser', 'copy:flatPickr', 'copy:hammertime', 'copy:hammerjs', 'copy:initialize', 'copy:touchsupport', 'copy:dropzone', 'copy:mobile', 'copy:xeditable', 'copy:manifest', 'copy:htaccess', 'copy:img', 'copy:ajax', 'dist-js', 'dev_prod_switch', 'minifyHtml']);
// Default task.
grunt.registerTask('prod', ['clean:dist', 'dist-css', 'copy:fonts', 'copy:fontAwesome', 'symlinks', 'copy:weatherIcons', 'copy:intlTelInput', 'copy:phoneLib', 'copy:jquery311', 'copy:charPatterns', 'copy:pageScripts', 'copy:outdatedbrowser', 'copy:flatPickr', 'copy:hammertime', 'copy:hammerjs', 'copy:initialize', 'copy:touchsupport', 'copy:dropzone', 'copy:mobile', 'copy:xeditable', 'copy:manifest', 'copy:htaccess', 'copy:img', 'copy:ajax', 'default-js', 'clean:pageSpecificJS', 'clean:pageSpecificCSS', 'dev_prod_switch', 'minifyHtml']);
// Version numbering task.
// grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
// This can be overzealous, so its changes should always be manually reviewed!
grunt.registerTask('change-version-number', 'sed');
grunt.registerTask('build-glyphicons-data', function () {
generateGlyphiconsData.call(this, grunt);
});
// task for building customizer
grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
grunt.registerTask('build-customizer-html', 'jade');
grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () {
var banner = grunt.template.process('<%= banner %>');
generateRawFiles(grunt, banner);
});
grunt.registerTask('commonjs', 'Generate CommonJS entrypoint module in dist dir.', function () {
var srcFiles = grunt.config.get('concat.bootstrap.src');
var destFilepath = 'dist/js/npm.js';
generateCommonJSModule(grunt, srcFiles, destFilepath);
});
// Docs task.
grunt.registerTask('docs-css', ['autoprefixer:docs', 'autoprefixer:examples', 'csscomb:docs', 'csscomb:examples', 'cssmin:docs']);
grunt.registerTask('lint-docs-css', ['csslint:docs', 'csslint:examples']);
grunt.registerTask('docs-js', ['uglify:docsJs', 'uglify:customize']);
grunt.registerTask('lint-docs-js', ['jshint:assets', 'jscs:assets']);
grunt.registerTask('docs', ['docs-css', 'lint-docs-css', 'docs-js', 'lint-docs-js', 'clean:docs', 'copy:docs', 'build-glyphicons-data', 'build-customizer']);
grunt.registerTask('prep-release', ['jekyll:github', 'compress']);
// Task for updating the cached npm packages used by the Travis build (which are controlled by test-infra/npm-shrinkwrap.json).
// This task should be run and the updated file should be committed whenever Bootstrap's dependencies change.
grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', '_update-shrinkwrap']);
grunt.registerTask('_update-shrinkwrap', function () {
var done = this.async();
npmShrinkwrap({
dev: true,
dirname: __dirname
}, function (err) {
if (err) {
grunt.fail.warn(err);
}
var dest = 'test-infra/npm-shrinkwrap.json';
fs.renameSync('npm-shrinkwrap.json', dest);
grunt.log.writeln('File ' + dest.cyan + ' updated.');
done();
});
});
};
Any assistance appreciated - thanks
I split up the bootstrap.less into two files which solved the issue

WebStorm / grunt debug run throwing EADDRINUSE error

I have a Node/Angular app, developed using the WebStorm IDE. I can run the application fine via WebStorm (Shift + F10). However, any time I try to run in debug mode, I am receiving the EADDRINUSE error:
Running "concurrent:default" (concurrent) task
Verifying property concurrent.default exists in config...OK
Files: [no src] -> default
Options: limit=10, logConcurrentOutput
Error: listen EADDRINUSE :::52387
Here is my gruntfile.js - like I said, WebStorm builds and runs it just fine, until I try to run it in debug mode, where it throws the error:
'use strict';
var fs = require('fs');
module.exports = function(grunt) {
// Unified Watch Object
var watchFiles = {
serverViews: ['app/views/**/*.*'],
serverJS: ['gruntfile.js', 'server.js', 'config/**/*.js', 'app/**/*.js', '!app/tests/'],
clientViews: ['public/modules/**/views/**/*.html'],
sass: ['public/css/*.scss'],
clientJS: ['public/js/*.js', 'public/modules/**/*.js'],
clientCSS: ['public/modules/**/*.css'],
mochaTests: ['app/tests/**/*.js']
};
// Project Configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
serverViews: {
files: watchFiles.serverViews,
options: {
livereload: true
}
},
serverJS: {
files: watchFiles.serverJS,
tasks: ['jshint'],
options: {
livereload: true
}
},
clientViews: {
files: watchFiles.clientViews,
options: {
livereload: true
}
},
clientJS: {
files: watchFiles.clientJS,
tasks: ['jshint'],
options: {
livereload: true
}
},
clientCSS: {
files: watchFiles.clientCSS,
tasks: ['csslint'],
options: {
livereload: true
}
},
sass: {
files: watchFiles.sass,
tasks: ['sass:dev'],
options: {
livereload: true
}
},
mochaTests: {
files: watchFiles.mochaTests,
tasks: ['test:server'],
}
},
jshint: {
all: {
src: watchFiles.clientJS.concat(watchFiles.serverJS),
options: {
jshintrc: true
}
}
},
csslint: {
options: {
csslintrc: '.csslintrc'
},
all: {
src: watchFiles.clientCSS
}
},
uglify: {
production: {
options: {
mangle: false
},
files: {
'public/dist/application.min.js': 'public/dist/application.js'
}
}
},
cssmin: {
combine: {
files: {
'public/dist/application.min.css': '<%= applicationCSSFiles %>'
}
}
},
nodemon: {
dev: {
script: 'server.js',
options: {
nodeArgs: ['--debug'],
ext: 'js,html',
watch: watchFiles.serverViews.concat(watchFiles.serverJS)
}
}
},
'node-inspector': {
custom: {
options: {
'web-port': 1337,
'web-host': 'localhost',
'debug-port': 5858,
'save-live-edit': true,
'no-preload': true,
'stack-trace-limit': 50,
'hidden': []
}
}
},
concurrent: {
default: ['nodemon', 'watch'],
debug: ['nodemon', 'watch', 'node-inspector'],
options: {
logConcurrentOutput: true,
limit: 10
}
},
env: {
test: {
NODE_ENV: 'test'
},
secure: {
NODE_ENV: 'secure'
},
development: {
NODE_ENV: 'development'
}
},
mochaTest: {
src: watchFiles.mochaTests,
options: {
reporter: 'spec',
require: 'server.js'
}
},
karma: {
unit: {
configFile: 'karma.conf.js'
}
},
sass: {
dev: {
files: {
'public/css/style.css': 'public/css/*.scss'
}
}
},
copy: {
localConfig: {
src: 'config/env/local.example.js',
dest: 'config/env/local.js',
filter: function() {
return !fs.existsSync('config/env/local.js');
}
}
}
});
// Load NPM tasks
require('load-grunt-tasks')(grunt);
// Making grunt default to force in order not to break the project.
grunt.option('force', true);
// A Task for loading the configuration object
grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() {
var init = require('./config/init')();
var config = require('./config/config');
grunt.config.set('applicationJavaScriptFiles', config.assets.js);
grunt.config.set('applicationCSSFiles', config.assets.css);
});
//Sass task
grunt.registerTask('default', ['lint', 'sass:dev', 'concurrent:default']);
// Debug task.
grunt.registerTask('debug', ['lint', 'copy:localConfig', 'concurrent:debug']);
// Secure task(s).
grunt.registerTask('secure', ['env:secure', 'lint', 'copy:localConfig', 'concurrent:default']);
// Lint task(s).
grunt.registerTask('lint', ['jshint', 'csslint']);
// Build task(s).
grunt.registerTask('build', ['lint', 'loadConfig', 'ngAnnotate', 'uglify', 'cssmin']);
// Test task.
grunt.registerTask('test', ['copy:localConfig', 'test:server', 'test:client']);
grunt.registerTask('test:server', ['env:test', 'mochaTest']);
grunt.registerTask('test:client', ['env:test', 'karma:unit']);
};
The problem is caused by the way Grunt spawns child tasks. By default, grunt.util.spawn() inherits main process arguments and starts child process with same options as the main process (--debug-brk=52387), so child process is started on the same debug port as the main process, causing EADDRINUSE. See https://github.com/gruntjs/grunt/issues/1420.
As a workaround, try adding process.execArgv = []; to the top of Gruntfile.js - it should help

Grunt not running any tasks except for watch

I'm trying to build a website with Bootstrap, using Grunt to run tasks. I have been trying to figure out why my gruntfile does not seem to be running any tasks except for 'watch', but I can't seem to find the answer. No errors show up either. In terminal, time-grunt will show the execution time (although no tasks are executed) and then it would say 'Waiting....' which means watch is running. Could someone shed some light on what I've done wrong in my gruntfile? Any help would be greatly appreciated :)
module.exports = function(grunt) {
//time
require('time-grunt')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
options: {
sourceMap: true,
style: 'compressed',
},
files: {
'assets/css/style.css' : 'assets/scss/style.scss',
}
}
},
copy: {
scripts: {
cwd: 'bower_components/jquery/dist/',
expand: true,
src: [
'jquery.min.js',
],
dest: 'assets/js/',
filter: 'isFile',
}
},
concat: {
options: {
separator: ';',
},
js: {
src: [
'bower_components/bootstrap-sass/assets/javascripts/bootstrap.js',
'bower_components/bootstrap-sass/assets/javascripts/bootstrap/button.js',
'bower_components/bootstrap-sass/assets/javascripts/bootstrap/collapse.js',
'bower_components/bootstrap-sass/assets/javascripts/bootstrap/dropdown.js',
'bower_components/bootstrap-sass/assets/javascripts/bootstrap/modal.js',
'bower_components/bootstrap-sass/assets/javascripts/bootstrap/tab.js',
'bower_components/bootstrap-sass/assets/javascripts/bootstrap/transition.js',
],
dest: 'assets/js/bootstrap.js',
},
sass: {
src: [
'bower_components/bootstrap-sass/assets/stylesheets/_bootstrap.scss',
'bower_components/bootstrap-sass/assets/stylesheets/bootstrap/**/*.scss'
],
dest: 'assets/scss/style.scss'
}
},
uglify: {
options: {
mangle: false,
},
my_target: {
files: {
'assets/css/style.min.css' : ['assets/css/style.css'],
'assets/js/bootstrap.min.js' : ['assets/js/bootstrap.js']
}
}
},
watch: {
gruntfile: {
files: 'Gruntfile.js',
tasks: ['jshint:gruntfile'],
options: {
livereload: true
}
},
src: {
files: ['assets/js/*.js', 'assets/scss/*.scss'],
tasks: ['default'],
options: {
livereload: true
}
}
},
jshint: {
all: ['Gruntfile.js', 'assets/**/*.js']
},
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('build', ['sass', 'copy', 'concat', 'uglify']);
grunt.registerTask('default', ['watch', 'jshint']);
};
Your tasks names and orders were a bit mixed up, here are 3 points to fully fix it - and provide StackOverflow with an answer to the question:
watch should always be the last task to run, as it does not end. So:
grunt.registerTask('default', ['jshint', 'watch']);
if you want to run a task (like build by just calling grunt, you have to put it in your default task, so:
grunt.registerTask('default', ['jshint', 'build', 'watch']);
your watch task must not launch a watch task itself, so watch.src should not call default (as default includes watch):
watch: {
gruntfile: {
files: 'Gruntfile.js',
tasks: ['jshint:gruntfile'],
options: {
livereload: true
}
},
src: {
files: ['assets/js/*.js', 'assets/scss/*.scss'],
tasks: ['jshint', 'build'],
options: {
livereload: true
}
}
},

why this error come 'can not read property summary of undefined' when running command grunt filerev_apply?

why I am getting can not read property summary of undefined error while I run grunt filerev_apply or grunt filerev_replace . And when I run grunt.filerev.summary
It shows grunt.filerev.summary is not recognized as internal or external command.
Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
filerev: {
options: {
algorithm: 'md5',
length: 8
},
images: {
src: ['views/common/abc.html'],
}
},
filerev_replace: {
options: {
assets_root: 'views/common/abc.html'
},
compiled_assets: {
src: 'views/common/abc.html'
},
views: {
options: {
views_root: 'views/'
},
src: 'views/**/*.html'
}
},
useminPrepare: {
html: 'index.html',
options: {
dest: 'indexfolder'
}
},
usemin: {
html: 'indexfolder/index.html',
options: {
dirs: ['views','views1'],
assetsDirs: ['views','views1'],
revmap: ''
}
},
filerev_apply: {
files: [
{
//expand: true,
//cwd: 'views',
src: ['views/**/*.html'],
//dest: 'views'
}
]
},
reload: {
//port: 8000,
proxy: {
host: 'localhost',
port: 80
}
},
watch: {
sass: {
files: ['views/**/*.html'],
tasks: ['reload'],
options: {
livereload: true,
}
}
}
});
grunt.loadNpmTasks('grunt-usemin');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-reload');
grunt.loadNpmTasks('grunt-filerev');
grunt.loadNpmTasks('grunt-filerev-apply');
grunt.loadNpmTasks('grunt-filerev-replace');
grunt.registerTask('default', ['usemin', 'useminPrepare', 'watch','connect', 'reload', 'filerev', 'filerev_apply', 'filerev_replace']);
};

Grunt watch task is not starting until the first output to console

My task configuration works fine but I have annoying issue where the watch task does not start to monitor unless I refresh a page or add a line for console output. So normally I am supposed to get:
Running "watch" task
Waiting...
But I don't get it until some output goes to the console.
Is it a bug?
My config is:
module.exports = function(grunt) {
grunt.initConfig({
concat: {
options: {
separator: '\n\n'
},
dev: {
src: ['ng_app/app.js', 'ng_app/**/*.js'],
dest: 'public/js/app.js'
}
},
less: {
dev: {
files: [
{
expand: true,
cwd: 'styles',
src: ['*.less', '!mixins.less', '!var.less'],
dest: 'public/css/',
ext: '.css'
},
{
expand: true,
cwd: 'styles/views',
src: ['*.less'],
dest: 'public/css/views',
ext: '.css'
}
]
}
},
express: {
dev: {
options: {
script: 'bin/www'
}
}
},
watch: {
options: {
livereload: true
},
express: {
files: ['**/*.js'],
tasks: ['express:dev'],
options: {
spawn: false
}
},
less: {
files: ['styles/**/*.less'],
tasks: ['less'],
options: {
livereload: false
}
},
concat: {
files: ['ng_app/**/*.js'],
tasks: ['concat'],
options: {
livereload: false
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-express-server');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['concat', 'less']);
grunt.registerTask('server', [ 'express:dev', 'watch' ]);
};

Resources