I have a working Gruntfile with less and autoprefixer. I also have 'grunt watch' working fine.
Before I was using autoprefixer, I was using less mixins for vendor prefixes. Running 'grunt less' would build working CSS with all my prefixes.
Now I have autoprefixer, but if I want to do a once-off build of my styles, I now have to run 'grunt less' then 'grunt autoprefixer' to get working CSS with prefixes.
How can I modify 'grunt less' so it build working, prefixes less again?
I've read the docs, and I know I could add an additional task to do both these things. However:
'grunt less' now doesn't have usable output. A task should always produce usable output.
I don't want to have to tell other people that 'grunt less' doesn't produce usable output
An additional task should not be required to replace one that doesn't work
I.e., I just want grunt less to produce working CSS (with prefixes).
module.exports = function(grunt) {
// Load Grunt tasks declared in the package.json file
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
// Configure Grunt
grunt.initConfig({
less: {
development: {
options: {
paths: ["./less"],
yuicompress: false
},
files: {
"./public/css/style.css": "./public/less/style.less"
}
}
},
autoprefixer: {
development: {
browsers: ['last 2 version', 'ie 9'],
expand: true,
flatten: true,
src: 'public/css/*.css',
dest: 'public/css'
}
},
watch: {
less: {
files: ["./public/less/*"],
tasks: ["less", "autoprefixer:development"],
options: {
livereload: true
}
}
},
});
};
For using autoprefixer as plugin for LESS, you must install npm-package less-plugin-autoprefix:
npm install grunt-contrib-less less-plugin-autoprefix --save-dev
Gruntfile.js
module.exports = function(grunt) {
"use strict";
var gruntConfig = {
less : {
options : {
plugins : [ new (require('less-plugin-autoprefix'))({browsers : [ "last 2 versions" ]}) ]
},
main : {
files: {
'src/css/desktop/bootstrap-theme.css' : 'src/less/desktop/bootstrap-theme.less',
'src/css/desktop/company.css' : 'src/less/desktop/company.less',
'src/css/desktop/index.css' : 'src/less/desktop/index.less',
'src/css/desktop/login.css' : 'src/less/desktop/login.less'
}
}
}
};
grunt.initConfig(gruntConfig);
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('default', [ 'less' ]);
};
Grunt can't do what you describe in the question as tasks do not know about each other inherently. You have to glue tasks together using aliases, (easy) or functions (for when you want a bit more control), but there's no way of modifying the way one of these tasks behaves without changing the source.
As an example, you could fork grunt-contrib-less and add the code to run the auto prefixing directly into the task, around here: https://github.com/gruntjs/grunt-contrib-less/blob/master/tasks/less.js#L69 - inject this line here https://github.com/nDmitry/grunt-autoprefixer/blob/master/tasks/autoprefixer.js#L56 and then use your fork instead of the official plugin.
The easiest and best way is to register a new task that does the job of these two tasks but in the one command, i.e:
grunt.registerTask('buildless', ['less', 'autoprefixer']);
I do this with all my own tasks - SASS compilation, JS concat + uglify, webfont generation etc. Just tell the others in your team to run those tasks and not grunt less or grunt autoprefixer on their own.
Better still, use my Grunt plugin available tasks. With this (and the filter config) you will be able to produce a trimmed down list of tasks whenever someone runs grunt availabletasks although I prefer to alias this with tasks for quicker typing. If you're like me and have been bitten by the automation bug (and have registered loads of plugins in your Gruntfile), this can really help a newcomer to the project with which tasks should be run.
Related
Our current build process currently uses Grunt, vueify, and browserify to build our Single File Components and also pull Vue out of the SFC and into its own external file.
For various reasons (vueify no longer supported, async loading components, ...) we want to switch to Webpack.
However, I am failing at wrapping my head on how to make our current method work for Webpack. I've included our current build process below. I would love to figure out how make Webpack work for us. Any suggestions? I can't even seem to get started... How can I make Webpack compile our *.vue.js files into pre-rendered javascript files? At the bottom I've also included the contents of one of our SFC .vue.js files.
vueRuntime: {
expand: true,
cwd: 'node_modules/vue/dist/',
src: 'vue.runtime.min.js',
dest: 'js/rwd/libs',
ext: '.js',
extDot: 'first',
options: {
configure: b => b
.require('vue')
.transform(
// Required in order to process node_modules files
{global: true},
envify({NODE_ENV: 'production'})
)
.bundle(),
browserifyOptions: {
debug: false
}
}
},
vue: {
expand: true,
cwd: 'js/rwd/',
src: '**/*.vue.js',
dest: 'js/rwd',
ext: '.js',
extDot: 'first',
options: {
configure: b => b
.transform('vueify')
.transform(
// Required in order to process node_modules files
{
global: true
},
envify({NODE_ENV: 'production'})
)
.external('vue')
.bundle(),
browserifyOptions: {
debug: false
}
}
}
A sample *.vue.js file:
const Vue = require('vue');
const App = require('./something/components/Something.vue');
new Vue(App).$mount('#app-element-id');
Having done a similar migration to Vue + Webpack recently, I found this blog post extremely helpful: https://itnext.io/vue-js-and-webpack-4-from-scratch-part-3-3f68d2a3c127
Another source of examples is the vue-cli. Unfortunately, the produced boilerplate is extremely hard to decipher because it requires a ton of node modules that all contribute minuscule amounts of config and also depend on other modules. So if you want to build something customized or actually learn how it all works together, it's more trouble than it's worth.
I'm using Lee Munroe's grunt-email-workflow to build out a set of email templates but I am not able to find where are the tasks configured.
When I run "grunt" from the terminal I can see that few tasks are executed:
-clean
-sass
-assemble pages
-juice
etc.
But the Gruntfile.js does not contain anything a part from:
module.exports = function(grunt) {
require('load-grunt-config')(grunt, {
// Pass data to tasks
data: {
// Re-usable filesystem path variables
paths: {
src: 'src',
src_img: 'src/img',
dist: 'dist',
dist_img: 'dist/img',
preview: 'preview'
},
// secrets.json is ignored in git because it contains sensitive data
// See the README for configuration settings
secrets: grunt.file.readJSON('secrets.json')
}
});
};
Am I missing something?
load-grunt-config is auto-loading the required grunt modules located in the package.json of the project. This is where clean (grunt-contrib-clean) sass (grunt-sass) etc are coming from.
This File determines which tasks are run by grunt
I'm trying to inject content via grunt-replace when I build by visual studio solution. However I would like to inject different content depending on the build configuration.
Is it possible to read the build configuration using grunt/node.
Thanks.
You can use grunt.option for this. Provide your build env on the command line and use it in the Gruntfile using grunt.option.
Quoting the example from grunt.option documentation
Gruntfile.js
grunt.initConfig({
compass: {
dev: {
options: {
/* ... */
outputStyle: 'expanded'
},
},
staging: {
options: {
/* ... */
outputStyle: 'compressed'
},
},
},
});
var target = grunt.option('target') || 'dev';
grunt.registerTask('deploy', ['compass:' + target]);
As you run grunt deploy your stylesheets would default to the dev target and output the CSS in the expanded format. If you ran grunt deploy --target=staging the staging target would instead be ran and your CSS would be in the compressed format.
grunt deploy --target=staging
I'm new to Grunt, and am trying to configure grunt-contrib-sass to work alongside Compass.
I'm using the grunt-contrib-sass plugin, as I need to export my .scss files to two separate destinations and I couldn't get that to work with grunt-contrib-compass.
The problem that I'm having, is that on compile of .scss files I get 'ERROR: Cannot load compass' in the terminal.
Here's a copy of my gruntfile.js;
module.exports = function(grunt){
grunt.initConfig({
uglify: {
my_target: {
files: {
'wp-content/themes/mytheme/js/functions.js' : [ 'components/js/*.js' ]
}
}
}, // uglify
sass:{
dist:{
files: {
'wp-content/themes/mytheme/style.css' : 'components/sass/style.scss',
'wp-content/themes/mytheme/css/ie.css' : 'components/sass/ie.scss '
},
options: {
compass: true,
}
}
},
watch: {
scripts : {
files: ['components/js/*.js'],
tasks: ['uglify']
},
css: {
files: [ 'components/sass/*.scss'],
tasks: [ 'sass' ],
options: { livereload: true }
},
livereload: {
options: { livereload: true },
files: ['wp-content/themes/mytheme/'],
},
} // watch
})
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask( 'default', 'watch' );
} // exports
Thanks!
Grunt-contrib-sass doesn't support Compass versions less than v1.0.0 (which is in alpha at the time of writing).
After updating Compass with;
gem install compass --pre
everything appears to work fine on compilation. The same gruntfile.js was used as above.
Removing all versions of sass except of known working version 3.2.19 solved the problem for me.
$ sudo gem uninstall sass
Select gem to uninstall:
1. sass-3.2.3
2. sass-3.2.5
3. sass-3.2.19
4. sass-3.3.5
5. All versions
> 4
According to the grunt-contrib-compass github page you need to have Ruby, Sass and Compass installed as prerequisite. You are using grunt-contrib-sass instead of grunt-contrib-compass. See examples on the contrib-compass github.
I found another way to get compass to work without the ruby gem. (it is a bit of work though).
Go to https://github.com/Compass/compass and get the code.
Copy the contents of core/stylesheets/compass into your sass/scss folder. Now you can use the normal import-rules from the compass-website.
BUT:
You probably have to change some imports from compass like import "compass/support"; in _transitions.scss to import "../support";
grunt-contrib-sass perfectly works with compass, just add compass: true to options. I read this point on oficial git repository.
Example
sass: {
dist: {
options: {
style: 'expanded',
compass: true
},
files: [
{
expand: true,
cwd: 'ipa-framework/src/css/scss',
src: ['*.scss'],
dest: 'ipa-framework/src/css',
ext: '.css'
}
]
}
}
So none of the answers worked exactly for me but it did help me solve the issue.
When you install compass using
gem install compass --pre
it installs another version of sass, so dont install sass at all let the compass install do it for you.
So to get it to work
gem uninstall sass
gem install compass --pre
And for reference this is the npm libraries I needed to have to get this working
npm install -g grunt grunt-contrib-sass grunt-contrib-watch grunt-livereload sass grunt-contrib-cssmin grunt-contrib-compass
Background
I've just started using grunt as of about 30mins ago. So bear with me.
But I have a rather simple script going that will look at my js and then compress it all into one file for me.
Code
"use strict";
module.exports = function (grunt) {
// load all grunt tasks
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
beautify: true,
report: 'gzip'
},
build: {
src: ['docroot/js/*.js', 'docroot/components/pages/*.js', 'docroot/components/plugins/*.js'],
dest: 'docroot/js/main.min.js'
}
},
watch: {
options: {
dateFormat: function(time) {
grunt.log.writeln('The watch finished in ' + time + 'ms at' + (new Date()).toString());
grunt.log.writeln('Waiting for more changes...');
}
},
js: {
files: '<%= uglify.build.src %>',
tasks: ['uglify']
}
}
});
grunt.registerTask('default', 'watch');
}
Question
My main.min.js is getting included in the compile each time. Meaning my min.js is getting 2x, 4x, 8x, 16x etc etc. Is best way around this is to add an exception and ignore main.min.js?
To the end of the src array, add
'!docroot/js/main.min.js'
This will exclude it. The ! turns it into an exclude.
http://gruntjs.com/api/grunt.file#grunt.file.expand
Paths matching patterns that begin with ! will be excluded from the returned array. Patterns are processed in order, so inclusion and exclusion order is significant.
This is not specific to grunt uglify, but any task that uses grunt convention for specifying files will work this way.
As a general advice though I would suggest putting built files somewhere else than your source files. Like in a root dist folder.