I am using Grunt and grunt-contrib-less to compile LESS files to CSS. Project has two CSS file but I want to only one of them was minifier. When I set "compress" above files are comressed.
Can you help me config Gruntfile.js?
my Gruntfile.js
'use strict';
module.exports = function(grunt) {
grunt.initConfig({
less: {
dist: {
files: {
'assets/css/main.min.css': [ // THIS FILE I WANT TO COMPRESS
'assets/less/app.less'
],
'assets/css/style.css': [ // THIS FILE I DO NOT WANT TO COMPRESS
'assets/less/style.less'
]
},
options: {
compress: false
}
}
},
});
// Load tasks
grunt.loadNpmTasks('grunt-contrib-less');
// Register tasks
grunt.registerTask('default', [
'less'
]);
};
I think you have to create two seperate tasks. Something like this:
'use strict';
module.exports = function(grunt) {
grunt.initConfig({
less: {
one: {
files: {
'assets/css/main.min.css': [ // THIS FILE I WANT TO COMPRESS
'assets/less/app.less'
]
},
options: {
compress: true
}
},
two: {
files: {
'assets/css/style.css': [ // THIS FILE I DO NOT WANT TO COMPRESS
'assets/less/style.less'
]
},
options: {
compress: false
}
}
},
});
// Load tasks
grunt.loadNpmTasks('grunt-contrib-less');
// Register tasks
grunt.registerTask('default', [
'less'
]);
};
More info: http://gruntjs.com/configuring-tasks
Edit:
You'll need something like this then:
'use strict';
module.exports = function(grunt) {
grunt.initConfig({
less: {
one: {
files: {
'assets/css/main.min.css': [ // THIS FILE I WANT TO COMPRESS
'assets/less/app.less'
]
},
options: {
compress: true
}
},
two: {
files: {
'assets/css/style.css': [ // THIS FILE I DO NOT WANT TO COMPRESS
'assets/less/style.less'
]
},
options: {
compress: false
}
},
three: {
files: {
'assets/css/main.min.css': [ // THIS FILE I WANT TO COMPRESS
'assets/less/app.less'
]
},
options: {
compress: true
}
},
four: {
files: {
'assets/css/style.css': [ // THIS FILE I DO NOT WANT TO COMPRESS
'assets/less/style.less'
]
},
options: {
compress: false
}
}
},
});
// Load tasks
grunt.loadNpmTasks('grunt-contrib-less');
// Register tasks
grunt.registerTask('production', ['one', 'two']);
grunt.registerTask('development', ['three', 'four']);
};
Related
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
The grunt-autoprefixer said "This project has been deprecated in favour of grunt-postcss." So, I want to change it to grunt-postcss.
My current setting in Gruntfile.js for grunt-autoprefixer
autoprefixer: {
options: {
browsers: ['last 1 version']
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
If upgrade to grunt-postcss. How can I write my settings in Gruntfile.js?
I saw the README in grunt-postcss, but I didn't get it. Seems some values cannnot mapping to the new settings for grunt-postcss.
It is done like any other postcss processors. See this for example:
var autoprefixer = require('autoprefixer-core');
grunt.initConfig({
postcss: {
options: {
processors: [
autoprefixer({
browsers: ['> 0.5%', 'last 2 versions']
}).postcss
]
},
dist: {
files: {
'dist/': 'css/*.css'
}
}
}
});
Warning from 2020:
The usage of browsers option in autoprefixer processor has changed.
Now you need to move the browsers option into your package.json file:
Gruntfile.js
...
processors: [
...
// No autoprefixer 'browsers' option
require('autoprefixer')(),
...
]
...
package.json
{
...
// 'browserslist' option at the end of the file just above the last curly brace
'browserslist': [
'last 2 versions',
'> 0.5%'
]
}
See: https://github.com/browserslist/browserslist#browserslist-
(This answer I took from the part of my similar answer here: https://stackoverflow.com/a/64079551/12320578)
An example of working postcss-autoprefixer usage:
Gruntfile.js
module.exports = function (grunt) {
grunt.initConfig({
postcss: {
options: {
processors: [
require('autoprefixer')({grid: 'autoplace'}),
],
map: {
inline: false, // save all sourcemaps as separate files...
annotation: 'assets/css/' // ...to the specified directory
}
},
dist: {
files: {
// Generated file target location and source location
'assets/css/style.min.css': 'assets/css/style.css',
'assets/css/info.min.css': 'assets/css/info.css'
}
// or:
/*files: [
{
expand: true,
src: ['assets/css/*.css', '!**/*.min.css'],
ext: '.min.css',
extDot: 'first'
}
]*/
}
},
watch: {
styles: {
files: ['assets/css/style.css', 'assets/css/info.css'],
// or:
/*files: ['assets/css/*.css', '!assets/css/*.min.css'],*/
tasks: ['postcss']
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-postcss');
};
package.json
{
... // Other already existing options
"browserslist": [
"last 4 versions",
"> 0.5%"
]
}
See https://gruntjs.com/configuring-tasks#building-the-files-object-dynamically
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
}
}
},
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' ]);
};
I have this setup in my Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
compress: false,
yuicompress: false,
optimization: 0
},
files: {
// target.css file: source.less file
"assets/css/main.css": "assets/css/main.less"
},
}
},
watch: {
styles: {
// Which files to watch (all .less files recursively in the less directory)
files: ['assets/css/*.less', 'assets/less/*.less'],
tasks: ['less'],
},
// Live reload CSS
css: {
files: ['assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true,
},
},
},
});
// Watch
grunt.loadNpmTasks('grunt-contrib-watch');
// Less Complile
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', ['less','watch']);
};
My sylesheet is loaded like this:
<link rel="stylesheet" href="http://project.dev/wp-content/themes/project/style.css">
Whenever I change the css file the I get a 404 error in the browser for this url
http://project.dev/assets/css/main.css?livereload=1392748371895
Which is of course right because the css file lives in:
http://project.dev/wp-content/themes/project/assets/css/main.css
How do I get live reload to get the right URL?
You have to set the base so that Grunt knows where to run the application from. The files the tasks output should be set to reflect the structure Wordpress expects. Its all in the path configuration.
You can achieve a more flexible path structure if you configure it early on Grunt's configuration. Assuming that the Gruntfile.js is in the root of your site (besides the wp-content directory), you could do the following configuration:
grunt.initConfig({
// configurable paths
cfg: {
dist: './wp-content/themes/project'
},
// tasks configurations come here...
});
Then on the watch task, you'd set:
livereload: {
files: ['<%= cfg.dist %>/assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true
}
}
The resulting Gruntfile.js would look like:
module.exports = function(grunt) {
grunt.initConfig({
// configurable paths
cfg: {
dist: './wp-content/themes/project'
},
less: {
development: {
options: {
compress: false,
yuicompress: false,
optimization: 0
},
files: {
'<%= cfg.dist %>/assets/css/main.css': '<%= cfg.dist %>/assets/css/main.less'
}
}
},
watch: {
styles: {
files: ['<%= cfg.dist %>/assets/css/*.less', '<%= cfg.dist %>/assets/less/*.less'],
tasks: ['less']
},
css: {
files: ['<%= cfg.dist %>/assets/css/*.css'],
options: {
nospawn: true,
interrupt: false,
livereload: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less','watch']);
};
You'd still have to adjust the above to fit your needs, but the principle is there.
I don't have a setup I can test this on, but I think you need to set the base option:
// Project configuration.
grunt.initConfig({
connect: {
server: {
options: {
base: 'www-root'
}
}
}
});
See doc here: https://github.com/gruntjs/grunt-contrib-connect/blob/master/README.md#basic-use
Read down through multiple servers if relevant.